Android鍵盤系統相關程式碼分析(1)

來源:互聯網
上載者:User

EventHub.cpp檔案中open_device函數淺析

    

    使用者態中,與核心態聯絡緊密的一個函數是open_device,它位於EventHub.cpp檔案中,該函數有大量的底層操作,以完成上層對硬體的操作。該函數的首部為:

int EventHub::open_device(const char *deviceName)

其中參數有scan_dir()函數獲得。在這裡,deviceName=”/dev/input/event0”



for (attempt = 0; attempt < 10; attempt++) {

fd = open(deviceName, O_RDWR);

if (fd >= 0) break;

usleep(100);

}

這個迴圈給了系統10次開啟裝置的機會,若失敗,則等待100usec後繼續嘗試。

---

if(ioctl(fd, EVIOCGVERSION, &version))

if(ioctl(fd, EVIOCGID, &id))

if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1)

通過ioctl介面擷取驅動版本號碼、id號及裝置名稱。



List<String8>::iterator iter = mExcludedDevices.begin();

List<String8>::iterator end = mExcludedDevices.end();

for ( ; iter != end; iter++) {

const char* test = *iter;

if (strcmp(name, test) == 0) {

LOGI("ignoring event id %s driver %s/n", deviceName, test);

close(fd);

fd = -1;

return -1;

}

}

檢查裝置執行列變,若列表中有與上一步獲的裝置名稱相同的情況(裝置已經開啟),則關閉裝置。



if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1)

if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1)


int devid = 0;

if (devid >= mNumDevicesById) { // mNumDevicesById在建構函式中被初始化為0;

//所以會執行下面的內容;

device_ent* new_devids = (device_ent*)realloc(mDevicesById,

sizeof(mDevicesById[0]) * (devid + 1));

if (new_devids == NULL) {

LOGE("out of memory");

return -1;

}



mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;


device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName, name);

當new一個device_t時,會把後面的參數傳送到:

EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name)

: id(_id), path(_path), name(name), classes(0)

, keyBitmask(NULL), layoutMap(new KeyLayoutMap()), next(NULL) {

}

其中layoutMap初始化成了:new KeyLayoutMap(),因此,進入會KeyLayoutMap();


ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0)

通過ioctl介面擷取鍵盤位元遮罩。



const char* root = getenv("ANDROID_ROOT");

snprintf(keylayoutFilename, sizeof(keylayoutFilename),

"%s/usr/keylayout/%s.kl", root, tmpfn);

bool defaultKeymap = false;

if (access(keylayoutFilename, R_OK)) {

snprintf(keylayoutFilename, sizeof(keylayoutFilename),

"%s/usr/keylayout/%s", root, "qwerty.kl");

defaultKeymap = true;

}

device->layoutMap->load(keylayoutFilename);

這段代碼的作用是載入鍵盤配置檔案。由

snprintf(keylayoutFilename, sizeof(keylayoutFilename)......

可知:keylayoutFilename與tmptn有關。由strcpy(tmpfn, name);可知tmptn=name。在前面的一個ioctl介面中,已經擷取到了裝置名稱。由類比機開機記錄可以知道:name=qwerty2。若access(keylayoutFilename, R_OK)為假,則使用預設的布局檔案qwerty.kl




device->layoutMap->load(keylayoutFilename);

接下來,載入這個鍵盤配置檔案。


進入load函數,我們就可以能清楚地看到檔案的載入過程。

int fd = open(filename, O_RDONLY); //開啟檔案

off_t len = lseek(fd, 0, SEEK_END); //擷取檔案長度

char* buf = (char*)malloc(len+1); //開闢讀取檔案的緩衝區

if (read(fd, buf, len) != len) //將檔案內容讀到緩衝區

buf[len] = '/0' //標誌檔案結束



int line = 1;

char const* p = buf;

enum { BEGIN, SCANCODE, KEYCODE, FLAG } state = BEGIN;

while (true) {

String8 token = next_token(&p, &line);

進入這個死迴圈之間的第一條語句是:String8 token = next_token(&p, &line);而該函數的返回為:return String8(begin, end-begin);從String8類的建構函式我們知道next_token到底返回了個什麼東西:

String8::String8(const char16_t* o, size_t len)

: mString(allocFromUTF16(o, len)) { }

我們可以看到,String8的這個建構函式初始化了一個字串常量(const char* mString;)

這個字串常量在後面會用到:

scancode = strtol(token.string(), &end, 0);

因為token.string這個函數原型為;

inline const char* String8::string() const

{

return mString;

}



以上所有對底層地操作,如:

fd = open(deviceName, O_RDWR);

if(ioctl(fd, EVIOCGVERSION, &version))

等都不是直接對鍵盤驅動進行操作,而是對事件處理驅動進行的操作。也就是說,事件處理驅動對鍵盤驅動進行了封裝。

接下來,是對底層驅動的分析:

鍵盤驅動函數Goldfish_events.c

輸入核心驅動函數input.c

事件處理驅動函數evdev.c

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.