一直想要整理一下keyguard(锁屏)模块的相关流程,由于各种原因总是没真正着手开始做,一直拖也不是个办法,所以就索性开始了。

这篇内容会比较偏分析,所以闲话就少扯点了。

锁屏模块位于framework中,有别于一般的上层应用,它的逻辑代码和view视图,资源文件散布在framework的几处地方,这也给新手分析该模块带来也一点的麻烦。下面我会试着来捋捋这些散落的珠子。

1.文件目录:

a,逻辑是Frameworks/base/policy/src/com/android/internal/policy/ impl/目录下

b,视图view是在 Framework/base/core/java/com/android/internal/ widget/路径下:

文件夹multiwaveview就是从4.0开始加入的环形解锁视图及相应动画实现。

c,资源文件在Framework/base/core/res/res/下。

这个就不贴目录了,和一般android应用一样,图片资源,布局文件都很规矩的放在相应分辨率的文件夹下。大致了解了锁屏模块文件分布后,我们一般就要开始看源代码了。

2,keyguard锁屏流程图:

现在看不明白的没关系可以先跳过,先看下面,再更几遍源码就会发现该图就是个小菜了。

3,keyguard锁屏view层次图:

一般4.0真机都会有五种锁屏方式:

这里和2.3有明显区别了,2.3的view视图如下:

可以看出来以前的锁屏流程是分正常锁屏和图案锁屏方式。在选择图案解锁方式,是不会显示正常解锁slidingview的。但是选择密码解锁就会出现需要用户二次解锁的情况。三星2.2就对此进行了流程优化统一。本人也试着做了,有兴趣可以。。。

4.0以后该流程得到了官方的统一,选择任何锁屏方式,用户都只需要一次解锁。流程上也更直观了。相信Google,必须是越来越good。

4,keyguard锁屏重要类分析:

1,KeyguardScreenback.java和KeyguardViewCallback.java

说明:接口两个,等着被LockPatternKeyguardView.java实例化。注意Keyguard ViewCallback.java还偷偷捞外快,同时替KeyguardViewMediator.java服务。

[java] view plain copy print ?
  1. public interface KeyguardScreenCallback extends KeyguardViewCallback {
  2. void goToLockScreen();//Transition to the lock screen.
  3. void goToUnlockScreen();//Transition to the unlock screen.
  4. void forgotPattern(boolean isForgotten);// The user forgot their pattern
  5. boolean isSecure();//Whether the keyguard requires some sort of PIN.
  6. /**
  7. * @return Whether we are in a mode where we only want to verify the
  8. *   user can get past the keyguard.
  9. */
  10. boolean isVerifyUnlockOnly();
  11. /**
  12. * Stay on me, but recreate me (so I can use a different layout).
  13. */
  14. void recreateMe(Configuration config);
  15. void takeEmergencyCallAction();//Take action to send an emergency call
  16. void reportFailedUnlockAttempt();//user had a failed attempt to unlock
  17. void reportSuccessfulUnlockAttempt();//successfully entered their password
  18. /**
  19. * Report whether we there's another way to unlock the device.
  20. * @return true
  21. */
  22. boolean doesFallbackUnlockScreenExist();
  23. }
public interface KeyguardScreenCallback extends KeyguardViewCallback {void goToLockScreen();//Transition to the lock screen.void goToUnlockScreen();//Transition to the unlock screen.void forgotPattern(boolean isForgotten);// The user forgot their patternboolean isSecure();//Whether the keyguard requires some sort of PIN./*** @return Whether we are in a mode where we only want to verify the*   user can get past the keyguard.*/boolean isVerifyUnlockOnly();/*** Stay on me, but recreate me (so I can use a different layout).*/void recreateMe(Configuration config);void takeEmergencyCallAction();//Take action to send an emergency callvoid reportFailedUnlockAttempt();//user had a failed attempt to unlockvoid reportSuccessfulUnlockAttempt();//successfully entered their password/*** Report whether we there's another way to unlock the device.* @return true*/boolean doesFallbackUnlockScreenExist();
}
[java] view plain copy print ?
  1. public interface KeyguardViewCallback {
  2. /**
  3. * Request the wakelock to be poked for the default amount of time.
  4. */
  5. void pokeWakelock();//使屏幕保持亮一段时间。
  6. void pokeWakelock(int millis);
  7. void keyguardDone(boolean authenticated);// Report keyguard is done.
  8. /**
  9. * Report that the keyguard is done drawing.
  10. */
  11. void keyguardDoneDrawing();//所有锁屏视图完成draw时调用该方法。
  12. }
public interface KeyguardViewCallback {/*** Request the wakelock to be poked for the default amount of time.*/void pokeWakelock();//使屏幕保持亮一段时间。void pokeWakelock(int millis);void keyguardDone(boolean authenticated);// Report keyguard is done./*** Report that the keyguard is done drawing.*/void keyguardDoneDrawing();//所有锁屏视图完成draw时调用该方法。
}

google的注释实在是太优雅了,都翻译成中文反而会有所误导且影响美观,单词看不明白的,有道去。实在懒的话,意会也行的;)

2. KeyguardScreen.java

说明:接口一个,坐等LockScreen.java等具体锁屏方式来实现它。

[java] view plain copy print ?
  1. public interface KeyguardScreen {
  2. boolean needsInput();//是否需要键盘进行输入
  3. void onPause();//view不在最上层时被系统调用。
  4. void onResume();//view重新掌权时被系统调用
  5. void cleanUp();//view被扫地出门。
  6. }
public interface KeyguardScreen {boolean needsInput();//是否需要键盘进行输入void onPause();//view不在最上层时被系统调用。void onResume();//view重新掌权时被系统调用void cleanUp();//view被扫地出门。
}

3. KeyguardStatusViewManager.java

说明:这个类是4.0后新增加的,其实它是从2.3的LockScreen.java分离了出来,所以它还是摆脱不了命运的束缚,依然要为LockScreen.java服务,而且它比以前更累了,如果条件需要它还要服侍其他如密码解锁,图形解锁等方式。功能就是状态视图总管。

[java] view plain copy print ?
  1. /***
  2. * Manages a number of views inside of LockScreen layouts. See below for a list of widgets
  3. */
  4. class KeyguardStatusViewManager implements OnClickListener {
  5. public KeyguardStatusViewManager(View view, KeyguardUpdateMonitor updateMonitor,LockPatternUtils lockPatternUtils, KeyguardScreenCallback callback,boolean showEmergencyButtonByDefault) {
  6. if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()");
  7. mContainer = view; //视图容器
  8. mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);//格式日期
  9. mLockPatternUtils = lockPatternUtils;
  10. mUpdateMonitor = updateMonitor;
  11. mCallback = callback;
  12. mCarrierView = (TextView) findViewById(R.id.carrier);//运营商标识
  13. mDateView = (TextView) findViewById(R.id.date);//日期
  14. mStatus1View = (TextView) findViewById(R.id.status1);//sim卡状态
  15. mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);//闹铃状态
  16. mOwnerInfoView = (TextView) findViewById(R.id.propertyOf);
  17. mTransportView = (TransportControlView) findViewById(R.id.transport);
  18. mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
  19. mShowEmergencyButtonByDefault = showEmergencyButtonByDefault;
  20. //紧急呼叫按钮
  21. // Hide transport control view until we know we need to show it.
  22. if (mTransportView != null) {
  23. mTransportView.setVisibility(View.GONE);
  24. }
  25. if (mEmergencyCallButton != null) {
  26. mEmergencyCallButton.setText(R.string.lockscreen_emergency_call);
  27. mEmergencyCallButton.setOnClickListener(this);
  28. mEmergencyCallButton.setFocusable(false); // touch only!
  29. }
  30. mTransientTextManager = new TransientTextManager(mCarrierView);
  31. mUpdateMonitor.registerInfoCallback(mInfoCallback);
  32. mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
  33. resetStatusInfo();//更新电池状态信息
  34. refreshDate();//刷新时间
  35. updateOwnerInfo();//更新所有者的信息
  36. // Required to get Marquee to work.
  37. final View scrollableViews[] = { mCarrierView, mDateView, mStatus1View, mOwnerInfoView,
  38. mAlarmStatusView };
  39. for (View v : scrollableViews) {
  40. if (v != null) {
  41. v.setSelected(true);
  42. }
  43. }
  44. }
/**** Manages a number of views inside of LockScreen layouts. See below for a list of widgets
*/
class KeyguardStatusViewManager implements OnClickListener {public KeyguardStatusViewManager(View view, KeyguardUpdateMonitor updateMonitor,LockPatternUtils lockPatternUtils, KeyguardScreenCallback callback,boolean showEmergencyButtonByDefault) {if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()");mContainer = view; //视图容器mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);//格式日期mLockPatternUtils = lockPatternUtils;mUpdateMonitor = updateMonitor;mCallback = callback;mCarrierView = (TextView) findViewById(R.id.carrier);//运营商标识mDateView = (TextView) findViewById(R.id.date);//日期mStatus1View = (TextView) findViewById(R.id.status1);//sim卡状态mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);//闹铃状态mOwnerInfoView = (TextView) findViewById(R.id.propertyOf);mTransportView = (TransportControlView) findViewById(R.id.transport);mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);mShowEmergencyButtonByDefault = showEmergencyButtonByDefault;
//紧急呼叫按钮// Hide transport control view until we know we need to show it.if (mTransportView != null) {mTransportView.setVisibility(View.GONE);}if (mEmergencyCallButton != null) {mEmergencyCallButton.setText(R.string.lockscreen_emergency_call);mEmergencyCallButton.setOnClickListener(this);mEmergencyCallButton.setFocusable(false); // touch only!}mTransientTextManager = new TransientTextManager(mCarrierView);mUpdateMonitor.registerInfoCallback(mInfoCallback);mUpdateMonitor.registerSimStateCallback(mSimStateCallback);resetStatusInfo();//更新电池状态信息refreshDate();//刷新时间updateOwnerInfo();//更新所有者的信息// Required to get Marquee to work.final View scrollableViews[] = { mCarrierView, mDateView, mStatus1View, mOwnerInfoView,mAlarmStatusView };for (View v : scrollableViews) {if (v != null) {v.setSelected(true);}}}

4. LockScreen.java

说明:五种锁屏方式之一,为系统默认设置选用,名为滑动解锁,也就是4.0的那个带锁的圆。它继承于LinearLayout并实现了KeyguardScreen接口,所以他具备了接受视图的解锁事件并作出响应。

[java] view plain copy print ?
  1. /**
  2. * The screen within {@link LockPatternKeyguardView} that shows general
  3. * information about the device depending on its state, and how to get
  4. * past it, as applicable.
  5. */
  6. class LockScreen extends LinearLayout implements KeyguardScreen {
  7. class SlidingTabMethods implements SlidingTab.OnTriggerListener, UnlockWidgetCommonMethods {
  8. private final SlidingTab mSlidingTab;
  9. SlidingTabMethods(SlidingTab slidingTab) {
  10. mSlidingTab = slidingTab;
  11. }
  12. public void updateResources() {
  13. .......
  14. }
  15. /** 解锁响应*/
  16. public void onTrigger(View v, int whichHandle) {
  17. if (whichHandle == SlidingTab.OnTriggerListener.LEFT_HANDLE) {
  18. mCallback.goToUnlockScreen();
  19. } else if (whichHandle == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {
  20. toggleRingMode();
  21. mCallback.pokeWakelock();
  22. }
  23. }
  24. /** {@inheritDoc} */
  25. public void onGrabbedStateChange(View v, int grabbedState) {
  26. .......
  27. }
  28. public View getView() {
  29. return mSlidingTab;
  30. }
  31. public void reset(boolean animate) {
  32. mSlidingTab.reset(animate);
  33. }
  34. public void ping() {
  35. }
  36. }
  37. class WaveViewMethods implements WaveView.OnTriggerListener, UnlockWidgetCommonMethods {
  38. private final WaveView mWaveView;
  39. WaveViewMethods(WaveView waveView) {
  40. mWaveView = waveView;
  41. }
  42. /** {@inheritDoc} */
  43. public void onTrigger(View v, int whichHandle) {
  44. if (whichHandle == WaveView.OnTriggerListener.CENTER_HANDLE) {
  45. requestUnlockScreen();
  46. }
  47. }
  48. /** {@inheritDoc} */
  49. public void onGrabbedStateChange(View v, int grabbedState) {
  50. // Don't poke the wake lock when returning to a state where the handle is
  51. // not grabbed since that can happen when the system (instead of the user)
  52. // cancels the grab.
  53. if (grabbedState == WaveView.OnTriggerListener.CENTER_HANDLE) {
  54. mCallback.pokeWakelock(STAY_ON_WHILE_GRABBED_TIMEOUT);
  55. }
  56. }
  57. public void updateResources() {
  58. }
  59. public View getView() {
  60. return mWaveView;
  61. }
  62. public void reset(boolean animate) {
  63. mWaveView.reset();
  64. }
  65. public void ping() {
  66. }
  67. }
  68. class MultiWaveViewMethods implements MultiWaveView.OnTriggerListener,
  69. UnlockWidgetCommonMethods {
  70. private final MultiWaveView mMultiWaveView;
  71. private boolean mCameraDisabled;
  72. MultiWaveViewMethods(MultiWaveView multiWaveView) {
  73. mMultiWaveView = multiWaveView;
  74. final boolean cameraDisabled = mLockPatternUtils.getDevicePolicyManager()
  75. .getCameraDisabled(null);
  76. if (cameraDisabled) {
  77. Log.v(TAG, "Camera disabled by Device Policy");
  78. mCameraDisabled = true;
  79. } else {
  80. // Camera is enabled if resource is initially defined for MultiWaveView
  81. // in the lockscreen layout file
  82. mCameraDisabled = mMultiWaveView.getTargetResourceId()
  83. != R.array.lockscreen_targets_with_camera;
  84. }
  85. }
/*** The screen within {@link LockPatternKeyguardView} that shows general* information about the device depending on its state, and how to get* past it, as applicable.*/
class LockScreen extends LinearLayout implements KeyguardScreen {class SlidingTabMethods implements SlidingTab.OnTriggerListener, UnlockWidgetCommonMethods {private final SlidingTab mSlidingTab;SlidingTabMethods(SlidingTab slidingTab) {mSlidingTab = slidingTab;}public void updateResources() {.......}/** 解锁响应*/public void onTrigger(View v, int whichHandle) {if (whichHandle == SlidingTab.OnTriggerListener.LEFT_HANDLE) {mCallback.goToUnlockScreen();} else if (whichHandle == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {toggleRingMode();mCallback.pokeWakelock();}}/** {@inheritDoc} */public void onGrabbedStateChange(View v, int grabbedState) {.......}public View getView() {return mSlidingTab;}public void reset(boolean animate) {mSlidingTab.reset(animate);}public void ping() {}}class WaveViewMethods implements WaveView.OnTriggerListener, UnlockWidgetCommonMethods {private final WaveView mWaveView;WaveViewMethods(WaveView waveView) {mWaveView = waveView;}/** {@inheritDoc} */public void onTrigger(View v, int whichHandle) {if (whichHandle == WaveView.OnTriggerListener.CENTER_HANDLE) {requestUnlockScreen();}}/** {@inheritDoc} */public void onGrabbedStateChange(View v, int grabbedState) {// Don't poke the wake lock when returning to a state where the handle is// not grabbed since that can happen when the system (instead of the user)// cancels the grab.if (grabbedState == WaveView.OnTriggerListener.CENTER_HANDLE) {mCallback.pokeWakelock(STAY_ON_WHILE_GRABBED_TIMEOUT);}}public void updateResources() {}public View getView() {return mWaveView;}public void reset(boolean animate) {mWaveView.reset();}public void ping() {}}class MultiWaveViewMethods implements MultiWaveView.OnTriggerListener,UnlockWidgetCommonMethods {private final MultiWaveView mMultiWaveView;private boolean mCameraDisabled;MultiWaveViewMethods(MultiWaveView multiWaveView) {mMultiWaveView = multiWaveView;final boolean cameraDisabled = mLockPatternUtils.getDevicePolicyManager().getCameraDisabled(null);if (cameraDisabled) {Log.v(TAG, "Camera disabled by Device Policy");mCameraDisabled = true;} else {// Camera is enabled if resource is initially defined for MultiWaveView// in the lockscreen layout filemCameraDisabled = mMultiWaveView.getTargetResourceId()!= R.array.lockscreen_targets_with_camera;}}

这个类的主要作用就是提供了三种不同时期的滑动解锁方案重载,具体用哪种已经在keyguard_screen_tab_unlock.xml中配置好了。

5. KeyguardViewBase.java

说明:一个抽象类,里面封装了一些抽象方法,并完成对各种按键的监听。条件允许的话他还会拦截keyEvent,从中作梗。

[java] view plain copy print ?
  1. public abstract class KeyguardViewBase extends FrameLayout {
  2. public boolean dispatchKeyEvent(KeyEvent event) {
  3. if (shouldEventKeepScreenOnWhileKeyguardShowing(event)) {
  4. mCallback.pokeWakelock();
  5. }
  6. if (interceptMediaKey(event)) {
  7. return true;
  8. }
  9. return super.dispatchKeyEvent(event);
  10. }
  11. private boolean shouldEventKeepScreenOnWhileKeyguardShowing(KeyEvent event) {
  12. if (event.getAction() != KeyEvent.ACTION_DOWN) {
  13. return false;
  14. }
  15. switch (event.getKeyCode()) {
  16. case KeyEvent.KEYCODE_DPAD_DOWN:
  17. case KeyEvent.KEYCODE_DPAD_LEFT:
  18. case KeyEvent.KEYCODE_DPAD_RIGHT:
  19. case KeyEvent.KEYCODE_DPAD_UP:
  20. return false;
  21. default:
  22. return true;
  23. }
  24. }
  25. private boolean interceptMediaKey(KeyEvent event) {
  26. final int keyCode = event.getKeyCode();
  27. if (event.getAction() == KeyEvent.ACTION_DOWN) {
  28. switch (keyCode) {
  29. case KeyEvent.KEYCODE_MEDIA_PLAY:
  30. case KeyEvent.KEYCODE_MEDIA_PAUSE:
  31. case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
  32. ......
  33. }
public abstract class KeyguardViewBase extends FrameLayout {public boolean dispatchKeyEvent(KeyEvent event) {if (shouldEventKeepScreenOnWhileKeyguardShowing(event)) {mCallback.pokeWakelock();}if (interceptMediaKey(event)) {return true;}return super.dispatchKeyEvent(event);}private boolean shouldEventKeepScreenOnWhileKeyguardShowing(KeyEvent event) {if (event.getAction() != KeyEvent.ACTION_DOWN) {return false;}switch (event.getKeyCode()) {case KeyEvent.KEYCODE_DPAD_DOWN:case KeyEvent.KEYCODE_DPAD_LEFT:case KeyEvent.KEYCODE_DPAD_RIGHT:case KeyEvent.KEYCODE_DPAD_UP:return false;default:return true;}}private boolean interceptMediaKey(KeyEvent event) {final int keyCode = event.getKeyCode();if (event.getAction() == KeyEvent.ACTION_DOWN) {switch (keyCode) {case KeyEvent.KEYCODE_MEDIA_PLAY:case KeyEvent.KEYCODE_MEDIA_PAUSE:case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:......}

6.LockPatternKeyguardView.java

说明:1-6的最终boss,上面的零碎都直接或间接为它工作,他的作用呢,可以参考上面的锁屏view层次图。一句话它是锁屏的最高权威,该整那样,它说了算,鉴于它太过NB,这里就不贴代码了,读者必须亲自膜拜三遍。

7. KeyguardViewManager.java

说明:封装了WindowManager,可以随性改变锁屏视图的创建,显示,隐藏及重新设定。

[java] view plain copy print ?
  1. /**
  2. * Manages creating, showing, hiding and resetting the keyguard.  Calls back
  3. * via {@link com.android.internal.policy.impl.KeyguardViewCallback} to poke
  4. * the wake lock and report that the keyguard is done, which is in turn,
  5. * reported to this class by the current {@link KeyguardViewBase}.
  6. */
  7. public class KeyguardViewManager implements KeyguardWindowController {
  8. private final KeyguardViewProperties mKeyguardViewProperties;
  9. private final KeyguardUpdateMonitor mUpdateMonitor;
  10. private WindowManager.LayoutParams mWindowLayoutParams;
  11. private boolean mNeedsInput = false;
  12. private FrameLayout mKeyguardHost;
  13. private KeyguardViewBase mKeyguardView;
  14. .....
  15. protected void dispatchDraw(Canvas canvas) {
  16. super.dispatchDraw(canvas);
  17. mCallback.keyguardDoneDrawing();
  18. }
  19. }
  20. /**
  21. * Show the keyguard.  Will handle creating and attaching to the view manager
  22. * lazily.
  23. */
  24. public synchronized void show() {
  25. .....
  26. if (mScreenOn) {
  27. mKeyguardView.show();
  28. }
  29. }
  30. // Disable aspects of the system/status/navigation bars that are not appropriate or
  31. // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.
  32. // Other disabled bits are handled by the KeyguardViewMediator talking directly to the
  33. // status bar service.
  34. int visFlags =
  35. ( View.STATUS_BAR_DISABLE_BACK
  36. | View.STATUS_BAR_DISABLE_HOME
  37. );
  38. mKeyguardHost.setSystemUiVisibility(visFlags);
  39. mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
  40. mKeyguardHost.setVisibility(View.VISIBLE);
  41. mKeyguardView.requestFocus();
  42. }
  43. public void setNeedsInput(boolean needsInput) {
  44. ...
  45. }
  46. /**
  47. * Reset the state of the view.
  48. */
  49. public synchronized void reset() {
  50. }
  51. public synchronized void onScreenTurnedOff() {
  52. }
  53. public synchronized void onScreenTurnedOn(
  54. final KeyguardViewManager.ShowListener showListener) {
  55. // Caller should wait for this window to be shown before turning
  56. // on the screen.
  57. }
  58. public synchronized void verifyUnlock() {
  59. if (DEBUG) Log.d(TAG, "verifyUnlock()");
  60. show();
  61. mKeyguardView.verifyUnlock();
  62. }
  63. /**
  64. * A key has woken the device.
  65. */
  66. public boolean wakeWhenReadyTq(int keyCode) {
  67. .....
  68. }
  69. /**
  70. * Hides the keyguard view
  71. */
  72. public synchronized void hide() {
  73. .....
  74. }
  75. /**
  76. * @return Whether the keyguard is showing
  77. */
  78. public synchronized boolean isShowing() {
  79. return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
  80. }
/*** Manages creating, showing, hiding and resetting the keyguard.  Calls back* via {@link com.android.internal.policy.impl.KeyguardViewCallback} to poke* the wake lock and report that the keyguard is done, which is in turn,* reported to this class by the current {@link KeyguardViewBase}.*/
public class KeyguardViewManager implements KeyguardWindowController {private final KeyguardViewProperties mKeyguardViewProperties;private final KeyguardUpdateMonitor mUpdateMonitor;private WindowManager.LayoutParams mWindowLayoutParams;private boolean mNeedsInput = false;private FrameLayout mKeyguardHost;private KeyguardViewBase mKeyguardView;.....protected void dispatchDraw(Canvas canvas) {super.dispatchDraw(canvas);mCallback.keyguardDoneDrawing();}}/*** Show the keyguard.  Will handle creating and attaching to the view manager* lazily.*/public synchronized void show() {.....if (mScreenOn) {mKeyguardView.show();}}// Disable aspects of the system/status/navigation bars that are not appropriate or// useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.// Other disabled bits are handled by the KeyguardViewMediator talking directly to the// status bar service.int visFlags =( View.STATUS_BAR_DISABLE_BACK| View.STATUS_BAR_DISABLE_HOME);mKeyguardHost.setSystemUiVisibility(visFlags);mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);mKeyguardHost.setVisibility(View.VISIBLE);mKeyguardView.requestFocus();}public void setNeedsInput(boolean needsInput) {...}/*** Reset the state of the view.*/public synchronized void reset() {}public synchronized void onScreenTurnedOff() {}public synchronized void onScreenTurnedOn(final KeyguardViewManager.ShowListener showListener) {// Caller should wait for this window to be shown before turning// on the screen.}public synchronized void verifyUnlock() {if (DEBUG) Log.d(TAG, "verifyUnlock()");show();mKeyguardView.verifyUnlock();}/*** A key has woken the device.  */public boolean wakeWhenReadyTq(int keyCode) {.....}/*** Hides the keyguard view*/public synchronized void hide() {.....}/*** @return Whether the keyguard is showing*/public synchronized boolean isShowing() {return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);}

8. KeyguardUpdateMonitor.java

说明:监听系统状态值的改变如时间、SIM卡状态、电池电量等,状态值的改变会回调监听了该状态信息的对象实例。如果只是关注功能的话只需要看hadle里面的每个消息调用的方法即可。

[java] view plain copy print ?
  1. /**
  2. * Watches for updates that may be interesting to the keyguard, and provides
  3. * the up to date information as well as a registration for callbacks that care
  4. * to be updated.
  5. *
  6. * Note: under time crunch, this has been extended to include some stuff that
  7. * doesn't really belong here.  see {@link #handleBatteryUpdate} where it shutdowns
  8. * the device, and {@link #getFailedAttempts()}, {@link #reportFailedAttempt()}
  9. * and {@link #clearFailedAttempts()}.  Maybe we should rename this 'KeyguardContext'...
  10. */
  11. public class KeyguardUpdateMonitor {
  12. private Handler mHandler;
  13. private ContentObserver mContentObserver;
  14. private int mRingMode;
  15. private int mPhoneState;
  16. ......
  17. /**
  18. * SIM卡状态改变捕获赋值。
  19. * the intent and provide a {@link SimCard.State} result.
  20. */
  21. private static class SimArgs {
  22. public final IccCard.State simState;
  23. private SimArgs(Intent intent) {
  24. if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
  25. throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
  26. }
  27. String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
  28. if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
  29. final String absentReason = intent
  30. .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
  31. if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
  32. absentReason)) {
  33. this.simState = IccCard.State.PERM_DISABLED;
  34. } else {
  35. this.simState = IccCard.State.ABSENT;
  36. }
  37. } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
  38. this.simState = IccCard.State.READY;
  39. } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
  40. final String lockedReason = intent
  41. .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
  42. if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
  43. this.simState = IccCard.State.PIN_REQUIRED;
  44. } else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
  45. this.simState = IccCard.State.PUK_REQUIRED;
  46. } else {
  47. this.simState = IccCard.State.UNKNOWN;
  48. }
  49. } else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
  50. this.simState = IccCard.State.NETWORK_LOCKED;
  51. } else {
  52. this.simState = IccCard.State.UNKNOWN;
  53. }
  54. }
  55. public String toString() {
  56. return simState.toString();
  57. }
  58. }
  59. public KeyguardUpdateMonitor(Context context) {
  60. mContext = context;
  61. mHandler = new Handler() {
  62. @Override
  63. public void handleMessage(Message msg) {
  64. switch (msg.what) {
  65. case MSG_TIME_UPDATE:
  66. handleTimeUpdate();
  67. break;
  68. case MSG_BATTERY_UPDATE:
  69. handleBatteryUpdate(msg.arg1,  msg.arg2);
  70. break;
  71. case MSG_CARRIER_INFO_UPDATE:
  72. handleCarrierInfoUpdate();
  73. break;
  74. case MSG_SIM_STATE_CHANGE:
  75. handleSimStateChange((SimArgs) msg.obj);
  76. break;
  77. case MSG_RINGER_MODE_CHANGED:
  78. handleRingerModeChange(msg.arg1);
  79. break;
  80. case MSG_PHONE_STATE_CHANGED:
  81. handlePhoneStateChanged((String)msg.obj);
  82. break;
  83. case MSG_CLOCK_VISIBILITY_CHANGED:
  84. handleClockVisibilityChanged();
  85. break;
  86. case MSG_DEVICE_PROVISIONED:
  87. handleDeviceProvisioned();
  88. break;
  89. }
  90. }
  91. };
/*** Watches for updates that may be interesting to the keyguard, and provides* the up to date information as well as a registration for callbacks that care* to be updated.** Note: under time crunch, this has been extended to include some stuff that* doesn't really belong here.  see {@link #handleBatteryUpdate} where it shutdowns* the device, and {@link #getFailedAttempts()}, {@link #reportFailedAttempt()}* and {@link #clearFailedAttempts()}.  Maybe we should rename this 'KeyguardContext'...*/
public class KeyguardUpdateMonitor {private Handler mHandler;private ContentObserver mContentObserver;private int mRingMode;private int mPhoneState;
....../*** SIM卡状态改变捕获赋值。* the intent and provide a {@link SimCard.State} result.*/private static class SimArgs {public final IccCard.State simState;private SimArgs(Intent intent) {if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");}String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {final String absentReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(absentReason)) {this.simState = IccCard.State.PERM_DISABLED;} else {this.simState = IccCard.State.ABSENT;}} else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {this.simState = IccCard.State.READY;} else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {this.simState = IccCard.State.PIN_REQUIRED;} else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {this.simState = IccCard.State.PUK_REQUIRED;} else {this.simState = IccCard.State.UNKNOWN;}} else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {this.simState = IccCard.State.NETWORK_LOCKED;} else {this.simState = IccCard.State.UNKNOWN;}}public String toString() {return simState.toString();}}public KeyguardUpdateMonitor(Context context) {mContext = context;mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_TIME_UPDATE:handleTimeUpdate();break;case MSG_BATTERY_UPDATE:handleBatteryUpdate(msg.arg1,  msg.arg2);break;case MSG_CARRIER_INFO_UPDATE:handleCarrierInfoUpdate();break;case MSG_SIM_STATE_CHANGE:handleSimStateChange((SimArgs) msg.obj);break;case MSG_RINGER_MODE_CHANGED:handleRingerModeChange(msg.arg1);break;case MSG_PHONE_STATE_CHANGED:handlePhoneStateChanged((String)msg.obj);break;case MSG_CLOCK_VISIBILITY_CHANGED:handleClockVisibilityChanged();break;case MSG_DEVICE_PROVISIONED:handleDeviceProvisioned();break;}}};

9.KeyguardViewMediator.java

说明:也是boss级别的,虽然明面上不及LockPatternKeyguardView.java,但论实权,是个深藏不露的实力派。奈何可能有把柄在他人之手,所以他必须低调,任劳任怨,为PhoneWindowManager.java所各种差遣。看它的话先把开头的50来行英文注释整清楚,然后在跳到handle里面看一下每个消息对应的执行函数,这样对这个所谓调度者就有个大概的理解了。然后就可以具体功能流程具体分析了。

[java] view plain copy print ?
  1. /**
  2. *有关键盘锁请求的调度者。包括键盘锁状态的查询,power management事件影响键盘锁是否应该被显示或者重置,特定的回调函数来
  3. *通知window manager键盘锁是什么时候显示,以及接受view视图传过来的消息表明已经成功完成解锁。
  4. *请注意键盘锁是在灭屏后立即被调用显示的。这样当你点亮屏幕,锁屏才能第一时间显示出来。
  5. *例如外部事件调度锁屏视图流程:
  6. *
  7. *-灭屏动作-》重置锁屏并显示它为下次点亮屏幕做好准备。
  8. *-锁屏很自然流畅的打开了-》如果他不是安全的,隐藏之。
  9. *
  10. *来自于锁屏视图的事件:
  11. *-用户成功完成解锁条件-》隐藏锁屏视图,不再对输入事件进行拦截。
  12. *请再注意:第三方应用通过条用power managment实例可以屏蔽系统的键盘锁。
  13. *
  14. *线程和同步:
  15. *该类是由WindowManagerPolicy创建并运行在它的线程里,锁屏UI也是这个类的构造函数里面产生。这个apis也可以被其他线程所调用。
  16. *然而,这个类的方法手势同步的,同时任何一个锁屏视图都会发消息到handle来保证它是在锁屏UI线程里面执行的。
  17. */
  18. public class KeyguardViewMediator implements KeyguardViewCallback,
  19. KeyguardUpdateMonitor.InfoCallback, KeyguardUpdateMonitor.SimStateCallback {
  20. private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
  21. /**
  22. * This handler will be associated with the policy thread, which will also
  23. * be the UI thread of the keyguard.  Since the apis of the policy, and therefore
  24. * this class, can be called by other threads, any action that directly
  25. * interacts with the keyguard ui should be posted to this handler, rather
  26. * than called directly.
  27. */
  28. private Handler mHandler = new Handler() {
  29. @Override
  30. public void handleMessage(Message msg) {
  31. switch (msg.what) {
  32. case TIMEOUT:
  33. handleTimeout(msg.arg1);
  34. return ;
  35. case SHOW:
  36. handleShow();
  37. return ;
  38. case HIDE:
  39. handleHide();
  40. return ;
  41. case RESET:
  42. handleReset();
  43. return ;
  44. case VERIFY_UNLOCK:
  45. handleVerifyUnlock();
  46. return;
  47. case NOTIFY_SCREEN_OFF:
  48. handleNotifyScreenOff();
  49. return;
  50. case NOTIFY_SCREEN_ON:
  51. handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);
  52. return;
  53. case WAKE_WHEN_READY:
  54. handleWakeWhenReady(msg.arg1);
  55. return;
  56. case KEYGUARD_DONE:
  57. handleKeyguardDone(msg.arg1 != 0);
  58. return;
  59. case KEYGUARD_DONE_DRAWING:
  60. handleKeyguardDoneDrawing();
  61. return;
  62. case KEYGUARD_DONE_AUTHENTICATING:
  63. keyguardDone(true);
  64. return;
  65. case SET_HIDDEN:
  66. handleSetHidden(msg.arg1 != 0);
  67. break;
  68. case KEYGUARD_TIMEOUT:
  69. synchronized (KeyguardViewMediator.this) {
  70. doKeyguardLocked();
  71. }
  72. break;
  73. }
  74. }
  75. };
  76. private void adjustStatusBarLocked() {
  77. ......//控制是否能在锁屏界面下拉状态栏。
  78. }
  79. }
/***有关键盘锁请求的调度者。包括键盘锁状态的查询,power management事件影响键盘锁是否应该被显示或者重置,特定的回调函数来*通知window manager键盘锁是什么时候显示,以及接受view视图传过来的消息表明已经成功完成解锁。*请注意键盘锁是在灭屏后立即被调用显示的。这样当你点亮屏幕,锁屏才能第一时间显示出来。*例如外部事件调度锁屏视图流程: **-灭屏动作-》重置锁屏并显示它为下次点亮屏幕做好准备。*-锁屏很自然流畅的打开了-》如果他不是安全的,隐藏之。**来自于锁屏视图的事件:*-用户成功完成解锁条件-》隐藏锁屏视图,不再对输入事件进行拦截。*请再注意:第三方应用通过条用power managment实例可以屏蔽系统的键盘锁。**线程和同步:*该类是由WindowManagerPolicy创建并运行在它的线程里,锁屏UI也是这个类的构造函数里面产生。这个apis也可以被其他线程所调用。*然而,这个类的方法手势同步的,同时任何一个锁屏视图都会发消息到handle来保证它是在锁屏UI线程里面执行的。*/public class KeyguardViewMediator implements KeyguardViewCallback,KeyguardUpdateMonitor.InfoCallback, KeyguardUpdateMonitor.SimStateCallback {
private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
/*** This handler will be associated with the policy thread, which will also* be the UI thread of the keyguard.  Since the apis of the policy, and therefore* this class, can be called by other threads, any action that directly* interacts with the keyguard ui should be posted to this handler, rather* than called directly.*/private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case TIMEOUT:handleTimeout(msg.arg1);return ;case SHOW:handleShow();return ;case HIDE:handleHide();return ;case RESET:handleReset();return ;case VERIFY_UNLOCK:handleVerifyUnlock();return;case NOTIFY_SCREEN_OFF:handleNotifyScreenOff();return;case NOTIFY_SCREEN_ON:handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);return;case WAKE_WHEN_READY:handleWakeWhenReady(msg.arg1);return;case KEYGUARD_DONE:handleKeyguardDone(msg.arg1 != 0);return;case KEYGUARD_DONE_DRAWING:handleKeyguardDoneDrawing();return;case KEYGUARD_DONE_AUTHENTICATING:keyguardDone(true);return;case SET_HIDDEN:handleSetHidden(msg.arg1 != 0);break;case KEYGUARD_TIMEOUT:synchronized (KeyguardViewMediator.this) {doKeyguardLocked();}break;}}};
private void adjustStatusBarLocked() {......//控制是否能在锁屏界面下拉状态栏。}
}

10.        PhoneWindowManager.java

说明:在Android中的地位犹如封疆之王爷,此等人物,岂能一眼看透并妄加揣测。需时日翻阅各种资料假以研究才能得出个大概.......此乃后话,当另谋篇幅。

5,2.3keyguard锁屏解的几个小问题,贴上仅供娱乐:

后续待补充。

高清文档下载,请ClickMe!

Android 4.4 keyguard 分析:Android4.4 锁屏流程梳理

转载自:http://blog.csdn.net/aaa2832/article/details/7727848

Android4.0 4.1Keyguard锁屏流程梳理相关推荐

  1. Android 9.0 SystemUI 锁屏流程分析

    1.锁屏界面显示的流程 2.按键灭屏 -> 按键亮屏 对于Key事件,InputDispatcher在分发之前会先将事件上发到PhoneWindowManager中,可以进行拦截,故从Phone ...

  2. android锁屏流程_Android开机锁屏流程分析

    Android开机锁屏流程: 首先:手机开机时,在SystemServer类的init2()方法中会启动线程类ServerThread的run方法如下: WindowMan Android开机锁屏流程 ...

  3. java 强制安卓竖屏,Android4.0强制横屏竖屏

    Android4.0强制横屏竖屏 方法一: android4.0/frameworks/base/services/Java/com/android/server/wm/WindowManagerSe ...

  4. AndroidICS4.0----LockScreen锁屏流程【Android源码解析九】

    先来说说LockScreen分类: 一.无锁屏: 二.锁屏: 1.UnLockScreen: 图案锁. PIN锁, 密码锁: 2.LockScreen: 波纹锁: 转载请表明出处:http://blo ...

  5. android锁屏流程_android 解锁,锁屏流程

    解锁.锁屏界面状态改变.锁屏(开机锁屏.时间超时锁屏.按power键锁屏)  一.解锁.以划动解锁(LockScreen.java)为例     1.划动解锁触发其控件监听方法onTrigger,on ...

  6. android7.0 8.1 9.0 10.0 去掉屏幕锁屏(屏幕默认锁屏方式改成无)

    1.概述 在10.0的系统产品开发中,系统在开机后会默认进入锁屏界面,但是产品需求要求去掉锁屏方式,默认无锁屏,就是需要实现去掉屏幕锁屏功能 2.去掉屏幕锁屏(屏幕默认锁屏方式改成无)的核心类 fra ...

  7. android不设密码装证书,安卓4.0不设置锁屏安装根证书教程

    Android 4.0 已经支持用户安装根证书了,只需要将根证书放到sdcard根目录,然后到设置(Settings) – 安全(Security) – 从存储设备安装(Install from st ...

  8. android 11.0 12.0去掉屏幕锁屏(屏幕默认锁屏方式改成无)

    1.概述 在11.0 12.0定制化开发中,需求要求去掉屏幕锁屏功能,默认无锁屏功能,所以要去掉系统默认锁屏功能 分两步: 1.1在SettingProvider数据库加载时默认无锁屏 1.2去掉Se ...

  9. Android 9.0 禁用屏幕锁屏和修改默认输入法为谷歌输入法功能实现

    目录 1.概述 2.禁用屏幕锁屏和修改默认输入法为谷歌输入法功能实现的核心类

最新文章

  1. 2022-2028年中国亲子游行业市场分析及前瞻研究报告
  2. python 实现延迟的操作
  3. 不断的困惑:为什么我仍然使用JavaScript函数语句
  4. 王恩哥院士:信息化发展进程中,科学、基础研究和技术、应用都是关键
  5. 非线性调频 matlab,非线性调频信号
  6. 400万奖金池,倪光南、邓中翰等顶级学者指导,大手笔芯片比赛邀你参与
  7. 从一道面试题说去 2
  8. C++ leetCode 判断一个整数是否为回文数 9. 回文数 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
  9. 一个高效的定时任务系统
  10. Java队列 Queue
  11. which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mod
  12. 工作167:eachrt解决问题方法思路
  13. bzoj 1083 繁忙的都市
  14. 为什么那么多人转型做大数据
  15. 用友U8审核凭证出现列前缀tempdb无效未指定表名的对话框的解决方法
  16. kafka实现组内广播
  17. 很多人搞不清楚的两个类Vector,ArrayList
  18. boost mysql_玩转MySQL 8.0源码编译
  19. android widget 开发实例 : 桌面便签程序的实现具体解释和源代码 (上)
  20. 多时相地图瓦片简单设想

热门文章

  1. 【from Spark!】音视频中的码率控制(CBR、VBR、CVBR、FIXQP)
  2. PHP写动物世界,动物世界引发我对生命的思考
  3. word学习-插入段落制表位
  4. 2023最新CISP模拟考试题库及答案(一)
  5. 上门家教小程序开发的前景
  6. java毕业设计动漫的门户网站Mybatis+系统+数据库+调试部署
  7. 乐播投屏总是自动断开_人人视频投屏连接失败_不能投屏电视解决办法_3DM手游...
  8. 项目:ArrayList集合实现学生(自定义类)信息管理系统
  9. 读effection java
  10. 丈夫每月只回家一次,给妻子3万元生活费,然后转身就走