Android副屏锁屏界面-Android14
Android副屏锁屏界面-Android14
- 1、副屏锁屏界面模式
- 2、副屏锁屏界面
- 2.1 添加KeyguardPresentation
- 2.2 副屏同步主屏锁屏界面
Android 镜像模式和扩展模式区别探讨-Android14
1、副屏锁屏界面模式
属于
扩展模式
,非镜像模式。LogicalDisplay.java#configureDisplayLocked 添加日志显示mHasContent=true
,表明副屏添加了单独的界面。
2、副屏锁屏界面
SystemUI
中KeyguardDisplayManager.java
里isKeyguardShowable
判断锁屏界面是否添加KeyguardPresentation
;默认主屏DEFAULT_DISPLAY
不会添加
frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
private boolean isKeyguardShowable(Display display) {
if (display == null) {
if (DEBUG) Log.i(TAG, "Cannot show Keyguard on null display");
return false;
}
if (display.getDisplayId() == mDisplayTracker.getDefaultDisplayId()) {
if (DEBUG) Log.i(TAG, "Do not show KeyguardPresentation on the default display");
return false;
}
display.getDisplayInfo(mTmpDisplayInfo);
if ((mTmpDisplayInfo.flags & Display.FLAG_PRIVATE) != 0) {
if (DEBUG) Log.i(TAG, "Do not show KeyguardPresentation on a private display");
return false;
}
if ((mTmpDisplayInfo.flags & Display.FLAG_ALWAYS_UNLOCKED) != 0) {
if (DEBUG) {
Log.i(TAG, "Do not show KeyguardPresentation on an unlocked display");
}
return false;
}
if (mKeyguardStateController.isOccluded()
&& mDeviceStateHelper.isConcurrentDisplayActive(display)) {
if (DEBUG) {
// When activities with FLAG_SHOW_WHEN_LOCKED are shown on top of Keyguard, the
// Keyguard state becomes "occluded". In this case, we should not show the
// KeyguardPresentation, since the activity is presenting content onto the
// non-default display.
Log.i(TAG, "Do not show KeyguardPresentation when occluded and concurrent"
+ " display is active");
}
return false;
}
return true;
}
/**
* @param display The display to show the presentation on.
* @return {@code true} if a presentation was added.
* {@code false} if the presentation cannot be added on that display or the presentation
* was already there.
*/
private boolean showPresentation(Display display) {
if (!isKeyguardShowable(display)) return false;
if (DEBUG) Log.i(TAG, "Keyguard enabled on display: " + display);
final int displayId = display.getDisplayId();
Presentation presentation = mPresentations.get(displayId);
if (presentation == null) {
final Presentation newPresentation = createPresentation(display);
newPresentation.setOnDismissListener(dialog -> {
if (newPresentation.equals(mPresentations.get(displayId))) {
mPresentations.remove(displayId);
}
});
presentation = newPresentation;
try {
presentation.show();
} catch (WindowManager.InvalidDisplayException ex) {
Log.w(TAG, "Invalid display:", ex);
presentation = null;
}
if (presentation != null) {
mPresentations.append(displayId, presentation);
return true;
}
}
return false;
}
2.1 添加KeyguardPresentation
KeyguardPresentation
继承Presentation
,根据副屏对应Display
信息createDisplayContext
创建对应的Context
添加对应的副屏上。
frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
KeyguardPresentation createPresentation(Display display) {
return new KeyguardPresentation(mContext, display, mKeyguardStatusViewComponentFactory);
}
frameworks/base/core/java/android/app/Presentation.java
private static Context createPresentationContext(
Context outerContext, Display display, int theme, @WindowType int type) {
if (outerContext == null) {
throw new IllegalArgumentException("outerContext must not be null");
}
if (display == null) {
throw new IllegalArgumentException("display must not be null");
}
Context windowContext = outerContext.createDisplayContext(display)
.createWindowContext(getWindowType(type, display), null /* options */);
if (theme == 0) {
TypedValue outValue = new TypedValue();
windowContext.getTheme().resolveAttribute(
com.android.internal.R.attr.presentationTheme, outValue, true);
theme = outValue.resourceId;
}
return new ContextThemeWrapper(windowContext, theme);
}
2.2 副屏同步主屏锁屏界面
副屏同步主屏锁屏界面就不需要显示
KeyguardPresentation
,需要在KeyguardDisplayManager.java#isKeyguardShowable判断,可以判断display.getDisplayId() > mDisplayTracker.getDefaultDisplayId()
副屏返回false不添加界面;这里需要注意CTS会失败
。