从 锁屏服务AIDL线程通信案例看Android 底层启动

从 锁屏服务AIDL线程通信案例看Android 底层启动

请确保 你已经阅读过 我的
7篇文章,并且初步理解其核心内容
此处,我们从SystemSever的启动开始说起
目录/android/4.4/frameworks/base/services/java/com/android/server/SystemServer.java
开始继续说起
wm = WindowManagerService.main(context, power, display, inputManager,  
                    wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,  
                    !firstBoot, onlyCore);
<pre>try {
            wm.systemReady();
        } catch (Throwable e) {
            reportWtf("making Window Manager Service ready", e);
        }

 
 
在这里我们初始化了 WindowManagerService
目录(Android4.4/frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
                DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
                ......
                    final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
                ......
                public static WindowManagerService main(final Context context,
		            final PowerManagerService pm, final DisplayManagerService dm,
		            final InputManagerService im, final Handler wmHandler,
		            final boolean haveInputMethods, final boolean showBootMsgs,
		            final boolean onlyCore) {
				     final WindowManagerService[] holder = new WindowManagerService[1];
				        wmHandler.runWithScissors(new Runnable() {
				            @Override
				            public void run() {
				              holder[0] = new WindowManagerService(context, pm, dm, im,
				                        haveInputMethods, showBootMsgs, onlyCore);
				            }
				        }, 0);
				        return holder[0];
		    }
		    .......
		    private WindowManagerService(Context context, PowerManagerService pm,
	            DisplayManagerService displayManager, InputManagerService inputManager,
	            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
            }
                }

这里,我们清楚的看到WindowManagerService也是用AIDL来实现,但是我们这里先不管它
我们先关心
                    final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
                    public void systemReady() {
                        mPolicy.systemReady();
                    }

如果说你还不理解我们的mPolicy 是什么,你可以在返回去看看
这里,我不做出过多解释。
我们只需要知道mPolicy 最终指向了我们PhoneWindowManager
目录(Android4.4/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
public class PhoneWindowManager implements WindowManagerPolicy {
    @Override
    public void systemReady() {
        if (!mHeadless) {
            mKeyguardDelegate = new KeyguardServiceDelegate(mContext, null);
            mKeyguardDelegate.onSystemReady();
        }
        synchronized (mLock) {
            updateOrientationListenerLp();
            mSystemReady = true;
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    updateSettings();
                }
            });
        }
    }
}
启动到了这一步,不用我说,大家都明白是时候初始化 KeyguardServiceDelegate并且告诉锁屏的管理者,我准备好了,该你来控制加载锁屏界面了。接着调用到了KeyguardServiceDelegate.java这个类的onSystemReady()方法
/**
 * A local class that keeps a cache of keyguard state that can be restored in the event
 * keyguard crashes. It currently also allows runtime-selectable
 * local or remote instances of keyguard.
 */
public class KeyguardServiceDelegate {
    public KeyguardServiceDelegate(Context context, LockPatternUtils lockPatternUtils) {
        Intent intent = new Intent();
        intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
        mScrim = createScrim(context);
        if (!context.bindServiceAsUser(intent, mKeyguardConnection,
                Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
            if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
        } else {
            if (DEBUG) Log.v(TAG, "*** Keyguard started");
        }
    }
    
    private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
            mKeyguardService = new KeyguardServiceWrapper(
                    IKeyguardService.Stub.asInterface(service));
            if (mKeyguardState.systemIsReady) {
                // If the system is ready, it means keyguard crashed and restarted.
                mKeyguardService.onSystemReady();
                // This is used to hide the scrim once keyguard displays.
                mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(null));
            }
            if (mKeyguardState.bootCompleted) {
                mKeyguardService.onBootCompleted();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");
            mKeyguardService = null;
        }

    };
    public void onSystemReady() {
        if (mKeyguardService != null) {
            mKeyguardService.onSystemReady();
        } else {
            if (DEBUG) Log.v(TAG, "onSystemReady() called before keyguard service was ready");
            mKeyguardState.systemIsReady = true;
        }
    }
    
    public void onSystemReady() {
        if (mKeyguardService != null) {
            mKeyguardService.onSystemReady();
        } else {
            if (DEBUG) Log.v(TAG, "onSystemReady() called before keyguard service was ready");
            mKeyguardState.systemIsReady = true;
        }
    }    
}

到了这里我们基本一目了然我们的 KeyguardViewMediator充当了Android AIDL理解中主程的角色
同样 毫无疑问,我们的注意力再次集中到
            mKeyguardService = new KeyguardServiceWrapper(
                    IKeyguardService.Stub.asInterface(service));
在Android4.4/frameworks/base/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java中
public class KeyguardServiceWrapper implements IKeyguardService {
    public KeyguardServiceWrapper(IKeyguardService service) {
        mService = service;
    }
}

这样一来,我们的实现自然就转移到了
Android4.4/frameworks\base\packages\Keyguard\src\com\android\keyguard/KeyguardService.java 中
public class KeyguardService extends Service {
    static final String TAG = "KeyguardService";
    static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
    private KeyguardViewMediator mKeyguardViewMediator;

    @Override
    public void onCreate() {
        if (mKeyguardViewMediator == null) {
            mKeyguardViewMediator = new KeyguardViewMediator(
                    KeyguardService.this, new LockPatternUtils(KeyguardService.this));
        }
        Log.v(TAG, "onCreate()");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        // TODO
    }

    void checkPermission() {
        if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
            Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
                    + ", must have permission " + PERMISSION);
        }
    }

    private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
        public boolean isShowing() {
            return mKeyguardViewMediator.isShowing();
        }
        public boolean isSecure() {
            return mKeyguardViewMediator.isSecure();
        }
        public boolean isShowingAndNotHidden() {
            return mKeyguardViewMediator.isShowingAndNotHidden();
        }
        public boolean isInputRestricted() {
            return mKeyguardViewMediator.isInputRestricted();
        }
        public void verifyUnlock(IKeyguardExitCallback callback) {
            mKeyguardViewMediator.verifyUnlock(callback);
        }
        public void keyguardDone(boolean authenticated, boolean wakeup) {
            checkPermission();
            mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
        }
        public void setHidden(boolean isHidden) {
            checkPermission();
            mKeyguardViewMediator.setHidden(isHidden);
        }
        public void dismiss() {
            mKeyguardViewMediator.dismiss();
        }
        public void onDreamingStarted() {
            checkPermission();
            mKeyguardViewMediator.onDreamingStarted();
        }
        public void onDreamingStopped() {
            checkPermission();
            mKeyguardViewMediator.onDreamingStopped();
        }
        public void onScreenTurnedOff(int reason) {
            checkPermission();
            mKeyguardViewMediator.onScreenTurnedOff(reason);
        }
        public void onScreenTurnedOn(IKeyguardShowCallback callback) {
            checkPermission();
            mKeyguardViewMediator.onScreenTurnedOn(callback);
        }
        public void setKeyguardEnabled(boolean enabled) {
            checkPermission();
            mKeyguardViewMediator.setKeyguardEnabled(enabled);
        }
        public boolean isDismissable() {
            return mKeyguardViewMediator.isDismissable();
        }
        public void onSystemReady() {
            checkPermission();
            mKeyguardViewMediator.onSystemReady();
        }
        public void doKeyguardTimeout(Bundle options) {
            checkPermission();
            mKeyguardViewMediator.doKeyguardTimeout(options);
        }
        public void setCurrentUser(int userId) {
            checkPermission();
            mKeyguardViewMediator.setCurrentUser(userId);
        }
        public void showAssistant() {
            checkPermission();
            mKeyguardViewMediator.showAssistant();
        }
        public void dispatch(MotionEvent event) {
            checkPermission();
            mKeyguardViewMediator.dispatch(event);
        }
        public void launchCamera() {
            checkPermission();
            mKeyguardViewMediator.launchCamera();
        }
        public void onBootCompleted() {
            checkPermission();
            mKeyguardViewMediator.onBootCompleted();
        }
    };

}        

那么再来看一下我们的
Android4.4/frameworks\base\core\java\com\android\internal\policy/IKeyguardService.aidl
interface IKeyguardService {
    boolean isShowing();
    boolean isSecure();
    boolean isShowingAndNotHidden();
    boolean isInputRestricted();
    boolean isDismissable();
    oneway void verifyUnlock(IKeyguardExitCallback callback);
    oneway void keyguardDone(boolean authenticated, boolean wakeup);
    oneway void setHidden(boolean isHidden);
    oneway void dismiss();
    oneway void onDreamingStarted();
    oneway void onDreamingStopped();
    oneway void onScreenTurnedOff(int reason);
    void onScreenTurnedOn(IKeyguardShowCallback callback);
    oneway void setKeyguardEnabled(boolean enabled);
    oneway void onSystemReady();
    oneway void doKeyguardTimeout(in Bundle options);
    oneway void setCurrentUser(int userId);
    oneway void showAssistant();
    oneway void dispatch(in MotionEvent event);
    oneway void launchCamera();
    oneway void onBootCompleted();
} 
那么我们的AIDL框架自然就自动布好
也就是说最终的时间处理交给了我们的
Android4.4/frameworks\base\packages\Keyguard\src\com\android\keyguard/KeyguardViewMediator.java
/**
     * Let us know that the system is ready after startup.
     */
    public void onSystemReady() {
        mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
        synchronized (this) {
            if (DEBUG) Log.d(TAG, "onSystemReady");
            mSystemReady = true;
            mUpdateMonitor.registerCallback(mUpdateCallback);

            // Suppress biometric unlock right after boot until things have settled if it is the
            // selected security method, otherwise unsuppress it.  It must be unsuppressed if it is
            // not the selected security method for the following reason:  if the user starts
            // without a screen lock selected, the biometric unlock would be suppressed the first
            // time they try to use it.
            //
            // Note that the biometric unlock will still not show if it is not the selected method.
            // Calling setAlternateUnlockEnabled(true) simply says don't suppress it if it is the
            // selected method.
            if (mLockPatternUtils.usingBiometricWeak()
                    && mLockPatternUtils.isBiometricWeakInstalled()
                    || mLockPatternUtils.usingVoiceWeak()
                    && FeatureOption.MTK_VOICE_UNLOCK_SUPPORT) {
                if (DEBUG) Log.d(TAG, "suppressing biometric unlock during boot");
                mUpdateMonitor.setAlternateUnlockEnabled(false);
            } else {
                mUpdateMonitor.setAlternateUnlockEnabled(true);
            }
            /// M: power-off alarm @{
            if (!KeyguardUpdateMonitor.isAlarmBoot()) {
                doKeyguardLocked();
            }
            /// @}
        }
        // Most services aren't available until the system reaches the ready state, so we
        // send it here when the device first boots.
        maybeSendUserPresentBroadcast();
    }

接着由doKeyguardLocked()这个方法来做启动锁屏界面的预处理,来看看这个方法都做了什么:

[java]  view plain copy print ?
  1. private void doKeyguardLocked() {  
  2.     doKeyguardLocked(null);  
  3. }  
  4.   
  5. /** 
  6.  * Enable the keyguard if the settings are appropriate. 
  7.  */  
  8. private void doKeyguardLocked(Bundle options) {  
  9.     // if another app is disabling us, don't show  
  10.     if (!mExternallyEnabled || KeyguardUpdateMonitor.isAlarmBoot()) {  
  11.         if (DEBUG) KeyguardUtils.xlogD(TAG, "doKeyguard: not showing because externally disabled");  
  12.   
  13.         // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes  
  14.         // for an occasional ugly flicker in this situation:  
  15.         // 1) receive a call with the screen on (no keyguard) or make a call  
  16.         // 2) screen times out  
  17.         // 3) user hits key to turn screen back on  
  18.         // instead, we reenable the keyguard when we know the screen is off and the call  
  19.         // ends (see the broadcast receiver below)  
  20.         // TODO: clean this up when we have better support at the window manager level  
  21.         // for apps that wish to be on top of the keyguard  
  22.         return;  
  23.     }  
  24.   
  25.     // if the keyguard is already showing, don't bother  
  26.     if (mKeyguardViewManager.isShowing()) {  
  27.         if (DEBUG) KeyguardUtils.xlogD(TAG, "doKeyguard: not showing because it is already showing");  
  28.         return;  
  29.     }  
  30.   
  31.     // if the setup wizard hasn't run yet, don't show  
  32.     if (DEBUG) KeyguardUtils.xlogD(TAG, "doKeyguard: get keyguard.no_require_sim property before");  
  33.     final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",  
  34.             false);  
  35.     if (DEBUG) KeyguardUtils.xlogD(TAG, "doKeyguard: get keyguard.no_require_sim property after");  
  36.     final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();  
  37.     final IccCardConstants.State state = mUpdateMonitor.getSimState();  
  38.     boolean lockedOrMissing = false;  
  39.     /// M: Support GeminiPlus  
  40.     for (int i = PhoneConstants.GEMINI_SIM_1; i <= KeyguardUtils.getMaxSimId(); i++) {  
  41.         lockedOrMissing = (lockedOrMissing || isLockedOrMissingGemini(i, requireSim));  
  42.         if (lockedOrMissing) {  
  43.             break;  
  44.         }  
  45.     }  
  46.       
  47.     if (DEBUG) KeyguardUtils.xlogD(TAG, "doKeyguard: get sim state after");  
  48.   
  49.     /// M: MTK MOTA UPDATE when on ics2 keygaurd set none,update to JB,the keyguard will show LockScreen.  
  50.     /// MTK MOTA UPDATE when the phone first boot,check the settingDB mirged or not ,because mota update,  
  51.     /// the settingdb migrate slow than keygaurd(timing sequence problem) @{   
  52.     boolean keyguardDisable = false;  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值