/*
* ConnectBot: simple, powerful, open-source SSH client for Android
* Copyright 2014 Torne Wuff
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.connectbot.service;
import android.annotation.TargetApi;
import android.os.Build;
import android.view.KeyEvent;
public class KeyEventUtil {
static final char CONTROL_LIMIT = ' ';
static final char PRINTABLE_LIMIT = '\u007e';
static final char[] HEX_DIGITS = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
static String printableRepresentation(String source) {
if (source == null)
return null;
final StringBuilder sb = new StringBuilder();
final int limit = source.length();
char[] hexbuf = null;
int pointer = 0;
sb.append('"');
while (pointer < limit) {
int ch = source.charAt(pointer++);
switch (ch) {
case '\0':
sb.append("\\0");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
default:
if (CONTROL_LIMIT <= ch && ch <= PRINTABLE_LIMIT) {
sb.append((char) ch);
} else {
sb.append("\\u");
if (hexbuf == null)
hexbuf = new char[4];
for (int offs = 4; offs > 0; ) {
hexbuf[--offs] = HEX_DIGITS[ch & 0xf];
ch >>>= 4;
}
sb.append(hexbuf, 0, 4);
}
}
}
return sb.append('"').toString();
}
private static class ClassCompat {
private static final ClassCompat INSTANCE;
static {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
INSTANCE = new HCMR2AndNewer();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
INSTANCE = new HCMR1AndNewer();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
INSTANCE = new GingerbreadAndNewer();
} else {
INSTANCE = new ClassCompat();
}
}
private ClassCompat() {
}
public static void appendExtras(StringBuilder d, int keyCode, KeyEvent event) {
INSTANCE.appendForApi(d, keyCode, event);
}
protected void appendForApi(StringBuilder d, int keyCode, KeyEvent event) {
}
@TargetApi(9)
private static class GingerbreadAndNewer extends ClassCompat {
@Override
protected void appendForApi(StringBuilder d, int keyCode, KeyEvent event) {
super.appendForApi(d, keyCode, event);
d.append(", source=").append(event.getSource());
}
}
@TargetApi(12)
private static class HCMR1AndNewer extends GingerbreadAndNewer {
protected void appendForApi(StringBuilder d, int keyCode, KeyEvent event) {
super.appendForApi(d, keyCode, event);
d.append(", keyCodeToString=").append(KeyEvent.keyCodeToString(keyCode));
}
}
@TargetApi(13)
private static class HCMR2AndNewer extends HCMR1AndNewer {
@Override
protected void appendForApi(StringBuilder d, int keyCode, KeyEvent event) {
super.appendForApi(d, keyCode, event);
d.append(", modifiers=").append(Integer.toHexString(event.getModifiers()));
}
}
}
public static String describeKeyEvent(int keyCode, KeyEvent event) {
StringBuilder d = new StringBuilder();
d.append("keyCode=").append(keyCode);
d.append(", event.toString=").append(event.toString());
d.append(", action=").append(event.getAction());
d.append(", characters=").append(printableRepresentation(event.getCharacters()));
d.append(", deviceId=").append(event.getDeviceId());
d.append(", displayLabel=").append((int) event.getDisplayLabel());
d.append(", flags=0x").append(Integer.toHexString(event.getFlags()));
d.append(", printingKey=").append(event.isPrintingKey());
d.append(", keyCode=").append(event.getKeyCode());
d.append(", metaState=0x").append(Integer.toHexString(event.getMetaState()));
d.append(", number=").append((int) event.getNumber());
d.append(", scanCode=").append(event.getScanCode());
d.append(", unicodeChar=").append(event.getUnicodeChar());
ClassCompat.appendExtras(d, keyCode, event);
return d.toString();
}
}