Android駆動の仮想キー
6881 ワード
Android駆動の仮想キー
Published on 2010年03月22日
in android. 0 Comments
Tags: android, driver, kernel, linux, virualkey.
1背景
nexus one工業の設計は簡潔で、iphoneのボタンが1つしかないような設計で、真ん中のトラックボールしかありません.しかしandroid標準キーボードはHOME,MENU,BACK,SEARCHなどがあるが,同時に工業設計を維持しなければならない.nexus oneはこのように問題を解決し、ディスプレイは800 X 480であるが、容量タッチスクリーンが8 x*480であるところが800より大きいところが仮想ボタンとなり、android標準ボタンをシミュレートした.
2シナリオ
実装するには,仮想キーはandroidの中で2層の協力で実現され,下位層では仮想キーをディスプレイよりも多くの場所で仮想キーの位置サイズやキー値などを規定し,上位層にファイルインタフェースを与える.上位javaレイヤは、この領域のキー応答を読み出すサービスを開始します.これが概略的なアーキテクチャです.具体的には、次のようになります.
2.1最下位の仮想キー機能の実現方案は簡単に言えば、カーネルの中で仮想キーのすべての情報を上位に与えることであり、どのような方法で提供しますか?sysファイルシステムの方式で、sysファイルシステムの経路は約束したので、コードは以下のように実現します.情報を与えるプロトコルフォーマットは連続する文字列であり、各キーは6項目がそれぞれコロンで分割され、キー間もコロンで分割され、6項目は順にキータイプ:キー値:キー領域中心x座標:キー領域中心y座標:キー領域幅:キー領域高さarch/arm/mach-msm/board-mahimahiである.c
JAVA上層案Java層は主にキー情報を読み取り、一定のアルゴリズムを経て、仮想キーを識別し、基本的に修正する必要はないが、java層のアーキテクチャを熟知することが望ましい.このような問題が発生した場合、frameworks/base/services/java/com/android/server/KeyInputQueueを位置決めするのに有利である.java
/*これは仮想キーのクラスにVirtualKeyで使用されるメンバー変数とキーの位置決め方法が含まれています*/
基本的には、デバッグ作業に時間がかかる可能性があります.また、仮想キーを作るには、ハードウェアのサポート(表示領域を超えるタッチスクリーン領域)が必要です.このコードはandroid 2.1に基づいて実際の状況に応じて変更してください
Published on 2010年03月22日
in android. 0 Comments
Tags: android, driver, kernel, linux, virualkey.
1背景
nexus one工業の設計は簡潔で、iphoneのボタンが1つしかないような設計で、真ん中のトラックボールしかありません.しかしandroid標準キーボードはHOME,MENU,BACK,SEARCHなどがあるが,同時に工業設計を維持しなければならない.nexus oneはこのように問題を解決し、ディスプレイは800 X 480であるが、容量タッチスクリーンが8 x*480であるところが800より大きいところが仮想ボタンとなり、android標準ボタンをシミュレートした.
2シナリオ
実装するには,仮想キーはandroidの中で2層の協力で実現され,下位層では仮想キーをディスプレイよりも多くの場所で仮想キーの位置サイズやキー値などを規定し,上位層にファイルインタフェースを与える.上位javaレイヤは、この領域のキー応答を読み出すサービスを開始します.これが概略的なアーキテクチャです.具体的には、次のようになります.
2.1最下位の仮想キー機能の実現方案は簡単に言えば、カーネルの中で仮想キーのすべての情報を上位に与えることであり、どのような方法で提供しますか?sysファイルシステムの方式で、sysファイルシステムの経路は約束したので、コードは以下のように実現します.情報を与えるプロトコルフォーマットは連続する文字列であり、各キーは6項目がそれぞれコロンで分割され、キー間もコロンで分割され、6項目は順にキータイプ:キー値:キー領域中心x座標:キー領域中心y座標:キー領域幅:キー領域高さarch/arm/mach-msm/board-mahimahiである.c
static ssize_t mahimahi_virtual_keys_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
if (system_rev > 2) {
/* center: x: back: 55, menu: 172, home: 298, search 412, y: 835 */
return sprintf(buf,
__stringify(EV_KEY) ":" __stringify(KEY_BACK) ":55:835:90:55"
":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":172:835:125:55"
":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":298:835:115:55"
":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":412:835:95:55"
"/n");
} else {
/* center: x: home: 55, menu: 185, back: 305, search 425, y: 835 */
return sprintf(buf,
__stringify(EV_KEY) ":" __stringify(KEY_HOME) ":55:835:70:55"
":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":185:835:100:55"
":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":305:835:70:55"
":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":425:835:70:55"
"/n");
}
}
static struct kobj_attribute mahimahi_virtual_keys_attr = {
.attr = {
.name = "virtualkeys.synaptics-rmi-touchscreen",
.mode = S_IRUGO,
},
.show = &mahimahi_virtual_keys_show,
};
static struct attribute *mahimahi_properties_attrs[] = {
&mahimahi_virtual_keys_attr.attr,
NULL
};
static struct attribute_group mahimahi_properties_attr_group = {
.attrs = mahimahi_properties_attrs,
};
struct kobject *properties_kobj;
properties_kobj = kobject_create_and_add("board_properties", NULL);
if (properties_kobj)
ret = sysfs_create_group(properties_kobj,
&mahimahi_properties_attr_group);
if (!properties_kobj || ret)
pr_err("failed to create board_properties/n");
JAVA上層案Java層は主にキー情報を読み取り、一定のアルゴリズムを経て、仮想キーを識別し、基本的に修正する必要はないが、java層のアーキテクチャを熟知することが望ましい.このような問題が発生した場合、frameworks/base/services/java/com/android/server/KeyInputQueueを位置決めするのに有利である.java
/*これは仮想キーのクラスにVirtualKeyで使用されるメンバー変数とキーの位置決め方法が含まれています*/
static class VirtualKey {
int scancode;
int centerx;
int centery;
int width;
int height;
int hitLeft;
int hitTop;
int hitRight;
int hitBottom;
InputDevice lastDevice;
int lastKeycode;
boolean checkHit(int x, int y) {
return (x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom);
}
void computeHitRect(InputDevice dev, int dw, int dh) {
if (dev == lastDevice) {
return;
}
if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "computeHitRect for " + scancode
+ ": dev=" + dev + " absX=" + dev.absX + " absY=" + dev.absY);
lastDevice = dev;
int minx = dev.absX.minValue;
int maxx = dev.absX.maxValue;
int halfw = width/2;
int left = centerx - halfw;
int right = centerx + halfw;
hitLeft = minx + ((left*maxx-minx)/dw);
hitRight = minx + ((right*maxx-minx)/dw);
int miny = dev.absY.minValue;
int maxy = dev.absY.maxValue;
int halfh = height/2;
int top = centery - halfh;
int bottom = centery + halfh;
hitTop = miny + ((top*maxy-miny)/dh);
hitBottom = miny + ((bottom*maxy-miny)/dh);
}
}
/* , , ok*/
private void readVirtualKeys(String deviceName) {
try {
FileInputStream fis = new FileInputStream(
"/sys/board_properties/virtualkeys." + deviceName);
/* kernel , , */
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr, 2048);
String str = br.readLine();
if (str != null) {
String[] it = str.split(":");
if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "***** VIRTUAL KEYS: " + it);
final int N = it.length-6;
for (int i=0; i<=N; i+=6) {
if (!"0x01".equals(it[i])) {
Log.w(TAG, "Unknown virtual key type at elem #" + i
+ ": " + it[i]);
continue;
}
try {
VirtualKey sb = new VirtualKey();
sb.scancode = Integer.parseInt(it[i+1]);
sb.centerx = Integer.parseInt(it[i+2]);
sb.centery = Integer.parseInt(it[i+3]);
sb.width = Integer.parseInt(it[i+4]);
sb.height = Integer.parseInt(it[i+5]);
if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Virtual key "
+ sb.scancode + ": center=" + sb.centerx + ","
+ sb.centery + " size=" + sb.width + "x"
+ sb.height);
mVirtualKeys.add(sb);
} catch (NumberFormatException e) {
Log.w(TAG, "Bad number at region " + i + " in: "
+ str, e);
}
}
}
br.close();
} catch (FileNotFoundException e) {
Log.i(TAG, "No virtual keys found");
} catch (IOException e) {
Log.w(TAG, "Error reading virtual keys", e);
}
}
基本的には、デバッグ作業に時間がかかる可能性があります.また、仮想キーを作るには、ハードウェアのサポート(表示領域を超えるタッチスクリーン領域)が必要です.このコードはandroid 2.1に基づいて実際の状況に応じて変更してください