进入安全模式的条件
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 2254
2254 public boolean detectSafeMode() {
2255 try {
2256 int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
2257 int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
2258 int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
2259 int trackballState = mWindowManager.getTrackballScancodeState(BTN_MOUSE);
2260 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0;
2261 performHapticFeedbackLw(null, mSafeMode
2262 ? HapticFeedbackConstants.SAFE_MODE_ENABLED
2263 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
2264 if (mSafeMode) {
2265 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
2266 + " dpad=" + dpadState + " trackball=" + trackballState + ")");
2267 } else {
2268 Log.i(TAG, "SAFE MODE not enabled");
2269 }
2270 return mSafeMode;
2271 } catch (RemoteException e) {
2272 // Doom! (it's also local)
2273 throw new RuntimeException("window manager dead");
2274 }
2275 }
menu键,全键盘的s键,DPAD_CENTER,轨迹球按键。
SystemServer 会在启动过程中,启动所有服务,然后检测是否是安全模式,如果是则通知 ActivityManagerService进入安全模式,ActivityManagerService又通知PackageManagerService进入安全模式,然后在左下角显示一个“安全模式”的文字。PackageManagerService进入安全模式,仅仅是设置了mSafeMode这个局部变量。 安全模式对PackageManagerService的影响: 在获得Persistent应用的时候如果是安全模式,则只返回SystemApp。 在解析ContentProvider的时候,如果是安全模式,只有制定的provider是系统自带的才能解析。 总的来说,如果PackageManagerService处于安全模式下,只有ApplicationInfo.FLAG_SYSTEM的组件才会返回。 设置了persistent标志的应用会在ActivityManagerService执行systemReady的时候,由AM来启动。 如果进入了安全模式,即使设置类persistent标志的第三方应用也不会启动。
launcher在加载桌面的时候,会通过AMS来获得判断是否是SafeMode。 安全模式对广播的影响,AMS最终会通过PM来获得广播的接收着,AppGlobals.getPackageManager().queryIntentReceivers