From 3c2905113331c59f85abbdee82d1aa129743348d Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 30 Mar 2020 22:12:52 +0800 Subject: [PATCH] Fix potential NPE when removing TaskOrganizerController Since unregister can be called from other process, the TaskOrganizerState may be removed from different thread. Bug: 139371701 Test: atest TaskOrganizerTests Change-Id: I4ede04e68fdf70f55f65db4193035d9266445ee3 --- .../server/wm/TaskOrganizerController.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 15b483cd0c495..eddb2cec1e217 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -75,7 +75,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { synchronized (mGlobalLock) { final TaskOrganizerState state = mTaskOrganizerStates.remove( mTaskOrganizer.asBinder()); - state.dispose(); + if (state != null) { + state.dispose(); + } } } }; @@ -216,9 +218,20 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { @Override public void unregisterTaskOrganizer(ITaskOrganizer organizer) { - final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder()); - state.unlinkDeath(); - state.dispose(); + enforceStackPermission("unregisterTaskOrganizer()"); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final TaskOrganizerState state = mTaskOrganizerStates.remove(organizer.asBinder()); + if (state == null) { + return; + } + state.unlinkDeath(); + state.dispose(); + } + } finally { + Binder.restoreCallingIdentity(origId); + } } ITaskOrganizer getTaskOrganizer(int windowingMode) {