Loading services/core/java/com/android/server/am/ActivityManagerService.java +4 −62 Original line number Original line Diff line number Diff line Loading @@ -174,7 +174,6 @@ import android.app.ProfilerInfo; import android.app.WaitResult; import android.app.WaitResult; import android.app.backup.BackupManager.OperationType; import android.app.backup.BackupManager.OperationType; import android.app.backup.IBackupManager; import android.app.backup.IBackupManager; import android.app.compat.CompatChanges; import android.app.usage.UsageEvents; import android.app.usage.UsageEvents; import android.app.usage.UsageEvents.Event; import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStatsManager; import android.app.usage.UsageStatsManager; Loading Loading @@ -13721,34 +13720,10 @@ public class ActivityManagerService extends IActivityManager.Stub false, false, userId, "package unstartable"); false, false, userId, "package unstartable"); break; break; case Intent.ACTION_CLOSE_SYSTEM_DIALOGS: case Intent.ACTION_CLOSE_SYSTEM_DIALOGS: if (!canCloseSystemDialogs(callingPid, callingUid, callerApp)) { if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid, // The app can't close system dialogs, throw only if it targets S+ callerPackage)) { if (CompatChanges.isChangeEnabled( ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, callingUid)) { throw new SecurityException( "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + "."); } else if (CompatChanges.isChangeEnabled( ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, callingUid)) { Slog.w(TAG, "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + ", dropping broadcast."); // Returning success seems to be the pattern here // Returning success seems to be the pattern here return ActivityManager.BROADCAST_SUCCESS; return ActivityManager.BROADCAST_SUCCESS; } else { Slog.w(TAG, intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " will require " + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + " in future builds."); } } } break; break; } } Loading Loading @@ -14043,39 +14018,6 @@ public class ActivityManagerService extends IActivityManager.Stub return ActivityManager.BROADCAST_SUCCESS; return ActivityManager.BROADCAST_SUCCESS; } } private boolean canCloseSystemDialogs(int pid, int uid, @Nullable ProcessRecord callerApp) { if (checkPermission(permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, pid, uid) == PERMISSION_GRANTED) { return true; } if (callerApp == null) { synchronized (mPidsSelfLocked) { callerApp = mPidsSelfLocked.get(pid); } } if (callerApp != null) { // Check if the instrumentation of the process has the permission. This covers the usual // test started from the shell (which has the permission) case. This is needed for apps // targeting SDK level < S but we are also allowing for targetSdk S+ as a convenience to // avoid breaking a bunch of existing tests and asking them to adopt shell permissions // to do this. ActiveInstrumentation instrumentation = callerApp.getActiveInstrumentation(); if (instrumentation != null && checkPermission( permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, -1, instrumentation.mSourceUid) == PERMISSION_GRANTED) { return true; } // This is the notification trampoline use-case for example, where apps use Intent.ACSD // to close the shade prior to starting an activity. WindowProcessController wmApp = callerApp.getWindowProcessController(); if (wmApp.canCloseSystemDialogsByToken()) { return true; } } return false; } /** /** * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1 */ */ services/core/java/com/android/server/am/ProcessRecord.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -1431,7 +1431,9 @@ class ProcessRecord implements WindowProcessListener { void setActiveInstrumentation(ActiveInstrumentation instr) { void setActiveInstrumentation(ActiveInstrumentation instr) { mInstr = instr; mInstr = instr; boolean isInstrumenting = instr != null; boolean isInstrumenting = instr != null; mWindowProcessController.setInstrumenting(isInstrumenting, mWindowProcessController.setInstrumenting( isInstrumenting, isInstrumenting ? instr.mSourceUid : -1, isInstrumenting && instr.mHasBackgroundActivityStartsPermission); isInstrumenting && instr.mHasBackgroundActivityStartsPermission); } } Loading services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -284,6 +284,14 @@ public abstract class ActivityTaskManagerInternal { */ */ public abstract void enforceCallerIsRecentsOrHasPermission(String permission, String func); public abstract void enforceCallerIsRecentsOrHasPermission(String permission, String func); /** * Returns true if the app can close system dialogs. Otherwise it either throws a {@link * SecurityException} or returns false with a logcat message depending on whether the app * targets SDK level {@link android.os.Build.VERSION_CODES#S} or not. */ public abstract boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName); /** /** * Called after the voice interaction service has changed. * Called after the voice interaction service has changed. */ */ Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +91 −1 Original line number Original line Diff line number Diff line Loading @@ -147,6 +147,7 @@ import android.app.WindowConfiguration; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyCache; import android.app.assist.AssistContent; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.assist.AssistStructure; import android.app.compat.CompatChanges; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ComponentName; Loading Loading @@ -2900,6 +2901,86 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } } } /** * Returns true if the app can close system dialogs. Otherwise it either throws a {@link * SecurityException} or returns false with a logcat message depending on whether the app * targets SDK level {@link android.os.Build.VERSION_CODES#S} or not. */ private boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) { final WindowProcessController process; synchronized (mGlobalLock) { process = mProcessMap.getProcess(pid); } if (packageName == null && process != null) { // WindowProcessController.mInfo is final, so after the synchronized memory barrier // above, process.mInfo can't change. As for reading mInfo.packageName, // WindowProcessController doesn't own the ApplicationInfo object referenced by mInfo. // ProcessRecord for example also holds a reference to that object, so protecting access // to packageName with the WM lock would not be enough as we'd also need to synchronize // on the AM lock if we are worried about races, but we can't synchronize on AM lock // here. Hence, since this is only used for logging, we don't synchronize here. packageName = process.mInfo.packageName; } String caller = "(pid=" + pid + ", uid=" + uid + ")"; if (packageName != null) { caller = packageName + " " + caller; } if (!canCloseSystemDialogs(pid, uid, process)) { // The app can't close system dialogs, throw only if it targets S+ if (CompatChanges.isChangeEnabled( ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { throw new SecurityException( "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + "."); } else if (CompatChanges.isChangeEnabled( ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, uid)) { Slog.e(TAG, "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + ", dropping broadcast."); return false; } else { Slog.w(TAG, Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " will require " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + " in future builds."); return true; } } return true; } private boolean canCloseSystemDialogs(int pid, int uid, @Nullable WindowProcessController process) { if (checkPermission(Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, pid, uid) == PERMISSION_GRANTED) { return true; } if (process != null) { // Check if the instrumentation of the process has the permission. This covers the // usual test started from the shell (which has the permission) case. This is needed // for apps targeting SDK level < S but we are also allowing for targetSdk S+ as a // convenience to avoid breaking a bunch of existing tests and asking them to adopt // shell permissions to do this. // Note that these getters all read from volatile fields in WindowProcessController, so // no need to lock. int sourceUid = process.getInstrumentationSourceUid(); if (process.isInstrumenting() && sourceUid != -1 && checkPermission( Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, -1, sourceUid) == PERMISSION_GRANTED) { return true; } // This is the notification trampoline use-case for example, where apps use Intent.ACSD // to close the shade prior to starting an activity. if (process.canCloseSystemDialogsByToken()) { return true; } } return false; } static void enforceTaskPermission(String func) { static void enforceTaskPermission(String func) { if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) == PackageManager.PERMISSION_GRANTED) { if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) == PackageManager.PERMISSION_GRANTED) { return; return; Loading Loading @@ -5176,6 +5257,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func); ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func); } } @Override public boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) { return ActivityTaskManagerService.this.checkCanCloseSystemDialogs(pid, uid, packageName); } @Override @Override public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) { public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) { synchronized (mGlobalLock) { synchronized (mGlobalLock) { Loading Loading @@ -5676,9 +5763,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override @Override public void closeSystemDialogs(String reason) { public void closeSystemDialogs(String reason) { enforceNotIsolatedCaller("closeSystemDialogs"); enforceNotIsolatedCaller("closeSystemDialogs"); final int pid = Binder.getCallingPid(); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid(); if (!checkCanCloseSystemDialogs(pid, uid, null)) { return; } final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity(); try { try { synchronized (mGlobalLock) { synchronized (mGlobalLock) { Loading services/core/java/com/android/server/wm/WindowManagerService.java +5 −0 Original line number Original line Diff line number Diff line Loading @@ -3243,6 +3243,11 @@ public class WindowManagerService extends IWindowManager.Stub @Override @Override public void closeSystemDialogs(String reason) { public void closeSystemDialogs(String reason) { int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid, null)) { return; } synchronized (mGlobalLock) { synchronized (mGlobalLock) { mRoot.closeSystemDialogs(reason); mRoot.closeSystemDialogs(reason); } } Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +4 −62 Original line number Original line Diff line number Diff line Loading @@ -174,7 +174,6 @@ import android.app.ProfilerInfo; import android.app.WaitResult; import android.app.WaitResult; import android.app.backup.BackupManager.OperationType; import android.app.backup.BackupManager.OperationType; import android.app.backup.IBackupManager; import android.app.backup.IBackupManager; import android.app.compat.CompatChanges; import android.app.usage.UsageEvents; import android.app.usage.UsageEvents; import android.app.usage.UsageEvents.Event; import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStatsManager; import android.app.usage.UsageStatsManager; Loading Loading @@ -13721,34 +13720,10 @@ public class ActivityManagerService extends IActivityManager.Stub false, false, userId, "package unstartable"); false, false, userId, "package unstartable"); break; break; case Intent.ACTION_CLOSE_SYSTEM_DIALOGS: case Intent.ACTION_CLOSE_SYSTEM_DIALOGS: if (!canCloseSystemDialogs(callingPid, callingUid, callerApp)) { if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid, // The app can't close system dialogs, throw only if it targets S+ callerPackage)) { if (CompatChanges.isChangeEnabled( ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, callingUid)) { throw new SecurityException( "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + "."); } else if (CompatChanges.isChangeEnabled( ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, callingUid)) { Slog.w(TAG, "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + ", dropping broadcast."); // Returning success seems to be the pattern here // Returning success seems to be the pattern here return ActivityManager.BROADCAST_SUCCESS; return ActivityManager.BROADCAST_SUCCESS; } else { Slog.w(TAG, intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " will require " + permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + " in future builds."); } } } break; break; } } Loading Loading @@ -14043,39 +14018,6 @@ public class ActivityManagerService extends IActivityManager.Stub return ActivityManager.BROADCAST_SUCCESS; return ActivityManager.BROADCAST_SUCCESS; } } private boolean canCloseSystemDialogs(int pid, int uid, @Nullable ProcessRecord callerApp) { if (checkPermission(permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, pid, uid) == PERMISSION_GRANTED) { return true; } if (callerApp == null) { synchronized (mPidsSelfLocked) { callerApp = mPidsSelfLocked.get(pid); } } if (callerApp != null) { // Check if the instrumentation of the process has the permission. This covers the usual // test started from the shell (which has the permission) case. This is needed for apps // targeting SDK level < S but we are also allowing for targetSdk S+ as a convenience to // avoid breaking a bunch of existing tests and asking them to adopt shell permissions // to do this. ActiveInstrumentation instrumentation = callerApp.getActiveInstrumentation(); if (instrumentation != null && checkPermission( permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, -1, instrumentation.mSourceUid) == PERMISSION_GRANTED) { return true; } // This is the notification trampoline use-case for example, where apps use Intent.ACSD // to close the shade prior to starting an activity. WindowProcessController wmApp = callerApp.getWindowProcessController(); if (wmApp.canCloseSystemDialogsByToken()) { return true; } } return false; } /** /** * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1 */ */
services/core/java/com/android/server/am/ProcessRecord.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -1431,7 +1431,9 @@ class ProcessRecord implements WindowProcessListener { void setActiveInstrumentation(ActiveInstrumentation instr) { void setActiveInstrumentation(ActiveInstrumentation instr) { mInstr = instr; mInstr = instr; boolean isInstrumenting = instr != null; boolean isInstrumenting = instr != null; mWindowProcessController.setInstrumenting(isInstrumenting, mWindowProcessController.setInstrumenting( isInstrumenting, isInstrumenting ? instr.mSourceUid : -1, isInstrumenting && instr.mHasBackgroundActivityStartsPermission); isInstrumenting && instr.mHasBackgroundActivityStartsPermission); } } Loading
services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -284,6 +284,14 @@ public abstract class ActivityTaskManagerInternal { */ */ public abstract void enforceCallerIsRecentsOrHasPermission(String permission, String func); public abstract void enforceCallerIsRecentsOrHasPermission(String permission, String func); /** * Returns true if the app can close system dialogs. Otherwise it either throws a {@link * SecurityException} or returns false with a logcat message depending on whether the app * targets SDK level {@link android.os.Build.VERSION_CODES#S} or not. */ public abstract boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName); /** /** * Called after the voice interaction service has changed. * Called after the voice interaction service has changed. */ */ Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +91 −1 Original line number Original line Diff line number Diff line Loading @@ -147,6 +147,7 @@ import android.app.WindowConfiguration; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyCache; import android.app.assist.AssistContent; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.assist.AssistStructure; import android.app.compat.CompatChanges; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ComponentName; Loading Loading @@ -2900,6 +2901,86 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } } } /** * Returns true if the app can close system dialogs. Otherwise it either throws a {@link * SecurityException} or returns false with a logcat message depending on whether the app * targets SDK level {@link android.os.Build.VERSION_CODES#S} or not. */ private boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) { final WindowProcessController process; synchronized (mGlobalLock) { process = mProcessMap.getProcess(pid); } if (packageName == null && process != null) { // WindowProcessController.mInfo is final, so after the synchronized memory barrier // above, process.mInfo can't change. As for reading mInfo.packageName, // WindowProcessController doesn't own the ApplicationInfo object referenced by mInfo. // ProcessRecord for example also holds a reference to that object, so protecting access // to packageName with the WM lock would not be enough as we'd also need to synchronize // on the AM lock if we are worried about races, but we can't synchronize on AM lock // here. Hence, since this is only used for logging, we don't synchronize here. packageName = process.mInfo.packageName; } String caller = "(pid=" + pid + ", uid=" + uid + ")"; if (packageName != null) { caller = packageName + " " + caller; } if (!canCloseSystemDialogs(pid, uid, process)) { // The app can't close system dialogs, throw only if it targets S+ if (CompatChanges.isChangeEnabled( ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) { throw new SecurityException( "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + "."); } else if (CompatChanges.isChangeEnabled( ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, uid)) { Slog.e(TAG, "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " requires " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + ", dropping broadcast."); return false; } else { Slog.w(TAG, Intent.ACTION_CLOSE_SYSTEM_DIALOGS + " broadcast from " + caller + " will require " + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + " in future builds."); return true; } } return true; } private boolean canCloseSystemDialogs(int pid, int uid, @Nullable WindowProcessController process) { if (checkPermission(Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, pid, uid) == PERMISSION_GRANTED) { return true; } if (process != null) { // Check if the instrumentation of the process has the permission. This covers the // usual test started from the shell (which has the permission) case. This is needed // for apps targeting SDK level < S but we are also allowing for targetSdk S+ as a // convenience to avoid breaking a bunch of existing tests and asking them to adopt // shell permissions to do this. // Note that these getters all read from volatile fields in WindowProcessController, so // no need to lock. int sourceUid = process.getInstrumentationSourceUid(); if (process.isInstrumenting() && sourceUid != -1 && checkPermission( Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, -1, sourceUid) == PERMISSION_GRANTED) { return true; } // This is the notification trampoline use-case for example, where apps use Intent.ACSD // to close the shade prior to starting an activity. if (process.canCloseSystemDialogsByToken()) { return true; } } return false; } static void enforceTaskPermission(String func) { static void enforceTaskPermission(String func) { if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) == PackageManager.PERMISSION_GRANTED) { if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) == PackageManager.PERMISSION_GRANTED) { return; return; Loading Loading @@ -5176,6 +5257,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func); ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func); } } @Override public boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) { return ActivityTaskManagerService.this.checkCanCloseSystemDialogs(pid, uid, packageName); } @Override @Override public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) { public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) { synchronized (mGlobalLock) { synchronized (mGlobalLock) { Loading Loading @@ -5676,9 +5763,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override @Override public void closeSystemDialogs(String reason) { public void closeSystemDialogs(String reason) { enforceNotIsolatedCaller("closeSystemDialogs"); enforceNotIsolatedCaller("closeSystemDialogs"); final int pid = Binder.getCallingPid(); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid(); if (!checkCanCloseSystemDialogs(pid, uid, null)) { return; } final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity(); try { try { synchronized (mGlobalLock) { synchronized (mGlobalLock) { Loading
services/core/java/com/android/server/wm/WindowManagerService.java +5 −0 Original line number Original line Diff line number Diff line Loading @@ -3243,6 +3243,11 @@ public class WindowManagerService extends IWindowManager.Stub @Override @Override public void closeSystemDialogs(String reason) { public void closeSystemDialogs(String reason) { int callingPid = Binder.getCallingPid(); int callingUid = Binder.getCallingUid(); if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid, null)) { return; } synchronized (mGlobalLock) { synchronized (mGlobalLock) { mRoot.closeSystemDialogs(reason); mRoot.closeSystemDialogs(reason); } } Loading