设置开机默认无keyguard
1. Description
默认情况下keyguard是打开的,在每次灭屏后,再重新点亮屏幕都会进入keyguard。在有的情况下,为了方便操作,希望开机后默认无锁屏。
2. Analysis
方案一:
keyguard在每次点亮时,会收到一个广播,然后再绘制出keyguard。所以可以在绘制的时候去掉该逻辑即屏蔽showLocked(options);
方法。
/**
* Enable the keyguard if the settings are appropriate.
*/
private void doKeyguardLocked(Bundle options) {
if (KeyguardUpdateMonitor.CORE_APPS_ONLY) {
// Don't show keyguard during half-booted cryptkeeper stage.
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because booting to cryptkeeper");
return;
}
// if another app is disabling us, don't show
if (!mExternallyEnabled) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
// note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
// for an occasional ugly flicker in this situation:
// 1) receive a call with the screen on (no keyguard) or make a call
// 2) screen times out
// 3) user hits key to turn screen back on
// instead, we reenable the keyguard when we know the screen is off and the call
// ends (see the broadcast receiver below)
// TODO: clean this up when we have better support at the window manager level
// for apps that wish to be on top of the keyguard
return;
}
// if the keyguard is already showing, don't bother
if (mStatusBarKeyguardViewManager.isShowing()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
resetStateLocked();
return;
}
// In split system user mode, we never unlock system user.
if (!mustNotUnlockCurrentUser()
|| !mUpdateMonitor.isDeviceProvisioned()) {
// if the setup wizard hasn't run yet, don't show
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
final boolean absent = SubscriptionManager.isValidSubscriptionId(
mUpdateMonitor.getNextSubIdForState(ABSENT));
final boolean disabled = SubscriptionManager.isValidSubscriptionId(
mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
|| ((absent || disabled) && requireSim);
if (!lockedOrMissing && shouldWaitForProvisioning()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
+ " and the sim is not locked or missing");
return;
}
boolean forceShow = options != null && options.getBoolean(OPTION_FORCE_SHOW, false);
if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
&& !lockedOrMissing && !forceShow) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
return;
}
if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
setShowingLocked(false, mAodShowing);
hideLocked();
return;
}
}
if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
showLocked(options);
}
但是发现这个做法并不靠谱,在第一次开机时正常,但是重启后会出现黑屏现象,应该是因为只去掉了lock的界面,而keyguard其他逻辑依然存在。
方案二:
其实在settings中,是可以手动关闭keyguard的,那就表示可以通过settings提供的接口来关掉keygard。在文件
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
中
loadSecureSettings
方法加载了各类item默认状态,而keyguard则是由Settings.System.LOCKSCREEN_DISABLED
属性控制。同时android提供了一个系统属性值ro.lockscreen.disable.default
来方便控制keyguard的打开状态
,如果该值为true则默认是关闭的,否则由文件frameworks/base/packages/SettingsProvider/res/values/defaults.xml
中的def_lockscreen_disabled
标签控制,默认情况下该标签为false即keygurad为打开状态。
private void loadSecureSettings(SQLiteDatabase db) {
SQLiteStatement stmt = null;
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+ " VALUES(?,?);");
loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
R.string.def_location_providers_allowed);
// Don't do this. The SystemServer will initialize ADB_ENABLED from a
// persistent system property instead.
//loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
// Allow mock locations default, based on build
loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
"1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
loadSecure35Settings(stmt);
loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
R.bool.def_mount_play_notification_snd);
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
R.bool.def_mount_ums_autostart);
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
R.bool.def_mount_ums_prompt);
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
R.bool.def_mount_ums_notify_enabled);
loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
R.integer.def_long_press_timeout_millis);
loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
R.bool.def_touch_exploration_enabled);
loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
R.bool.def_accessibility_speak_password);
if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) {
loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1");
} else {
loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
R.bool.def_lockscreen_disabled);
}
loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED,
com.android.internal.R.bool.config_dreamsEnabledByDefault);
loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
loadStringSetting(stmt, Settings.Secure.SCREENSAVER_COMPONENTS,
com.android.internal.R.string.config_dreamsDefaultComponent);
loadStringSetting(stmt, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
com.android.internal.R.string.config_dreamsDefaultComponent);
loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
R.bool.def_accessibility_display_magnification_enabled);
loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
R.fraction.def_accessibility_display_magnification_scale, 1);
loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
R.bool.def_user_setup_complete);
loadStringSetting(stmt, Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
R.string.def_immersive_mode_confirmations);
loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
R.bool.def_install_non_market_apps);
loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED,
R.bool.def_wake_gesture_enabled);
loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
R.integer.def_lock_screen_show_notifications);
loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
R.bool.def_lock_screen_allow_private_notifications);
loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
R.integer.def_sleep_timeout);
/*
* IMPORTANT: Do not add any more upgrade steps here as the global,
* secure, and system settings are no longer stored in a database
* but are kept in memory and persisted to XML.
*
后面验证发现在makefile文件中直接将系统属性ro.lockscreen.disable.default
赋值为ture并不生效,具体原因推测是因为直接赋值后,该属性值编译在verdor分区,而在 system分区get该属性值则无法成功的拿到(android 7.0之后新加特性,区分不同否分区属性值??)。
3. solution
修改文件build/tools/buildinfo.sh
,为系统属性ro.lockscreen.disable.default
赋值即可。
echo "# end build properties"
#set ro.lockscreen.disable.defualt as true
echo "ro.lockscreen.disable.default=ture"
4. summary
略