• 在PhoneWindowManagerjava中处理
    • 在InputDispatchercpp中处理

在Android开发中,我们通常需要对发往工厂的Android软件进行工厂测试;这其中就要去测试各个按键的功能,例如:测试HOME/BACK/MENU/POWER。但是问题在于:这些按键基本上都是有系统负责处理的,或者在系统处理了之后在向上分发的。也就是说,不论怎样系统都会对此类按键进行处理。
这里给出如下方法:

PhoneWindowManager.java中处理

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

Android 屏蔽Power键 Home键_第1张图片


// First we always handle the home key here, so applications// can never break it, although if keyguard is on, we do let// it handle it, because that gives us the correct 5 second// timeout.if (keyCode == KeyEvent.KEYCODE_HOME) {    // If we have released the home key, and didn't do anything else    // while it was pressed, then it is time to go home!    if (!down) {        cancelPreloadRecentApps();        mHomePressed = false;        if (mHomeConsumed) {            mHomeConsumed = false;            return -1;        }        if (canceled) {            Log.i(TAG, "Ignoring HOME; event canceled.");            return -1;        }        // If an incoming call is ringing, HOME is totally disabled.        // (The user is already on the InCallUI at this point,        // and his ONLY options are to answer or reject the call.)        TelecomManager telecomManager = getTelecommService();        if (telecomManager != null && telecomManager.isRinging()) {            Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");            return -1;        }        // Delay handling home if a double-tap is possible.        if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {            // just in case            mHomeDoubleTapPending = true;            mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,                    ViewConfiguration.getDoubleTapTimeout());            return -1;        }        // deal with key.... before        if (isTopActivityFactoryTool(win)) {            Log.d(TAG,"factory tool return");            return 0;        }        // deal with key.... end        handleShortPressOnHome();        return -1;    }    // If a system window has focus, then it doesn't make sense    // right now to interact with applications.    WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;    if (attrs != null) {        final int type = attrs.type;        if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM                || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG                || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {            // the "app" is keyguard, so give it the key            return 0;        }        final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;        for (int i=0; iif (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {                // don't do anything, but also don't pass it to the app                return -1;            }        }    }    // Remember that home is pressed and handle special actions.    if (repeatCount == 0) {        mHomePressed = true;        if (mHomeDoubleTapPending) {            mHomeDoubleTapPending = false;            mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);            handleDoubleTapOnHome();        } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI        || mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {            preloadRecentApps();        }    } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {        if (!keyguardOn) {            handleLongPressOnHome(event.getDeviceId());        }    }    return -1;}

其中
isTopActivityFactoryTool函数的实现方式

public boolean isTopActivityFactoryTool(WindowState win) {    if(win != null){        String topPackageName = win.getOwningPackage();        if(("com.cp.packagename1".equals(topPackageName)        || "com.cp.packagename2".equals(topPackageName))){            Log.d(TAG,"top activity is " + topPackageName);            return true;        }    }    return false;}

在InputDispatcher.cpp中处理

frameworks/base/native/services/inputflinger/InputDispatcher.cpp

void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {#if DEBUG_INBOUND_EVENT_DETAILS    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x,     action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x,    metaState=0x%x, downTime=%lld",            args->eventTime, args->deviceId, args->source, args->policyFlags,            args->action, args->flags, args->keyCode, args->scanCode,            args->metaState, args->downTime);#endif    if (!validateKeyEvent(args->action)) {        return;    }    uint32_t policyFlags = args->policyFlags;    int32_t flags = args->flags;    int32_t metaState = args->metaState;    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags &            AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {        policyFlags |= POLICY_FLAG_VIRTUAL;        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;    }    if (policyFlags & POLICY_FLAG_FUNCTION) {        metaState |= AMETA_FUNCTION_ON;    }    policyFlags |= POLICY_FLAG_TRUSTED;    int32_t keyCode = args->keyCode;    if (metaState & AMETA_META_ON && args->action == AKEY_EVENT_ACTION_DOWN) {        int32_t newKeyCode = AKEYCODE_UNKNOWN;        if (keyCode == AKEYCODE_DEL) {            newKeyCode = AKEYCODE_BACK;        } else if (keyCode == AKEYCODE_ENTER) {            newKeyCode = AKEYCODE_HOME;        }        if (newKeyCode != AKEYCODE_UNKNOWN) {            AutoMutex _l(mLock);            struct KeyReplacement replacement = {keyCode, args->deviceId};            mReplacedKeys.add(replacement, newKeyCode);            keyCode = newKeyCode;            metaState &= ~AMETA_META_ON;        }    } else if (args->action == AKEY_EVENT_ACTION_UP) {        // In order to maintain a consistent stream of up and down events, check to see if the key        // going up is one we've replaced in a down event and haven't yet replaced in an up event,        // even if the modifier was released between the down and the up events.        AutoMutex _l(mLock);        struct KeyReplacement replacement = {keyCode, args->deviceId};        ssize_t index = mReplacedKeys.indexOfKey(replacement);        if (index >= 0) {            keyCode = mReplacedKeys.valueAt(index);            mReplacedKeys.removeItemsAt(index);            metaState &= ~AMETA_META_ON;        }    }    KeyEvent event;    event.initialize(args->deviceId, args->source, args->action,            flags, keyCode, args->scanCode, metaState, 0,            args->downTime, args->eventTime);    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);    bool needWake;    { // acquire lock        mLock.lock();        if (shouldSendKeyToInputFilterLocked(args)) {            mLock.unlock();            policyFlags |= POLICY_FLAG_FILTERED;            if (!mPolicy->filterInputEvent(&event, policyFlags)) {                return; // event was consumed by the filter            }            mLock.lock();        }        int32_t repeatCount = 0;        //add your control code here        if(false){            //origin source code        }else{            //your self source code        }        #ifdef CONTROL_KEY_CODE            //your self source code        #else            //origin source doce        #endif        KeyEntry* newEntry = new KeyEntry(args->eventTime,                args->deviceId, args->source, policyFlags,                args->action, flags, keyCode, args->scanCode,                metaState, repeatCount, args->downTime);        needWake = enqueueInboundEventLocked(newEntry);        mLock.unlock();    } // release lock    if (needWake) {        mLooper->wake();    }}

详细的添加规则可以根据自己需求,伪代码如下所示

        //add your control code here        if(false){            //origin source code        }else{            //your self source code        }        #ifdef CONTROL_KEY_CODE            //your self source code        #else            //origin source doce        #endif

有关InputDispatch的处理参见 Android 中处理POWER/HOME流程

更多相关文章

  1. 深入理解:Android 编译系统
  2. 基于Android的校园快递系统_移动端设计_后台管理_MySQL数据库设
  3. 【生态】特斯拉的中控系统为什么是Linux而不是Android?
  4. 用U盘安装Android系统在PC x86平台上运行Android
  5. Android的内存泄露测试 mat
  6. Android中系统触摸相关辅助类总结

随机推荐

  1. Android高手进阶教程(九)之----Android(
  2. android为ImageView使用蒙层
  3. 对SqliteDatabase.findEditTable的改进
  4. Android修改源代码控制永不锁屏
  5. Tween动画
  6. Android颜色小工具
  7. [Android] Otto源码简析
  8. Android(安卓)-- RecyclerView
  9. adb 指令
  10. PagerBottomTabStrip