【Android N7.0】Framework层实现派发HOME按键到Application层的一种简单方案

frameworks/base/core/java/android/view/WindowManager.java

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


Android是不允许派发HOME按键到Application层的,其中一个原因,个人认为这是为了避免恶性软件如果同时拦截了HOME按键,BACK按键及MENU键或APP_SWITCH按键,则用户就没有办法退出Activity。因为Google保留一个HOME按键不往application层派发,可避免恶性软件的攻击。


下面介绍自己想的一种平台方实现派发HOME按键到Application层的一种简单方案,修改如下:

原文地址:http://blog.csdn.net/yelangjueqi/article/details/58587097

Framework层修改

1. WindowManager.java

......

        /**
         * Window type: disptach homekey keycent to application(Add by xxx)
         *
         * @hide
         */
        public static final int PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP = 0x00080000;

......


2. PhoneWindowManager.java

    /** {@inheritDoc} */
    @Override
    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
    
        // 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) {
            WindowManager.LayoutParams attr = win != null ? win.getAttrs() : null;
            if (attr != null) {
                boolean dispatchHomeKeyToApp = (attr.privateFlags & PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP) != 0;
                Slog.d(TAG, "dispatch homekey to application? dispatchHomeKeyToApp = " + dispatchHomeKeyToApp);
                if (dispatchHomeKeyToApp) {
                    return 0;
                }
            }

            
            // If we have released the home key, and didn't do anything else
            // while it was pressed, then it is time to go home!
        ......
        }
    }


修改截图:



3. App层使用(Activity)


    @Override
    public void onCreate(Bundle savedInstanceState) {
    
    ......
    getWindow().addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP);
    }


    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        Log.d(TAG, "dispatchKeyEvent code="+event.getKeyCode());
        switch (event.getKeyCode()) {
            case KeyEvent.KEYCODE_HOME:
                // TODO
                return true;
            default:
                break;
        }
        return super.dispatchKeyEvent(event);
    }


Log:

dispatchKeyEvent code=3



附 
基于Android N7.0制作的patch

diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index fe24230..f7d4bc9 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1254,6 +1254,13 @@ public interface WindowManager extends ViewManager {
         public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 0x00040000;
 
         /**
+         * Window type: disptach homekey keycent to application
+         *
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP = 0x00080000;
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b939fe3..c2f2a5b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3056,6 +3056,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         // it handle it, because that gives us the correct 5 second
         // timeout.
         if (keyCode == KeyEvent.KEYCODE_HOME) {
+            WindowManager.LayoutParams attr = win != null ? win.getAttrs() : null;
+            if (attr != null) {
+                boolean dispatchHomeKeyToApp = (attr.privateFlags & PRIVATE_FLAG_DISPATCH_HOME_KEY_TO_APP) != 0;
+                Slog.d(TAG, "dispatch homekey to application? dispatchHomeKeyToApp = " + dispatchHomeKeyToApp);
+                if (dispatchHomeKeyToApp) {
+                    return 0;
+                }
+            }
 
             // If we have released the home key, and didn't do anything else
             // while it was pressed, then it is time to go home!


posted @ 2017-04-07 11:10  行走的思想  阅读(9)  评论(0编辑  收藏  举报  来源