android关机流程前

介绍按住关机按键后到调用系统关机动画之前流程

接受到长按power按键

PhoneWindowManager.java

   public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
   ...
           switch (keyCode) {
                           case KeyEvent.KEYCODE_POWER: {
                // Any activity on the power button stops the accessibility shortcut
                cancelPendingAccessibilityShortcutAction();
                result &= ~ACTION_PASS_TO_USER;
                isWakeKey = false; // wake-up will be handled separately
                if (down) {
                    interceptPowerKeyDown(event, interactive);//1
                } else {
                    interceptPowerKeyUp(event, interactive, canceled);
                }
                break;
            }
           }
   }

在1处,调用interceptPowerKeyDown,发送一个延时的message,因为要长按才会弹出关机界面,所以如果在延时结束前就取消了就会停止发送.

    private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
        。。。
                        if (hasLongPressOnPowerBehavior()) {
                    Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
                    msg.setAsynchronous(true);
                    mHandler.sendMessageDelayed(msg,
                            ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());//2
                }
    }
    
    private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
    final boolean handled = canceled || mPowerKeyHandled;
    mScreenshotChordPowerKeyTriggered = false;
    cancelPendingScreenshotChordAction();
    cancelPendingPowerKeyAction();
    。。
    }
    private void cancelPendingPowerKeyAction() {
    if (!mPowerKeyHandled) {
        mPowerKeyHandled = true;
        mHandler.removeMessages(MSG_POWER_LONG_PRESS);//3
        }
    }    

在2处和3处,分别是发送延时关机和取消关机的操作.

    private class PolicyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_POWER_LONG_PRESS:
                    powerLongPress();
                    break;
                }
        }
        。。。。
    }
        
    private void powerLongPress() {
            showGlobalActionsInternal();
    }

    
    void showGlobalActionsInternal() {
        sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
        if (mGlobalActions == null) {
            mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
        }
        final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
        mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
        if (keyguardShowing) {
            // since it took two seconds of long press to bring this up,
            // poke the wake lock so they have some time to see the dialog.
            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
        }
    }
GlobalActionsclass 
implements GlobalActionsListener {

        public void showDialog(boolean keyguardShowing, boolean deviceProvisioned) {
        if (DEBUG) Slog.d(TAG, "showDialog " + keyguardShowing + " " + deviceProvisioned);
        mKeyguardShowing = keyguardShowing;
        mDeviceProvisioned = deviceProvisioned;
        mShowing = true;
        if (mStatusBarConnected) {
            mStatusBarInternal.showGlobalActions();//4
            mHandler.postDelayed(mShowTimeout, 5000);//5
        } else {
            // SysUI isn't alive, show legacy menu.
            ensureLegacyCreated();
            mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned);
        }
    }
    
    @Override
    public void onGlobalActionsShown() {
        if (DEBUG) Slog.d(TAG, "onGlobalActionsShown");
        // SysUI is showing, remove timeout callbacks.
        mHandler.removeCallbacks(mShowTimeout);//6
    }    
    
}

4处尝试调用的SystemUI的对话框,这个对话框显示关机重启操作按钮供用户选择。如果连接失败,就会失败就会调用系统的对话框,所有在5处会有同一个延时调用系统对话框的messge,如果成功调用SystemUI的对话框,回调会在6处.remove掉.

    public GlobalActions(Context context, WindowManagerFuncs windowManagerFuncs) {
        mContext = context;
        mHandler = new Handler();
        mWindowManagerFuncs = windowManagerFuncs;
        mStatusBarInternal = LocalServices.getService(StatusBarManagerInternal.class);

        // Some form factors do not have a status bar.
        if (mStatusBarInternal != null) {
            mStatusBarInternal.setGlobalActionsListener(this);
        }
    }

StatusBarManagerInternal是一个接口,那么获取的上面mStatusBarInternal对象应该是实现了StatusBarManagerInternal接口。

//添加service,与getService对应
    public StatusBarManagerService(Context context, WindowManagerService windowManager) {
        mContext = context;
        mWindowManager = windowManager;

        LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
    }
    /**
     * Private API used by NotificationManagerService.
     */
    private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
        private boolean mNotificationLightOn;
        。。。
                @Override
        public void showGlobalActions() {
            if (mBar != null) {
                try {
                    mBar.showGlobalActionsMenu();
                } catch (RemoteException ex) {}
            }
        }
        。。。
    }

这个mBar定义IStatusBar mBar,是一个跨进程的操作,从注解我们可以看出IStatusBar,来源status bar service.

SystemUI实现
CommandQueue.java

 
    @Override
    public void showGlobalActionsMenu() {
        synchronized (mLock) {
            mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS);
            mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget();
        }
    }
    

GlobalActionsComponent.java

public class GlobalActionsComponent extends SystemUI implements Callbacks, GlobalActionsManager {

    private Extension mExtension;
    private IStatusBarService mBarService;

    @Override
    public void start() {
        mBarService = IStatusBarService.Stub.asInterface(
                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
        mExtension = Dependency.get(ExtensionController.class).newExtension(GlobalActions.class)
                .withPlugin(GlobalActions.class)
                .withDefault(() -> new GlobalActionsImpl(mContext))
                .build();
        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
    }

    @Override
    public void handleShowGlobalActionsMenu() {
        mExtension.get().showGlobalActions(this);
    }
}

最终:

public class GlobalActionsImpl implements GlobalActions {

    private final Context mContext;
    private final KeyguardMonitor mKeyguardMonitor;
    private final DeviceProvisionedController mDeviceProvisionedController;
    private GlobalActionsDialog mGlobalActions;

    public GlobalActionsImpl(Context context) {
        mContext = context;
        mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
        mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
    }

    @Override
    public void showGlobalActions(GlobalActionsManager manager) {
        if (mGlobalActions == null) {
            final ContextThemeWrapper context = new ContextThemeWrapper(mContext,
                    android.R.style.Theme_Material_Light);
            mGlobalActions = new GlobalActionsDialog(context, manager);
        }
        mGlobalActions.showDialog(mKeyguardMonitor.isShowing(),
                mDeviceProvisionedController.isDeviceProvisioned());
    }
}

GlobalActionsDialog负责显示关机,重启的对话框,在这里我们可以自定义关机对话框。
这里面对于关机,重启,安全模式是调用系统api完成的

//关机
mWindowManagerFuncs.shutdown();
//以安全模式重启
mWindowManagerFuncs.reboot(true);
//重启
mWindowManagerFuncs.reboot(false);

具体重启是如何操作,再看mWindowManagerFuncs对象的实现类GlobalActionsComponent。

GlobalActionsComponent.java

    @Override
    public void reboot(boolean safeMode) {
        try {
            mBarService.reboot(safeMode);
        } catch (RemoteException e) {
        }
    }

mBarService的实现类
StatusBarManagerService.java

     */
    @Override
    public void reboot(boolean safeMode) {
        enforceStatusBarService();
        long identity = Binder.clearCallingIdentity();
        try {
            mHandler.post(() -> {
                // ShutdownThread displays UI, so give it a UI context.
                // TINNO START
                // Modified by Jameson.xu on 20171114 for VBNLITEIA-1113,device reset exception
                if (safeMode) {
                    //ShutdownThread.rebootSafeMode(getUiContext(), false);
                    //safe reboot,should show dialog for user(CTS 3PL(windware) need);for safemode function,CDAAOB-224,DATE20180825
                    ShutdownThread.rebootSafeMode(getUiContext(), true);
                } else {
                    ShutdownThread.reboot(getUiContext(),
                            PowerManager.SHUTDOWN_USER_REQUESTED, true);
                }
                // TINNO END
            });
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }


    /**
     * Allows the status bar to shutdown the device.
     */
    @Override
    public void shutdown() {
        enforceStatusBarService();
        long identity = Binder.clearCallingIdentity();
        try {
            // ShutdownThread displays UI, so give it a UI context.
            // TINNO START
            // Modified by Jameson.xu on 20171114 for VBNLITEIA-1113,device reset exception
            mHandler.post(() ->
                    ShutdownThread.shutdown(getUiContext(),
                        PowerManager.SHUTDOWN_USER_REQUESTED, true));
            // TINNO END
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

最终在ShutdownThread.java处理

你可能感兴趣的:(android框架)