Android SystemUI组件(07)锁屏KeyguardViewMediator分析

该系列文章总纲链接:专题分纲目录 Android SystemUI组件


本章关键点总结 & 说明:

说明:本章节持续迭代之前章节的思维导图,主要关注左侧上方锁屏分析部分即可。

为了更好理解本文的内容,优先说明下SystemUI中与Keyguard(锁屏)相关的类,主要包括:

  • KeyguardViewMediator:这是一个中介类,它负责管理锁屏的状态,包括锁屏的显示和隐藏,以及与锁屏相关的各种事件处理。它还负责在系统启动时初始化锁屏界面,并在设备准备好时启动锁屏。
  • KeyguardService:这个类是锁屏服务的入口点,它接收来自系统其他部分的请求,如启动锁屏或结束锁屏动画。
  • StatusBarKeyguardViewManager:负责管理状态栏中的锁屏视图,包括显示和隐藏锁屏界面。
  • KeyguardUpdateMonitor:监控系统的各种状态变化,如电池状态、时间变化等,并在这些变化发生时更新锁屏界面。
  • KeyguardBouncer:负责显示解锁界面,包括图案、PIN、密码等解锁方式。它处理用户的解锁尝试,并在成功或失败时提供反馈。
  • KeyguardHostView:是锁屏界面的根视图,它承载了所有的解锁方式视图。
  • KeyguardSecurityContainer:包含解锁方式的容器,如图案、PIN、密码等。
  • KeyguardPatternViewKeyguardPINViewKeyguardPasswordView:这些类分别对应不同的解锁方式,它们实现了用户与锁屏界面的交互。
  • KeyguardManager:系统服务,用于管理系统锁屏的状态,如启用或禁用锁屏。

这些类共同工作,提供了一个完整的锁屏体验,包括显示锁屏界面、处理用户解锁尝试、以及在设备准备好时启动锁屏。这些类构成了锁屏功能的核心。

接下来我们从KeyguardViewMediator.start开始分析,一直到KeyguardViewMediator的关键逻辑:doKeyguardLocked方法的内部实现,想了解为什么要从这里开始分析的,可以查看文章:Android SystemUI组件(01)SystemUIService启动

1 KeyguardViewMediator start启动分析

锁屏KeyguardViewMediator是在systemUI中启动的,从KeyguardViewMediator.start()开始分析。对应代码实现如下:

java 复制代码
public class KeyguardViewMediator extends SystemUI {
    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
    private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;

    private static final boolean DEBUG = KeyguardConstants.DEBUG;
    private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
    private final static boolean DBG_WAKE = false;

    private final static String TAG = "KeyguardViewMediator";
    //...
    @Override
    public void start() {
        synchronized (this) {
            setupLocked();//初始化与锁屏相关的状态和组件
        }
        //将当前实例(this)注册到一个组件管理系统中,以便其他部分的代码可以访问和使用这个实例
        putComponent(KeyguardViewMediator.class, this);
    }
    //...
}

其中关于putComponent方法具体解释如下:

  1. 组件管理putComponent方法通常是一个用于注册组件的工具方法。它将当前的KeyguardViewMediator实例存储在一个全局或共享的组件容器中,使得其他类或模块可以通过这个容器来获取这个实例。

  2. 依赖注入 :这种做法类似于依赖注入(Dependency Injection),允许系统中的其他部分在需要时获取KeyguardViewMediator的实例,而不需要直接创建它。这样可以减少类之间的耦合,提高代码的可维护性。

  3. 方便访问 :通过将KeyguardViewMediator实例放入组件管理系统,其他类可以方便地访问锁屏的相关功能和状态。例如,其他类可能会调用getComponent(KeyguardViewMediator.class)来获取当前的锁屏管理器实例,以便进行锁屏状态的检查或更新。

接下来我们详细分析代码setupLocked的实现,具体如下:

java 复制代码
public class KeyguardViewMediator extends SystemUI {
    //...
    private void setupLocked() {
        // 初始化系统服务和锁屏相关的WakeLock
        mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWM = WindowManagerGlobal.getWindowManagerService();
        mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
        mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
        mShowKeyguardWakeLock.setReferenceCounted(false);

        // 注册一个广播接收器,用于处理延迟锁屏的动作
        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));

        // 初始化锁屏显示管理器和闹钟管理器服务
        mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);

        // 获取锁屏更新监控实例和锁屏图案工具
        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
        mLockPatternUtils = new LockPatternUtils(mContext);
        mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());

        // 根据设备设置和用户状态决定是否显示锁屏,并通知信任管理器锁屏显示状态已改变
        setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled());
        mTrustManager.reportKeyguardShowingChanged();

        // 创建状态栏锁屏视图管理器,用于管理锁屏界面的显示和交互
        mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
                mViewMediatorCallback, mLockPatternUtils);
        
        // 获取内容解析器,用于访问系统设置
        final ContentResolver cr = mContext.getContentResolver();

        // 检查屏幕是否已经开启
        mScreenOn = mPM.isScreenOn();

        // 加载锁屏声音等
        mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
        String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
        if (soundPath != null) {
            mLockSoundId = mLockSounds.load(soundPath, 1);
        }

        if (soundPath == null || mLockSoundId == 0) {
            Log.w(TAG, "failed to load lock sound from " + soundPath);
        }
        soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
        if (soundPath != null) {
            mUnlockSoundId = mLockSounds.load(soundPath, 1);
        }

        if (soundPath == null || mUnlockSoundId == 0) {
            Log.w(TAG, "failed to load unlock sound from " + soundPath);
        }
        soundPath = Settings.Global.getString(cr, Settings.Global.TRUSTED_SOUND);
        if (soundPath != null) {
            mTrustedSoundId = mLockSounds.load(soundPath, 1);
        }

        if (soundPath == null || mTrustedSoundId == 0) {
            Log.w(TAG, "failed to load trusted sound from " + soundPath);
        }
        int lockSoundDefaultAttenuation = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lockSoundVolumeDb);
        mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20);

        // 加载锁屏隐藏动画资源
        mHideAnimation = AnimationUtils.loadAnimation(mContext,
                com.android.internal.R.anim.lock_screen_behind_enter);
    }
    //...
}

setupLocked()方法的主要目的是为KeyguardViewMediator的正常运行做好准备,确保所有必要的组件和状态都已初始化,以便在设备锁屏和解锁时能够正确响应用户的操作和系统事件。具体来说,关键部分主要包括:

  1. 初始化系统服务 :该方法会获取系统服务,如PowerManagerWindowManagerTrustManager,这些服务在锁屏和解锁过程中是必不可少的。

  2. 创建锁屏状态监控 :它会实例化KeyguardUpdateMonitor,用于监控与锁屏相关的各种状态变化,如电池状态、SIM卡状态等。

  3. 设置锁屏和解锁声音setupLocked()还会加载锁屏和解锁时的声音设置,以便在用户进行解锁操作时提供反馈。

  4. 注册广播接收器:该方法会注册一些广播接收器,以便监听特定的系统事件,如延迟锁屏等。

  5. 创建视图管理器 :通过SystemUIFactory创建StatusBarKeyguardViewManager,用于管理锁屏界面的显示和隐藏。

2 开机锁屏流程分析

当设备启动或用户按下电源键时,系统均显示锁屏界面。这个过程涉及KeyguardViewMediator类,它负责协调锁屏的显示和隐藏。接下来分2个部分来解读,一个是从系统的SystemServer启动到KeyguardViewMediator.onSystemReady的过程解读,另一个是SystemServer的SystemReady执行后KeyguardViewMediator具体做了哪些事情。

2.1 从SystemServer启动到KeyguardViewMediator的onSystemReady方法执行

系统SystemServer启动后执行startCoreServices,这里会执行WindowManagerService的systemReady方法,代码实现如下:

java 复制代码
public final class SystemServer {
    private static final String TAG = "SystemServer";
    //...
    private void startCoreServices() {
    	WindowManagerService wm = null;
    	//...
    	try {
            wm.systemReady();
        } catch (Throwable e) {
            reportWtf("making Window Manager Service ready", e);
        }
        //...
    }
    //...
}

这里调用了WindowManagerService的systemReady方法,代码具体实现如下:

java 复制代码
public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    static final String TAG = "WindowManager";
    //这里实际上mPolicy就是PhoneWindowManager对象
    final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
    //...
    public void systemReady() {
        mPolicy.systemReady();
    }
    //...
}

这里实际上就是调用了PhoneWindowManager的systemReady方法,代码具体实现如下:

java 复制代码
public class PhoneWindowManager implements WindowManagerPolicy {
    static final String TAG = "WindowManager";
    static final boolean DEBUG = false;
    //...
    @Override
    public void systemReady() {
        mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
        mKeyguardDelegate.onSystemReady();

        readCameraLensCoverState();
        updateUiMode();
        synchronized (mLock) {
            updateOrientationListenerLp();
            mSystemReady = true;
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    updateSettings();
                }
            });
        }
    }
    //...
}

这里调用了mKeyguardDelegate的onSystemReady方法,代码具体实现如下:

java 复制代码
public class KeyguardServiceDelegate {
    public static final String KEYGUARD_PACKAGE = "com.android.systemui";
    protected KeyguardServiceWrapper mKeyguardService;
    //...
    public void onSystemReady() {
        if (mKeyguardService != null) {
            mKeyguardService.onSystemReady();
        } else {
            mKeyguardState.systemIsReady = true;
        }
    }
    //...
}

这里调用了KeyguardServiceWrapper的onSystemReady方法,代码具体实现如下:

java 复制代码
public class KeyguardServiceWrapper implements IKeyguardService {
    private KeyguardStateMonitor mKeyguardStateMonitor;
    private IKeyguardService mService;
    private String TAG = "KeyguardServiceWrapper";
    //...
    @Override // Binder interface
    public void onSystemReady() {
        try {
            mService.onSystemReady();
        } catch (RemoteException e) {
            Slog.w(TAG , "Remote Exception", e);
        }
    }
    //...
}

这里调用了KeyguardService的onSystemReady方法,代码具体实现如下:

java 复制代码
public class KeyguardService extends Service {
    static final String TAG = "KeyguardService";
    static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
    //...
    private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {

        @Override // Binder interface
        public void addStateMonitorCallback(IKeyguardStateCallback callback) {
            checkPermission();
            mKeyguardViewMediator.addStateMonitorCallback(callback);
        }
        //...
        @Override // Binder interface
        public void onSystemReady() {
            checkPermission();
            mKeyguardViewMediator.onSystemReady();
        }
        //...
    }
}

这里调用了KeyguardViewMediator的onSystemReady方法,代码具体实现如下:

java 复制代码
public class KeyguardViewMediator extends SystemUI {
    // 默认的锁屏显示超时延迟时间(30秒)
    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
    // 锁屏完成挂起的超时时间(3秒)
    private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;
    //...
    public void onSystemReady() {
        mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
        synchronized (this) {
            mSystemReady = true;
            // 注册更新监控的回调
            mUpdateMonitor.registerCallback(mUpdateCallback);
            
            // 检查是否使用弱生物识别(如指纹)且相关硬件已安装
            if (mLockPatternUtils.usingBiometricWeak()
                    && mLockPatternUtils.isBiometricWeakInstalled()) {
                // 如果使用弱生物识别,则禁用备用解锁方式
                mUpdateMonitor.setAlternateUnlockEnabled(false);
            } else {// 否则,启用备用解锁方式
                mUpdateMonitor.setAlternateUnlockEnabled(true);
            }
            // 执行锁屏逻辑
            doKeyguardLocked(null);
        }
        // 可能发送用户已出现的广播
        maybeSendUserPresentBroadcast();
    }
    //...
}

至此,执行到KeyguardViewMediator.onSystemReady的方法中。这里最关键的便是锁屏逻辑对应的doKeyguardLocked方法。接下来继续分析关键逻辑doKeyguardLocked方法。

2.2 KeyguardViewMediator关键逻辑:doKeyguardLocked方法

doKeyguardLocked的代码分析具体如下所示:

java 复制代码
public class KeyguardViewMediator extends SystemUI {
    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
    private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;
    //...
    private void doKeyguardLocked(Bundle options) {
        // 检查是否允许外部控制锁屏的显示
        if (!mExternallyEnabled) {
            return;
        }

        // 如果锁屏已经显示,重置状态并返回
        if (mStatusBarKeyguardViewManager.isShowing()) {
            resetStateLocked();
            return;
        }

        // 检查是否需要SIM卡,如果需要但SIM卡缺失或被禁用,则不显示锁屏
        final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
        final boolean absent = SubscriptionManager.isValidSubscriptionId(
                mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.ABSENT));
        final boolean disabled = SubscriptionManager.isValidSubscriptionId(
                mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
        final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
                || ((absent || disabled) && requireSim);

        // 如果SIM卡锁定或缺失,并且设备还未完成初始设置向导,则不显示锁屏
        if (!lockedOrMissing && shouldWaitForProvisioning()) {
            return;
        }

        // 如果锁屏被禁用,并且SIM卡没有被锁定或缺失,则不显示锁屏
        if (mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
            return;
        }

        // 如果设备设置了Vold密码,并且当前用户需要输入Vold密码,则不显示锁屏
        if (mLockPatternUtils.checkVoldPassword()) {
            setShowingLocked(false);
            hideLocked();
            return;
        }

        // 如果所有条件都满足,则显示锁屏
        showLocked(options);
    }
    //...
    //...handler 发送消息 SHOW/HIDE
    private void showLocked(Bundle options) {
        if (DEBUG) Log.d(TAG, "showLocked");
        // ensure we stay awake until we are finished displaying the keyguard
        mShowKeyguardWakeLock.acquire();
        Message msg = mHandler.obtainMessage(SHOW, options);
        mHandler.sendMessage(msg);
    }

    //...handler处理
    private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SHOW:
                    handleShow((Bundle) msg.obj);
                    break;
                case HIDE:
                    handleHide();
                    break;
                //...
            }
        }
    };
    //handler关键处理方法handleShow
    private void handleShow(Bundle options) {
        synchronized (KeyguardViewMediator.this) {
            // 如果系统还没有准备好,忽略显示锁屏的请求
            if (!mSystemReady) {
                return;
            }

            // 标记锁屏为显示状态
            setShowingLocked(true);
            // 调用状态栏锁屏视图管理器显示锁屏
            mStatusBarKeyguardViewManager.show(options);
            // 标记锁屏不是在隐藏状态
            mHiding = false;
            // 重置锁屏完成挂起的状态
            resetKeyguardDonePendingLocked();
            // 标记没有运行隐藏动画
            mHideAnimationRun = false;
            // 更新活动锁屏状态
            updateActivityLockScreenState();
            // 调整状态栏
            adjustStatusBarLocked();
            // 用户活动事件
            userActivity();

            // 在最后执行,以免延迟锁屏显示
            playSounds(true);

            // 释放锁屏显示时持有的WakeLock
            mShowKeyguardWakeLock.release();
        }
        // 显示锁屏管理器
        mKeyguardDisplayManager.show();
    }

这里调用了mStatusBarKeyguardViewManager的show方法,代码具体实现如下:

java 复制代码
public class StatusBarKeyguardViewManager {
    //step1 显示锁屏
    public void show(Bundle options) {
        mShowing = true; // 标记锁屏为显示状态
        mStatusBarWindowManager.setKeyguardShowing(true); // 通知状态栏窗口管理器锁屏正在显示
        reset(); // 调用reset方法来重置锁屏状态
    }
    //step2 重置锁屏状态
    public void reset() {
        if (mShowing) {
            if (mOccluded) {
                mPhoneStatusBar.hideKeyguard(); // 如果锁屏被遮挡,隐藏锁屏
                mBouncer.hide(false /* destroyView */); // 隐藏解锁界面(Bouncer)
            } else {
                showBouncerOrKeyguard(); // 显示解锁界面或锁屏
            }
            updateStates(); // 更新锁屏状态
        }
    }
    //step3 显示解锁界面或锁屏
    private void showBouncerOrKeyguard() {
        if (mBouncer.needsFullscreenBouncer()) {
            mPhoneStatusBar.hideKeyguard(); // 需要全屏解锁界面时,隐藏锁屏
            mBouncer.show(true); // 显示解锁界面(Bouncer)
        } else {
            mPhoneStatusBar.showKeyguard(); // 不需要全屏解锁界面时,显示锁屏
            mBouncer.hide(false); // 隐藏解锁界面(Bouncer)
            mBouncer.prepare(); // 准备解锁界面(Bouncer)
        }
    }
}

接下来主要解读mBouncer.show和hide的实现及相关流程。主要以show方法(加载视图)为主。接下来继续分析KeyguardBouncer的show方法和hide方法流程,代码具体实现如下:

java 复制代码
public class KeyguardBouncer {
    private Context mContext;
	//...
    private final Runnable mShowRunnable = new Runnable() {
        @Override
        public void run() {
            // 设置锁屏视图的可见性为可见
            mRoot.setVisibility(View.VISIBLE);
            // 恢复锁屏视图的活动状态
            mKeyguardView.onResume();
            // 开始锁屏视图的显示动画
            mKeyguardView.startAppearAnimation();
            // 清除锁屏即将显示的标志
            mShowingSoon = false;
        }
    };
    //...
    //加载及锁屏界面关键流程
	//step1 显示锁屏界面
    public void show() {
		// 确保锁屏视图已经创建,锁屏View的加载
		ensureView();
		// 如果锁屏视图已经是可见的或者即将显示,则不需要再次显示
		if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) {
			// 更新当前的安全方法,这在锁屏已经显示但当前安全方法发生变化时是必要的
			mKeyguardView.show();
			return;
		}

		// 尝试dismiss锁屏。如果没有设置安全模式,这将dismiss整个锁屏。
		// 如果需要认证,则显示解锁界面(Bouncer)。
		if (!mKeyguardView.dismiss()) {
			// 设置标志,表示锁屏即将显示
			mShowingSoon = true;

			// 在多个帧上分散工作
			mChoreographer.postCallbackDelayed(Choreographer.CALLBACK_ANIMATION, mShowRunnable,
					null, 48);
		}
	}
	//step2 确保锁屏视图已经创建
    private void ensureView() {
		//检查mRoot(锁屏界面的根视图)是否已经存在。
        if (mRoot == null) {
			//加载锁屏界面
            inflateView();
        }
    }
	//step3 加载锁屏界面
    private void inflateView() {
		// 如果之前已经添加过锁屏视图,先将其移除
		removeView();

		// 通过LayoutInflater从keyguard_bouncer布局文件中加载锁屏界面布局
		mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);

		// 从加载的布局中获取KeyguardViewBase实例
		mKeyguardView = (KeyguardViewBase) mRoot.findViewById(R.id.keyguard_host_view);

		// 为锁屏视图设置锁图案工具,用于处理锁屏图案相关逻辑
		mKeyguardView.setLockPatternUtils(mLockPatternUtils);

		// 为锁屏视图设置ViewMediatorCallback,用于处理锁屏界面的回调事件
		mKeyguardView.setViewMediatorCallback(mCallback);

		// 将锁屏视图添加到容器视图中,确保它在容器的最后面
		mContainer.addView(mRoot, mContainer.getChildCount());

		// 初始时将锁屏视图的可见性设置为不可见
		mRoot.setVisibility(View.INVISIBLE);

		// 设置系统UI可见性,禁用HOME按钮,这样用户在锁屏界面上不会看到HOME按钮
		mRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
	}
	//...
    //隐藏锁屏界面关键流程
    //step1 隐藏锁屏界面
	public void hide(boolean destroyView) {
		// 取消任何即将执行的显示锁屏的操作
		cancelShowRunnable();
		// 如果锁屏视图不为空,则进行清理
		if (mKeyguardView != null) {
			// 移除锁屏视图上的解散动作,即用户不再能通过这个视图解散锁屏
			mKeyguardView.setOnDismissAction(null);
			// 清理锁屏视图,这可能包括重置状态、停止动画等
			mKeyguardView.cleanUp();
		}
		// 如果传入的参数destroyView为true,则完全移除锁屏视图
		if (destroyView) {
			removeView();
		} else if (mRoot != null) {
			// 如果不销毁视图,只是将其设置为不可见
			mRoot.setVisibility(View.INVISIBLE);
		}
	}
    //step2 锁屏界面不显示,取消线程
	private void cancelShowRunnable() {
		// 从Choreographer中移除之前安排的动画帧更新回调
		mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mShowRunnable, null);
		// 将mShowingSoon标志设置为false,表示锁屏界面不再即将显示
		mShowingSoon = false;
	}
}

最后,总结下整个流程,具体如下:

KeyguardViewMediator类中的doKeyguardLocked方法是用来控制锁屏界面显示的核心逻辑。这个方法会根据设备的当前状态和设置来决定是否显示锁屏。以下是该方法的概要流程:

  1. 检查锁屏状态 :首先,方法会检查锁屏是否已经被外部控制(例如通过setKeyguardEnabled方法)禁用。如果锁屏已被禁用,则不会显示锁屏。

  2. 检查锁屏是否已显示:如果锁屏已经显示在屏幕上,方法会重置锁屏状态并返回,不会重复显示锁屏。

  3. 检查SIM卡状态:方法会检查SIM卡是否缺失或被禁用,如果设备需要SIM卡且SIM卡状态不正常,则不会显示锁屏。

  4. 检查设备设置:如果设备还未完成初始设置向导,且SIM卡被锁定或缺失,则不会显示锁屏。

  5. 检查锁屏设置:如果锁屏被设置为禁用,或者设备设置了Vold密码,方法会隐藏锁屏并返回。

  6. 显示锁屏 :如果所有条件都满足,方法会调用showLocked方法来显示锁屏界面。

StatusBarKeyguardViewManager类中的show方法负责实际显示锁屏界面。它首先将锁屏的显示状态设置为true,然后调用reset方法来重置锁屏状态。reset方法会根据锁屏是否被遮挡来决定是显示解锁界面(Bouncer)还是锁屏界面。

KeyguardBouncer类中的show方法用于显示解锁界面(Bouncer)。如果需要全屏解锁界面,它会隐藏锁屏并显示解锁界面。否则,它会显示锁屏并隐藏解锁界面,并准备解锁界面以供用户输入。

KeyguardBouncer类中的hide方法用于隐藏解锁界面。它会取消任何即将执行的显示操作,并根据传入的参数决定是销毁视图还是仅仅将其设置为不可见。

这些方法共同工作,确保了锁屏界面能够在适当的时机显示或隐藏,同时提供了用户反馈和设备安全性。

相关推荐
老哥不老11 分钟前
MySQL安装教程
android·mysql·adb
xcLeigh2 小时前
html实现好看的多种风格手风琴折叠菜单效果合集(附源码)
android·java·html
InsightAndroid2 小时前
Android通知服务及相关概念
android
aqi004 小时前
FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播
android·ffmpeg·音视频·直播·流媒体
Leoysq4 小时前
Unity实现原始的发射子弹效果
android
起司锅仔5 小时前
ActivityManagerService Activity的启动流程(2)
android·安卓
猿小蔡5 小时前
Android Bitmap 和Drawable的区别
android
峥嵘life5 小时前
Android14 手机蓝牙配对后阻塞问题解决
android·智能手机
猿小蔡5 小时前
Android混淆不要怕--一文搞定
android