Android 短按两次Power键打开相机

 

RK3368 Android6.0

今天 12.31 有点搞笑 有测试人员反馈 短按power键 会跳转到camera2  

先看了一下日志 确实跳转到了camera2  把东西捋了一下 问了一下 硬件(一度怀疑power的键值是不是改变了) 硬件说要拿烙铁帮我看一下日志 哈哈哈

一.日志先上

12-31 15:06:45.716  GestureLauncherService(  586): Power button double tap gesture detected, launching camera. Interval=240ms  噫

12-31 15:06:45.959  ActivityManager(  586): START u0 {act=android.media.action.STILL_IMAGE_CAMERA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
12-31 15:06:45.476 W/TelecomManager(  586): Telecom Service not found.
12-31 15:06:45.624 D/XHApiManager(  586): enter XHApiManager
12-31 15:06:45.625 I/PowerManagerService(  586): Going to sleep due to power button (uid 1000)...
12-31 15:06:45.627 I/PowerManagerService(  586): Sleeping (uid 1000)...
12-31 15:06:45.715 D/XHApiManager(  586): enter XHApiManager
12-31 15:06:45.716 W/TelecomManager(  586): Telecom Service not found.
12-31 15:06:45.716 I/GestureLauncherService(  586): Power button double tap gesture detected, launching camera. Interval=240ms
12-31 15:06:45.717 I/PowerManagerService(  586): Waking up from sleep (uid 1000)...
12-31 15:06:45.733 D/SensorsHal(  586): Couldn't open /dev/mma8452_daemon (No such file or directory)
12-31 15:06:45.733 E/SensorService(  586): Error activating sensor 0 (Operation not permitted)
12-31 15:06:45.734 V/KeyguardServiceDelegate(  586): onStartedWakingUp()
12-31 15:06:45.749 D/WifiConfigStore(  586): Retrieve network priorities before PNO. Max priority: 0
12-31 15:06:45.751 D/XHService(  586): receiver intent :android.intent.action.SCREEN_OFF
12-31 15:06:45.751 E/WifiStateMachine(  586):  Fail to set up pno, want true now false
12-31 15:06:45.776 E/native  586): do suspend true
12-31 15:06:45.779 I/ActivityManager(  586): START u0 {act=android.media.action.STILL_IMAGE_CAMERA flg=0x14000000 cmp=com.android.camera2/com.android.camera.CameraActivity} from uid 10011 on display 0 

1.1.frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java

power键值

1
2
3
4
5
6
7
8
9
case KeyEvent.KEYCODE_POWER: {
    result &= ~ACTION_PASS_TO_USER;
    isWakeKey = false; // wake-up will be handled separately
    if (down) {
        interceptPowerKeyDown(event, interactive);                                                         
    } else {
        interceptPowerKeyUp(event, interactive, canceled);
    }
    break;

 power键按下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
    // Hold a wake lock until the power key is released.
    if (!mPowerKeyWakeLock.isHeld()) {
        mPowerKeyWakeLock.acquire();
    }
 
    // Cancel multi-press detection timeout.
    if (mPowerKeyPressCounter != 0) {
        mHandler.removeMessages(MSG_POWER_DELAYED_PRESS);
    }
 
    // Detect user pressing the power button in panic when an application has
    // taken over the whole screen.
    boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
            SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags));
    if (panic) {
        mHandler.post(mHiddenNavPanic);
    }
 
    // Latch power key state to detect screenshot chord.
    if (interactive && !mScreenshotChordPowerKeyTriggered
            && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
        mScreenshotChordPowerKeyTriggered = true;
        mScreenshotChordPowerKeyTime = event.getDownTime();
        interceptScreenshotChord();
    }
 
    // Stop ringing or end call if configured to do so when power is pressed.
    TelecomManager telecomManager = getTelecommService();
    boolean hungUp = false;
    if (telecomManager != null) {
        if (telecomManager.isRinging()) {
            // Pressing Power while there's a ringing incoming
            // call should silence the ringer.
            telecomManager.silenceRinger();
        } else if ((mIncallPowerBehavior
                & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
                && telecomManager.isInCall() && interactive) {
            // Otherwise, if "Power button ends call" is enabled,
            // the Power button will hang up any current active call.
            hungUp = telecomManager.endCall();
        }
    }
 
    GestureLauncherService gestureService = LocalServices.getService(
            GestureLauncherService.class);
    boolean gesturedServiceIntercepted = false;
    if (gestureService != null) {
        gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive);
    }
 
    // If the power key has still not yet been handled, then detect short
    // press, long press, or multi press and decide what to do.
    mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
            || mScreenshotChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
    if (!mPowerKeyHandled) {
        if (interactive) {
            // When interactive, we're already awake.
            // Wait for a long press or for the button to be released to decide what to do.
            if (hasLongPressOnPowerBehavior()) {
                Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                msg.setAsynchronous(true);
                mHandler.sendMessageDelayed(msg,
                        ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
            }
        } else {
            wakeUpFromPowerKey(event.getDownTime());
 
            if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
                Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                msg.setAsynchronous(true);
                mHandler.sendMessageDelayed(msg,
                        ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
                mBeganFromNonInteractive = true;
            } else {
                final int maxCount = getMaxMultiPressPowerCount();
 
                if (maxCount <= 1) {
                    mPowerKeyHandled = true;
                } else {
                    mBeganFromNonInteractive = true;
                }
            }
        }
    }

1.2.frameworks\base\services\core\java\com\android\server\GestureLauncherService.java

双击拉起camera2        mCameraDoubleTapPowerEnabled && 判断距离上一次按键时间 

mCameraDoubleTapPowerEnabled ->isCameraDoubleTapPowerSettingEnabled->Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED

updateCameraDoubleTapPowerEnabled

1
2
3
4
5
private void updateCameraDoubleTapPowerEnabled() {
    boolean enabled = isCameraDoubleTapPowerSettingEnabled(mContext, mUserId);
    synchronized (this) {
        mCameraDoubleTapPowerEnabled = enabled;
    

isCameraDoubleTapPowerSettingEnabled   

1
2
3
4
5
public static boolean isCameraDoubleTapPowerSettingEnabled(Context context, int userId) {
    return isCameraDoubleTapPowerEnabled(context.getResources())
            && (Settings.Secure.getIntForUser(context.getContentResolver(),
                    Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
}

interceptPowerKeyDown  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive) {
    boolean launched = false;
    boolean intercept = false;
    long doubleTapInterval;
    synchronized (this) {
        doubleTapInterval = event.getEventTime() - mLastPowerDown;
        if (mCameraDoubleTapPowerEnabled
                && doubleTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS
                && doubleTapInterval > CAMERA_POWER_DOUBLE_TAP_MIN_TIME_MS) {
            launched = true;
            intercept = interactive;
        }
        mLastPowerDown = event.getEventTime();
    }
    if (launched) {
        Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval="
                + doubleTapInterval + "ms");
        launched = handleCameraLaunchGesture(false /* useWakelock */,
                StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
        if (launched) {
            MetricsLogger.action(mContext, MetricsLogger.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
                    (int) doubleTapInterval);
        }
    }
    MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval);
    return intercept && launched;
}

handleCameraGesture 拉起相机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
 * @return true if camera was launched, false otherwise.
 */
private boolean handleCameraLaunchGesture(boolean useWakelock, int source) {
    boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(),
            Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
    if (!userSetupComplete) {
        if (DBG) Slog.d(TAG, String.format(
                "userSetupComplete = %s, ignoring camera launch gesture.",
                userSetupComplete));
        return false;
    }
    if (DBG) Slog.d(TAG, String.format(
            "userSetupComplete = %s, performing camera launch gesture.",
            userSetupComplete));
 
    if (useWakelock) {
        // Make sure we don't sleep too early
        mWakeLock.acquire(500L);
    }
    StatusBarManagerInternal service = LocalServices.getService(
            StatusBarManagerInternal.class);
    service.onCameraLaunchGestureDetected(source);
    return true;
}

  

posted @   CrushGirl  阅读(786)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示