1. 程式人生 > >PhoneWindowManager處理事件分析(十一)

PhoneWindowManager處理事件分析(十一)

1, 基本概念

PhoneWindowManager也是運行於systemserver執行緒中,在Event事件分發之前處理,比如電源鍵。Event事件分發後,僅有包含Activity的apk執行緒才可以處理,如果apk中沒有activity但是想處理Event事件怎麼辦呢?可以在PhoneWindowManager做做文章了。

在SystemServer中,

inputManager = new InputManagerService(context);
  wm = WindowManagerService.main(context, inputManager,
        mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
        !mFirstBoot, mOnlyCore);
 ServiceManager.addService(Context.WINDOW_SERVICE, wm);
 ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

 mActivityManagerService.setWindowManager(wm);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); // 訊息分發之前的回撥
inputManager.start();

InputManagerService的建立以及啟動已經論述了,在此就不多說了。在

WindowManagerService中新建了PhoneWindowManager和InputMonitor,並且將設定為InputManagerService物件的回撥物件。其實這2個類都和Event的處理有關,在Event分發之前進行處理,相當於擷取,具體的細節就一層一層抽絲剝繭了。

PhoneWindowManager是沒有對應的C/C++層程式碼了。

看下InputManagerService的setWindowManagerCallbacks方法,

public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
        mWindowManagerCallbacks = callbacks;
    }

因此, InputManagerService的變數mWindowManagerCallbacks指向InputMonitor物件。

2處理流程


InputDispatcher的notifyKey方法中,Event進佇列之前,會呼叫interceptKeyBeforeQueueing方法,

mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);

mPolicy變數是什麼呢?通過查詢,是NativeInputManager物件,

void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
        uint32_t& policyFlags) {
    bool interactive = mInteractive.load();
    if (interactive) {
        policyFlags |= POLICY_FLAG_INTERACTIVE;
    }
    if ((policyFlags & POLICY_FLAG_TRUSTED)) {
        nsecs_t when = keyEvent->getEventTime();
        JNIEnv* env = jniEnv();
        jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
        jint wmActions;
        if (keyEventObj) {
            wmActions = env->CallIntMethod(mServiceObj,
                    gServiceClassInfo.interceptKeyBeforeQueueing,
                    keyEventObj, policyFlags);
            if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
                wmActions = 0;
            }
            android_view_KeyEvent_recycle(env, keyEventObj);
            env->DeleteLocalRef(keyEventObj);
        }
•••
}

在register_android_server_InputManager方法中,

int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService",
            gInputManagerMethods, NELEM(gInputManagerMethods));
•••
GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
            "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");

很明顯了,呼叫Java層InputManagerService的interceptKeyBeforeQueueing方法,後面就沒有什麼困難了,最後呼叫PhoneWindowManager的interceptKeyBeforeQueueing方法。

看下InputMonitor的方法,有一些也是同樣的方法呼叫,關鍵是C/C++層的程式碼什麼時候呼叫,覺得InputMonitor的主要目的還是解耦,防止PhoneWindowManager和InputManagerService太緊,

public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
        mService.mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
    }
public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) {
        mService.mPolicy.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered);
    }
 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
        return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
    }
    public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
        return mService.mPolicy.interceptMotionBeforeQueueingNonInteractive(
                whenNanos, policyFlags);
    }
    public long interceptKeyBeforeDispatching(
            InputWindowHandle focus, KeyEvent event, int policyFlags) {
        WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
        return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
    }
    public KeyEvent dispatchUnhandledKey(
            InputWindowHandle focus, KeyEvent event, int policyFlags) {
        WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
        return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
    }
    public int getPointerLayer() {
        return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
                * WindowManagerService.TYPE_LAYER_MULTIPLIER
                + WindowManagerService.TYPE_LAYER_OFFSET;
    }

在InputDispatcher.cpp的中的Event入佇列之後,dispatchKeyLocked方法中會呼叫doInterceptKeyBeforeDispatchingLockedInterruptible方法,然後呼叫NativeInputManager的interceptKeyBeforeDispatching方法,

nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
            &event, entry->policyFlags);

最後會呼叫PhoneWindowManager的interceptKeyBeforeDispatching方法。

所以,如果apk中沒有acitivity但是想監聽Event事件怎麼辦呢?

在PhoneWindowManager的interceptKeyBeforeQueueing或者interceptKeyBeforeDispatching方法中稍加處理就可以了。

相關推薦

PhoneWindowManager處理事件分析()

1, 基本概念 PhoneWindowManager也是運行於systemserver執行緒中,在Event事件分發之前處理,比如電源鍵。Event事件分發後,僅有包含Activity的apk執行緒才可以處理,如果apk中沒有activity但是想處理Event事件怎麼辦呢

圖像處理(二)基於數據驅動的人臉卡通動畫生成-Siggraph Asia 2014

ssi 原來 大於 搜索 nbsp details 一起 fontsize man http://blog.csdn.net/garfielder007/article/details/50582018 在現實生活中,我們經常會去評價一個人,長得是否漂亮、是不是帥哥美女,然

Python資料處理之( )Pandas 選擇資料

首先先建立一個6X4的矩陣 >>> import pandas as pd >>> import numpy as np >>> dates=pd.date_range('20181121',periods=6) >>

演算法設計與分析()--動態規劃

1. Unique Binary Search Trees 2. Unique Binary Search Trees II Unique Binary Search Trees 題目 Given n, how many structurally unique

[Abp 原始碼分析]、許可權驗證

0.簡介 Abp 本身集成了一套許可權驗證體系,通過 ASP.NET Core 的過濾器與 Castle 的攔截器進行攔截請求,並進行許可權驗證。在 Abp 框架內部,許可權分為兩塊,一個是功能(Feature),一個是許可權項(Permission),在更多的時候兩者僅僅是概念不同而已,大體處理流程還是一樣

數字影象處理筆記():邊緣檢測演算法

1 - 引言 在影象識別中,如果可以將影象感興趣的物體或區別分割出來,無疑可以增加我們影象識別的準確率,傳統的數字影象處理中的分割方法多數基於灰度值的兩個基本性質 不連續性、 以灰度突變為基礎分割一副影象,比如影象的邊緣 相似性 根據一組預定義的準則將一副影象分割為相似

Spring Security原始碼分析:Spring Security OAuth2整合JWT

Json web token (JWT), 是為了在網路應用環境間傳遞宣告而執行的一種基於JSON的開放標準(RFC 7519).該token被設計為緊湊且安全的,特別適用於分散式站點的單點登入(SSO)場景。JWT的宣告一般被用來在身份提供者和服務提供者

ABP原始碼分析:Timing

Timing這個簡單實用的功能主要用於以統一的方式表示時間。因為ABP中有大量的module,還支援自定義module,所以將時間統一表示為local時間(預設)或utc時間是必要的。 IClockProvider:提供獲取當前時間和標準化時間的介面。 UtcClockProvider:實現了以UTC

影象處理(二)基於資料驅動的人臉卡通動畫生成-Siggraph Asia 2014

基於資料驅動的人臉卡通動畫生成 作者:hjimce 在現實生活中,我們經常會去評價一個人,長得是否漂亮、是不是帥哥美女,然而如何用五官的資料去評價一個人是否長得五官比例協調,我們卻很難說出來,也就是

Storm入門()Twitter Storm源代碼分析之CoordinatedBolt

業務 什麽 協議 ack 第一個 ng- rec 功能 這一 作者: xumingming | 可以轉載, 但必須以超鏈接形式標明文章原始出處和作者信息及版權聲明網址: http://xumingming.sinaapp.com/811/twitter-storm-code

事件對象

web lpad 常用 特殊 名詞 版本 特定 cap getchar 二十一、事件對象   JavaScript事件的一個重要方面是它們擁有一些相對一致的特點,可以給你的開發提供更多的強大功能。最方便和強大的就是事件對象,他們可以幫你處理鼠標事件和鍵盤敲擊方面的情況,

Nginx學習之-Nginx啟動框架處理流程

table ssl 優先級 init int 數組 linux cmd 默認 Nginx啟動過程流程圖 下面首先給出Nginx啟動過程的流程圖: ngx_cycle_t結構體 Nginx的啟動初始化在src/core/nginx.c的main函數中完成,當然main

節:Bundles壓縮合並js和css及原理分析

string數組 tab 速度 操作 spn sof 參考 reader 調試 一. 簡介 1.背景:瀏覽器默認一次性請求的網絡數是有上限的,如果你得js和css文件太多,就會導致瀏覽器需要多次加載,影響頁面的加載速度, MVC中提供Bundles的方式壓縮合並js和cs

CoreThink開發()首頁控制器判斷移動設備還是PC並做相應處理

iss htm meizu http nec window sam assign clas 在home模塊Index控制器添加判斷代碼 application\Home\Controller\IndexController.class.php <?php // +

【慕課網實戰】Spark Streaming實時流處理項目實戰筆記二之銘文升級版

win7 小時 其他 har safari 北京 web 連接 rim 銘文一級: DataV功能說明1)點擊量分省排名/運營商訪問占比 Spark SQL項目實戰課程: 通過IP就能解析到省份、城市、運營商 2)瀏覽器訪問占比/操作系統占比 Hadoop項目:userAg

c#數字圖像處理)圖像旋轉

nbsp 雙線 else 處理 找不到 nsa sin hds 像素點 如果平面上的點繞原點逆時針旋轉θo,則其坐標變換公式為:

Spark項目之電商用戶行為分析大數據平臺之()JSON及FASTJSON

附加 處理 用戶行為分析 基於 大數據平臺 base IT 為什麽 init 一、概述 JSON的全稱是”JavaScript Object Notation”,意思是JavaScript對象表示法,它是一種基於文本,獨立於語言的輕量級數據交換格式

Linux學習之-Linux字符集及亂碼處理

gin tails 讀取 文件 latin1 style ESS 自身 win Linux字符集及亂碼處理 1、字符(Character)是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。字符集(Character set)是多個字符的集合,字符集種類較多

Spring源碼分析)bean的加載

tty matches 判斷 alias desc getc ntb 結合 步驟 摘要:本文結合《Spring源碼深度解析》來分析Spring 5.0.6版本的源代碼。若有描述錯誤之處,歡迎指正。 經過前面的分析,我們終於結束了對XML配置文件的解析,接下來將會面

Linux進程啟動過程分析do_execve(可執行程序的加載和運行)---Linux進程的管理與調度(

[] flag 表示 conn nali 最終 roc 不同的 recursion execve系統調用 execve系統調用 我們前面提到了, fork, vfork等復制出來的進程是父進程的一個副本, 那麽如何我們想加載新的程序, 可以通過execve來加載和啟動新的程