Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +34 −26 Original line number Original line Diff line number Diff line Loading @@ -94,6 +94,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Iterator; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; import java.util.function.IntSupplier; /** /** * Server side implementation for the interface for organizing windows * Server side implementation for the interface for organizing windows Loading Loading @@ -810,26 +811,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); final SafeActivityOptions safeOptions = final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid); SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid); final Integer[] starterResult = {null}; waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents( // startActivityFromRecents should not be called in lock. caller.mPid, caller.mUid, taskId, safeOptions)); mService.mH.post(() -> { try { starterResult[0] = mService.mTaskSupervisor.startActivityFromRecents( caller.mPid, caller.mUid, taskId, safeOptions); } catch (Throwable t) { starterResult[0] = ActivityManager.START_CANCELED; Slog.w(TAG, t); } synchronized (mGlobalLock) { mGlobalLock.notifyAll(); } }); while (starterResult[0] == null) { try { mGlobalLock.wait(); } catch (InterruptedException ignored) { } } break; break; } } case HIERARCHY_OP_TYPE_PENDING_INTENT: { case HIERARCHY_OP_TYPE_PENDING_INTENT: { Loading @@ -838,22 +821,22 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mService.mContext.getContentResolver()) mService.mContext.getContentResolver()) : null; : null; Bundle options = null; ActivityOptions activityOptions = null; if (hop.getPendingIntent().isActivity()) { if (hop.getPendingIntent().isActivity()) { // Set the context display id as preferred for this activity launches, so that // Set the context display id as preferred for this activity launches, so that // it can land on caller's display. Or just brought the task to front at the // it can land on caller's display. Or just brought the task to front at the // display where it was on since it has higher preference. // display where it was on since it has higher preference. ActivityOptions activityOptions = hop.getLaunchOptions() != null activityOptions = hop.getLaunchOptions() != null ? new ActivityOptions(hop.getLaunchOptions()) ? new ActivityOptions(hop.getLaunchOptions()) : ActivityOptions.makeBasic(); : ActivityOptions.makeBasic(); activityOptions.setCallerDisplayId(DEFAULT_DISPLAY); activityOptions.setCallerDisplayId(DEFAULT_DISPLAY); options = activityOptions.toBundle(); } } final Bundle options = activityOptions != null ? activityOptions.toBundle() : null; mService.mAmInternal.sendIntentSender(hop.getPendingIntent().getTarget(), waitAsyncStart(() -> mService.mAmInternal.sendIntentSender( hop.getPendingIntent().getTarget(), hop.getPendingIntent().getWhitelistToken(), 0 /* code */, hop.getPendingIntent().getWhitelistToken(), 0 /* code */, hop.getActivityIntent(), resolvedType, null /* finishReceiver */, hop.getActivityIntent(), resolvedType, null /* finishReceiver */, null /* requiredPermission */, options); null /* requiredPermission */, options)); break; break; } } case HIERARCHY_OP_TYPE_START_SHORTCUT: { case HIERARCHY_OP_TYPE_START_SHORTCUT: { Loading Loading @@ -914,6 +897,31 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return effects; return effects; } } /** * Post and wait for the result of the activity start to prevent potential deadlock against * {@link WindowManagerGlobalLock}. */ private void waitAsyncStart(IntSupplier startActivity) { final Integer[] starterResult = {null}; mService.mH.post(() -> { try { starterResult[0] = startActivity.getAsInt(); } catch (Throwable t) { starterResult[0] = ActivityManager.START_CANCELED; Slog.w(TAG, t); } synchronized (mGlobalLock) { mGlobalLock.notifyAll(); } }); while (starterResult[0] == null) { try { mGlobalLock.wait(); } catch (InterruptedException ignored) { } } } private int sanitizeAndApplyHierarchyOp(WindowContainer container, private int sanitizeAndApplyHierarchyOp(WindowContainer container, WindowContainerTransaction.HierarchyOp hop) { WindowContainerTransaction.HierarchyOp hop) { final Task task = container.asTask(); final Task task = container.asTask(); Loading Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +34 −26 Original line number Original line Diff line number Diff line Loading @@ -94,6 +94,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Iterator; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; import java.util.function.IntSupplier; /** /** * Server side implementation for the interface for organizing windows * Server side implementation for the interface for organizing windows Loading Loading @@ -810,26 +811,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); final SafeActivityOptions safeOptions = final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid); SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid); final Integer[] starterResult = {null}; waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents( // startActivityFromRecents should not be called in lock. caller.mPid, caller.mUid, taskId, safeOptions)); mService.mH.post(() -> { try { starterResult[0] = mService.mTaskSupervisor.startActivityFromRecents( caller.mPid, caller.mUid, taskId, safeOptions); } catch (Throwable t) { starterResult[0] = ActivityManager.START_CANCELED; Slog.w(TAG, t); } synchronized (mGlobalLock) { mGlobalLock.notifyAll(); } }); while (starterResult[0] == null) { try { mGlobalLock.wait(); } catch (InterruptedException ignored) { } } break; break; } } case HIERARCHY_OP_TYPE_PENDING_INTENT: { case HIERARCHY_OP_TYPE_PENDING_INTENT: { Loading @@ -838,22 +821,22 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub mService.mContext.getContentResolver()) mService.mContext.getContentResolver()) : null; : null; Bundle options = null; ActivityOptions activityOptions = null; if (hop.getPendingIntent().isActivity()) { if (hop.getPendingIntent().isActivity()) { // Set the context display id as preferred for this activity launches, so that // Set the context display id as preferred for this activity launches, so that // it can land on caller's display. Or just brought the task to front at the // it can land on caller's display. Or just brought the task to front at the // display where it was on since it has higher preference. // display where it was on since it has higher preference. ActivityOptions activityOptions = hop.getLaunchOptions() != null activityOptions = hop.getLaunchOptions() != null ? new ActivityOptions(hop.getLaunchOptions()) ? new ActivityOptions(hop.getLaunchOptions()) : ActivityOptions.makeBasic(); : ActivityOptions.makeBasic(); activityOptions.setCallerDisplayId(DEFAULT_DISPLAY); activityOptions.setCallerDisplayId(DEFAULT_DISPLAY); options = activityOptions.toBundle(); } } final Bundle options = activityOptions != null ? activityOptions.toBundle() : null; mService.mAmInternal.sendIntentSender(hop.getPendingIntent().getTarget(), waitAsyncStart(() -> mService.mAmInternal.sendIntentSender( hop.getPendingIntent().getTarget(), hop.getPendingIntent().getWhitelistToken(), 0 /* code */, hop.getPendingIntent().getWhitelistToken(), 0 /* code */, hop.getActivityIntent(), resolvedType, null /* finishReceiver */, hop.getActivityIntent(), resolvedType, null /* finishReceiver */, null /* requiredPermission */, options); null /* requiredPermission */, options)); break; break; } } case HIERARCHY_OP_TYPE_START_SHORTCUT: { case HIERARCHY_OP_TYPE_START_SHORTCUT: { Loading Loading @@ -914,6 +897,31 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return effects; return effects; } } /** * Post and wait for the result of the activity start to prevent potential deadlock against * {@link WindowManagerGlobalLock}. */ private void waitAsyncStart(IntSupplier startActivity) { final Integer[] starterResult = {null}; mService.mH.post(() -> { try { starterResult[0] = startActivity.getAsInt(); } catch (Throwable t) { starterResult[0] = ActivityManager.START_CANCELED; Slog.w(TAG, t); } synchronized (mGlobalLock) { mGlobalLock.notifyAll(); } }); while (starterResult[0] == null) { try { mGlobalLock.wait(); } catch (InterruptedException ignored) { } } } private int sanitizeAndApplyHierarchyOp(WindowContainer container, private int sanitizeAndApplyHierarchyOp(WindowContainer container, WindowContainerTransaction.HierarchyOp hop) { WindowContainerTransaction.HierarchyOp hop) { final Task task = container.asTask(); final Task task = container.asTask(); Loading