Merge "Clean up previous DA organizer when registering" into sc-dev

This commit is contained in:
Chris Li
2021-07-16 06:53:18 +00:00
committed by Android (Google) Code Review
2 changed files with 62 additions and 40 deletions

View File

@@ -26,6 +26,7 @@ import android.content.pm.ParceledListSlice;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Slog;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.window.DisplayAreaAppearedInfo; import android.window.DisplayAreaAppearedInfo;
import android.window.IDisplayAreaOrganizer; import android.window.IDisplayAreaOrganizer;
@@ -49,7 +50,8 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
final ActivityTaskManagerService mService; final ActivityTaskManagerService mService;
private final WindowManagerGlobalLock mGlobalLock; private final WindowManagerGlobalLock mGlobalLock;
private final HashMap<Integer, IDisplayAreaOrganizer> mOrganizersByFeatureIds = new HashMap(); private final HashMap<Integer, DisplayAreaOrganizerState> mOrganizersByFeatureIds =
new HashMap();
private class DeathRecipient implements IBinder.DeathRecipient { private class DeathRecipient implements IBinder.DeathRecipient {
int mFeature; int mFeature;
@@ -63,12 +65,41 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
@Override @Override
public void binderDied() { public void binderDied() {
synchronized (mGlobalLock) { synchronized (mGlobalLock) {
mOrganizersByFeatureIds.remove(mFeature); mOrganizersByFeatureIds.remove(mFeature).destroy();
removeOrganizer(mOrganizer);
} }
} }
} }
private class DisplayAreaOrganizerState {
private final IDisplayAreaOrganizer mOrganizer;
private final DeathRecipient mDeathRecipient;
DisplayAreaOrganizerState(IDisplayAreaOrganizer organizer, int feature) {
mOrganizer = organizer;
mDeathRecipient = new DeathRecipient(organizer, feature);
try {
organizer.asBinder().linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
// Oh well...
}
}
void destroy() {
IBinder organizerBinder = mOrganizer.asBinder();
mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
if (da.mOrganizer != null && da.mOrganizer.asBinder().equals(organizerBinder)) {
if (da.isTaskDisplayArea() && da.asTaskDisplayArea().mCreatedByOrganizer) {
// Delete the organizer created TDA when unregister.
deleteTaskDisplayArea(da.asTaskDisplayArea());
} else {
da.setOrganizer(null);
}
}
});
organizerBinder.unlinkToDeath(mDeathRecipient, 0);
}
}
DisplayAreaOrganizerController(ActivityTaskManagerService atm) { DisplayAreaOrganizerController(ActivityTaskManagerService atm) {
mService = atm; mService = atm;
mGlobalLock = atm.mGlobalLock; mGlobalLock = atm.mGlobalLock;
@@ -80,7 +111,8 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
@Nullable @Nullable
IDisplayAreaOrganizer getOrganizerByFeature(int featureId) { IDisplayAreaOrganizer getOrganizerByFeature(int featureId) {
return mOrganizersByFeatureIds.get(featureId); final DisplayAreaOrganizerState state = mOrganizersByFeatureIds.get(featureId);
return state != null ? state.mOrganizer : null;
} }
@Override @Override
@@ -94,17 +126,18 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register display organizer=%s uid=%d", ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register display organizer=%s uid=%d",
organizer.asBinder(), uid); organizer.asBinder(), uid);
if (mOrganizersByFeatureIds.get(feature) != null) { if (mOrganizersByFeatureIds.get(feature) != null) {
if (mOrganizersByFeatureIds.get(feature).mOrganizer.asBinder()
.isBinderAlive()) {
throw new IllegalStateException( throw new IllegalStateException(
"Replacing existing organizer currently unsupported"); "Replacing existing organizer currently unsupported");
} }
final DeathRecipient dr = new DeathRecipient(organizer, feature); mOrganizersByFeatureIds.remove(feature).destroy();
try { Slog.d(TAG, "Replacing dead organizer for feature=" + feature);
organizer.asBinder().linkToDeath(dr, 0);
} catch (RemoteException e) {
// Oh well...
} }
final DisplayAreaOrganizerState state = new DisplayAreaOrganizerState(organizer,
feature);
final List<DisplayAreaAppearedInfo> displayAreaInfos = new ArrayList<>(); final List<DisplayAreaAppearedInfo> displayAreaInfos = new ArrayList<>();
mService.mRootWindowContainer.forAllDisplays(dc -> { mService.mRootWindowContainer.forAllDisplays(dc -> {
if (!dc.isTrusted()) { if (!dc.isTrusted()) {
@@ -120,7 +153,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
}); });
}); });
mOrganizersByFeatureIds.put(feature, organizer); mOrganizersByFeatureIds.put(feature, state);
return new ParceledListSlice<>(displayAreaInfos); return new ParceledListSlice<>(displayAreaInfos);
} }
} finally { } finally {
@@ -137,9 +170,11 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
synchronized (mGlobalLock) { synchronized (mGlobalLock) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Unregister display organizer=%s uid=%d", ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Unregister display organizer=%s uid=%d",
organizer.asBinder(), uid); organizer.asBinder(), uid);
mOrganizersByFeatureIds.entrySet().removeIf( mOrganizersByFeatureIds.values().forEach((state) -> {
entry -> entry.getValue().asBinder() == organizer.asBinder()); if (state.mOrganizer.asBinder() == organizer.asBinder()) {
removeOrganizer(organizer); state.destroy();
}
});
} }
} finally { } finally {
Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId);
@@ -190,19 +225,15 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
} }
final int taskDisplayAreaFeatureId = mNextTaskDisplayAreaFeatureId++; final int taskDisplayAreaFeatureId = mNextTaskDisplayAreaFeatureId++;
final DeathRecipient dr = new DeathRecipient(organizer, taskDisplayAreaFeatureId); final DisplayAreaOrganizerState state = new DisplayAreaOrganizerState(organizer,
try { taskDisplayAreaFeatureId);
organizer.asBinder().linkToDeath(dr, 0);
} catch (RemoteException e) {
// Oh well...
}
final TaskDisplayArea tda = parentRoot != null final TaskDisplayArea tda = parentRoot != null
? createTaskDisplayArea(parentRoot, name, taskDisplayAreaFeatureId) ? createTaskDisplayArea(parentRoot, name, taskDisplayAreaFeatureId)
: createTaskDisplayArea(parentTda, name, taskDisplayAreaFeatureId); : createTaskDisplayArea(parentTda, name, taskDisplayAreaFeatureId);
final DisplayAreaAppearedInfo tdaInfo = organizeDisplayArea(organizer, tda, final DisplayAreaAppearedInfo tdaInfo = organizeDisplayArea(organizer, tda,
"DisplayAreaOrganizerController.createTaskDisplayArea"); "DisplayAreaOrganizerController.createTaskDisplayArea");
mOrganizersByFeatureIds.put(taskDisplayAreaFeatureId, organizer); mOrganizersByFeatureIds.put(taskDisplayAreaFeatureId, state);
return tdaInfo; return tdaInfo;
} }
} finally { } finally {
@@ -230,8 +261,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
+ "TaskDisplayArea=" + taskDisplayArea); + "TaskDisplayArea=" + taskDisplayArea);
} }
mOrganizersByFeatureIds.remove(taskDisplayArea.mFeatureId); mOrganizersByFeatureIds.remove(taskDisplayArea.mFeatureId).destroy();
deleteTaskDisplayArea(taskDisplayArea);
} }
} finally { } finally {
Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId);
@@ -251,6 +281,10 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) { void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "DisplayArea vanished name=%s", da.getName()); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "DisplayArea vanished name=%s", da.getName());
if (!organizer.asBinder().isBinderAlive()) {
Slog.d(TAG, "Organizer died before sending onDisplayAreaVanished");
return;
}
try { try {
organizer.onDisplayAreaVanished(da.getDisplayAreaInfo()); organizer.onDisplayAreaVanished(da.getDisplayAreaInfo());
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -267,20 +301,6 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl
} }
} }
private void removeOrganizer(IDisplayAreaOrganizer organizer) {
IBinder organizerBinder = organizer.asBinder();
mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
if (da.mOrganizer != null && da.mOrganizer.asBinder().equals(organizerBinder)) {
if (da.isTaskDisplayArea() && da.asTaskDisplayArea().mCreatedByOrganizer) {
// Delete the organizer created TDA when unregister.
deleteTaskDisplayArea(da.asTaskDisplayArea());
} else {
da.setOrganizer(null);
}
}
});
}
private DisplayAreaAppearedInfo organizeDisplayArea(IDisplayAreaOrganizer organizer, private DisplayAreaAppearedInfo organizeDisplayArea(IDisplayAreaOrganizer organizer,
DisplayArea displayArea, String callsite) { DisplayArea displayArea, String callsite) {
displayArea.setOrganizer(organizer, true /* skipDisplayAreaAppeared */); displayArea.setOrganizer(organizer, true /* skipDisplayAreaAppeared */);

View File

@@ -57,6 +57,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.View; import android.view.View;
@@ -555,6 +556,7 @@ public class DisplayAreaTest extends WindowTestsBase {
final DisplayArea<WindowContainer> displayArea = new DisplayArea<>( final DisplayArea<WindowContainer> displayArea = new DisplayArea<>(
mWm, BELOW_TASKS, "NewArea", FEATURE_VENDOR_FIRST); mWm, BELOW_TASKS, "NewArea", FEATURE_VENDOR_FIRST);
final IDisplayAreaOrganizer mockDisplayAreaOrganizer = mock(IDisplayAreaOrganizer.class); final IDisplayAreaOrganizer mockDisplayAreaOrganizer = mock(IDisplayAreaOrganizer.class);
doReturn(mock(IBinder.class)).when(mockDisplayAreaOrganizer).asBinder();
displayArea.mOrganizer = mockDisplayAreaOrganizer; displayArea.mOrganizer = mockDisplayAreaOrganizer;
spyOn(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController); spyOn(mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController);
mDisplayContent.addChild(displayArea, 0); mDisplayContent.addChild(displayArea, 0);