SystemUI---双击电源键打开Camera(重启第一次无法启动相机)

src/com/android/keyguard/KeyguardSecurityContainerController.java

        if (finish) {
            mSecurityCallback.finish(strongAuth, targetUserId);
            Log.d(TAG, "finish ");
        }
        if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish() - return finish = " + finish) ;
        
        /* add by *** for not allowed open camera begin*/
        if (finish) {
            SystemProperties.set("sys.keyguard_open","1");
        }
        /* add by *** for not allowed open camera begin*/

        return finish;
    }

src/com/android/systemui/statusbar/phone/StatusBar.java

    @Override
    public void onCameraLaunchGestureDetected(int source) {
        mLastCameraLaunchSource = source;
        /* add by *** for not allowed open camera begin*/
        if ("0".equals(SystemProperties.get("sys.keyguard_open","0"))) {
            return;
        } else {
            Slog.d(TAG, "The camera is not allowed to start because it has never been unlocked");
        }
        /* add by **** for not allowed open camera end*/

        if (isGoingToSleep()) {
            if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Finish going to sleep before launching camera");
            mLaunchCameraOnFinishedGoingToSleep = true;
            return;
        }

分析双击电源键打开相机的流程:

找到电源按键上报的代码:

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

关键函数:

在这两个函数中处理,注意可能被重写导致不在PhoneWindowManager.java中出现

1)interceptKeyBeforeDispatching

2)interceptKeyBeforeQueueing

处理流程:

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

interceptKeyBeforeQueueing->
handleKeyGesture->
mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched);

public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {

......
        if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
            Log.d(TAG,"handleKeyGesture +000");
            handleKeyGesture(event, interactiveAndOn);
        }
......
}

/*********************************************************************************/
    private void handleKeyGesture(KeyEvent event, boolean interactive) {
......
        if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) {
            mPowerKeyHandled = handleCameraGesture(event, interactive);
            if (mPowerKeyHandled) {
                // handled by camera gesture.
                mSingleKeyGestureDetector.reset();
                return;
            }
        }

        mSingleKeyGestureDetector.interceptKey(event, interactive);
    }

/********************************************************************************/
    // The camera gesture will be detected by GestureLauncherService.
    private boolean handleCameraGesture(KeyEvent event, boolean interactive) {
        // camera gesture.
......
        final boolean intercept =
                mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched);
......
    }

/********************************************************************************/

base/services/core/java/com/android/server/GestureLauncherService.java

interceptPowerKeyDown->

handleCameraGesture->

onCameraLaunchGestureDetected

    public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive,
            MutableBoolean outLaunched) {
.......

        if (launchCamera) {
            Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval="
                    + powerTapInterval + "ms");
            launchCamera = handleCameraGesture(false /* useWakelock */,
                    StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
            if (launchCamera) {
                mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
                        (int) powerTapInterval);
                mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER);
            }
        } else if (launchEmergencyGesture) {
            Slog.i(TAG, "Emergency gesture detected, launching.");
            launchEmergencyGesture = handleEmergencyGesture();
            mUiEventLogger.log(GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
        }
.......
    }

/*********************************************************************************/
    @VisibleForTesting
    boolean handleCameraGesture(boolean useWakelock, int source) {
......
            if (useWakelock) {
                // Make sure we don't sleep too early
                mWakeLock.acquire(500L);
            }
            StatusBarManagerInternal service = LocalServices.getService(
                    StatusBarManagerInternal.class);
            service.onCameraLaunchGestureDetected(source);
            return true;
......
    }

base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java

        @Override
        public void onCameraLaunchGestureDetected(int source) {
            if (mBar != null) {
                try {
                    mBar.onCameraLaunchGestureDetected(source);
                } catch (RemoteException e) {
                }
            }
        }

base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

    @Override
    public void onCameraLaunchGestureDetected(int source) {
        mLastCameraLaunchSource = source;
        // Slog.e(TAG,  Log.getStackTraceString(new Throwable()));
        /* add by zhoujian for not allowed open camera begin*/
        if ("0".equals(SystemProperties.get("sys.keyguard_open","0"))) {
            return;
        } else {
            Slog.e(TAG, "The camera is allowed to start because it has been unlocked");
        }
        /* add by zhoujian for not allowed open camera end*/

        if (isGoingToSleep()) {
            if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Finish going to sleep before launching camera");
            mLaunchCameraOnFinishedGoingToSleep = true;
            return;
        }
        if (!mNotificationPanelViewController.canCameraGestureBeLaunched()) {
            if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Can't launch camera right now");
            return;
        }
        if (!mDeviceInteractive) {
            mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
                    "com.android.systemui:CAMERA_GESTURE");
        }
        vibrateForCameraGesture();

        if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
            Log.v(TAG, "Camera launch");
            /// M: ALPS05974700 Fix the screen desplay white while double click power key
            mCameraLaunchPowerDouble = true;
            mKeyguardUpdateMonitor.onCameraLaunched();//屏蔽人脸或者指纹解锁
        }

        if (!mStatusBarKeyguardViewManager.isShowing()) {
            final Intent cameraIntent = CameraIntents.getInsecureCameraIntent(mContext);
            startActivityDismissingKeyguard(cameraIntent,
                    false /* onlyProvisioned */, true /* dismissShade */,
                    true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0,
                    null /* animationController */);
        } else {

            if (!mDeviceInteractive) {
                // Avoid flickering of the scrim when we instant launch the camera and the bouncer
                // comes on.
                mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
            }

            if (isWakingUpOrAwake()) {
                if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Launching camera aaa");
                if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                    mStatusBarKeyguardViewManager.reset(true /* hide */);
                }
                // M: Mtk add for fix unresponse when swipe lock and occluded.
                if (!mStatusBarKeyguardViewManager.isSecure()
                        && mStatusBarKeyguardViewManager.isOccluded()) {
                    Slog.d(TAG, "Non-Secure unlock, no need to launch camera");
                    return;
                }

                mNotificationPanelViewController.launchCamera(
                        mDeviceInteractive /* animate */, source);//启动相机

                updateScrimController();
            } else {
                // We need to defer the camera launch until the screen comes on, since otherwise
                // we will dismiss us too early since we are waiting on an activity to be drawn and
                // incorrectly get notified because of the screen on event (which resumes and pauses
                // some activities)
                if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Deferring until screen turns on");
                mLaunchCameraWhenFinishedWaking = true;
            }
        }
    }

startActivityDismissingKeyguard()

    private void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
            final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching,
            final Callback callback, int flags,
            @Nullable ActivityLaunchAnimator.Controller animationController) {
        Slog.e(TAG,  Log.getStackTraceString(new Throwable())); 

        if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return;

        final boolean willLaunchResolverActivity =
                mActivityIntentHelper.wouldLaunchResolverActivity(intent,
                        mLockscreenUserManager.getCurrentUserId());

        boolean animate =
                animationController != null && !willLaunchResolverActivity && shouldAnimateLaunch(
                        true /* isActivityIntent */);
        ActivityLaunchAnimator.Controller animController =
                animate ? wrapAnimationController(animationController, dismissShade) : null;

        // If we animate, we will dismiss the shade only once the animation is done. This is taken
        // care of by the StatusBarLaunchAnimationController.
        boolean dismissShadeDirectly = dismissShade && animController == null;

        Runnable runnable = () -> {
            mAssistManagerLazy.get().hideAssist();
            intent.setFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.addFlags(flags);
            int[] result = new int[]{ActivityManager.START_CANCELED};

            mActivityLaunchAnimator.startIntentWithAnimation(animController,
                    animate, intent.getPackage(), (adapter) -> {
                        ActivityOptions options = new ActivityOptions(
                                getActivityOptions(mDisplayId, adapter));
                        options.setDisallowEnterPictureInPictureWhileLaunching(
                                disallowEnterPictureInPictureWhileLaunching);
                        if (CameraIntents.isInsecureCameraIntent(intent)) {
                            // Normally an activity will set it's requested rotation
                            // animation on its window. However when launching an activity
                            // causes the orientation to change this is too late. In these cases
                            // the default animation is used. This doesn't look good for
                            // the camera (as it rotates the camera contents out of sync
                            // with physical reality). So, we ask the WindowManager to
                            // force the crossfade animation if an orientation change
                            // happens to occur during the launch.
                            options.setRotationAnimationHint(
                                    WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
                        }
                        if (intent.getAction() == Settings.Panel.ACTION_VOLUME) {
                            // Settings Panel is implemented as activity(not a dialog), so
                            // underlying app is paused and may enter picture-in-picture mode
                            // as a result.
                            // So we need to disable picture-in-picture mode here
                            // if it is volume panel.
                            options.setDisallowEnterPictureInPictureWhileLaunching(true);
                        }

                        try {
                            result[0] = ActivityTaskManager.getService().startActivityAsUser(
                                    null, mContext.getBasePackageName(),
                                    mContext.getAttributionTag(),
                                    intent,
                                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                                    null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
                                    options.toBundle(), UserHandle.CURRENT.getIdentifier());
                        } catch (RemoteException e) {
                            Log.w(TAG, "Unable to start activity", e);
                        }
                        return result[0];
                    });

            if (callback != null) {
                callback.onActivityStarted(result[0]);
            }
        };
        Runnable cancelRunnable = () -> {
            if (callback != null) {
                callback.onActivityStarted(ActivityManager.START_CANCELED);
            }
        };
        executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
                willLaunchResolverActivity, true /* deferred */, animate);
    }

src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java

launchCamera->launchAffordance

    public void launchCamera(boolean animate, int source) {
        if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
            mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP;
        } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) {
            mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE;
        } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) {
            mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER;
        } else {

            // Default.
            mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
        }

        // If we are launching it when we are occluded already we don't want it to animate,
        // nor setting these flags, since the occluded state doesn't change anymore, hence it's
        // never reset.
        Log.d(TAG, "launchCamera +++");
        if (!isFullyCollapsed()) {
            setLaunchingAffordance(true);//启动动画????
        } else {
            animate = false;
        }
        mAffordanceHasPreview = mKeyguardBottomArea.getRightPreview() != null;
        mAffordanceHelper.launchAffordance(
                animate, mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
    }

src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java

......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值