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

View File

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