Merge "Cleanup TaskFragment reference on remove" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
707ac92563
@@ -242,7 +242,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
|
||||
/** Client assigned unique token for this TaskFragment if this is created by an organizer. */
|
||||
@Nullable
|
||||
private IBinder mFragmentToken;
|
||||
private final IBinder mFragmentToken;
|
||||
|
||||
/**
|
||||
* Whether to delay the last activity of TaskFragment being immediately removed while finishing.
|
||||
@@ -2392,10 +2392,18 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
void removeImmediately() {
|
||||
mIsRemovalRequested = false;
|
||||
resetAdjacentTaskFragment();
|
||||
cleanUp();
|
||||
super.removeImmediately();
|
||||
sendTaskFragmentVanished();
|
||||
}
|
||||
|
||||
/** Called on remove to cleanup. */
|
||||
private void cleanUp() {
|
||||
if (mIsEmbedded) {
|
||||
mAtmService.mWindowOrganizerController.cleanUpEmbeddedTaskFragment(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Dimmer getDimmer() {
|
||||
// If the window is in an embedded TaskFragment, we want to dim at the TaskFragment.
|
||||
|
||||
@@ -140,7 +140,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
mLastSentTaskFragmentInfos.put(tf, info);
|
||||
tf.mTaskFragmentAppearedSent = true;
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Exception sending onTaskFragmentAppeared callback", e);
|
||||
Slog.d(TAG, "Exception sending onTaskFragmentAppeared callback", e);
|
||||
}
|
||||
onTaskFragmentParentInfoChanged(organizer, tf);
|
||||
}
|
||||
@@ -150,7 +150,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
try {
|
||||
organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo());
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Exception sending onTaskFragmentVanished callback", e);
|
||||
Slog.d(TAG, "Exception sending onTaskFragmentVanished callback", e);
|
||||
}
|
||||
tf.mTaskFragmentAppearedSent = false;
|
||||
mLastSentTaskFragmentInfos.remove(tf);
|
||||
@@ -175,7 +175,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo());
|
||||
mLastSentTaskFragmentInfos.put(tf, info);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Exception sending onTaskFragmentInfoChanged callback", e);
|
||||
Slog.d(TAG, "Exception sending onTaskFragmentInfoChanged callback", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig);
|
||||
mLastSentTaskFragmentParentConfigs.put(tf, new Configuration(parentConfig));
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
|
||||
Slog.d(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
||||
try {
|
||||
organizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Exception sending onTaskFragmentError callback", e);
|
||||
Slog.d(TAG, "Exception sending onTaskFragmentError callback", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1470,6 +1470,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
return mLaunchTaskFragments.get(tfToken);
|
||||
}
|
||||
|
||||
void cleanUpEmbeddedTaskFragment(TaskFragment taskFragment) {
|
||||
mLaunchTaskFragments.remove(taskFragment.getFragmentToken());
|
||||
}
|
||||
|
||||
static class CallerInfo {
|
||||
final int mPid;
|
||||
final int mUid;
|
||||
|
||||
@@ -359,17 +359,11 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
public void testApplyTransaction_enforceHierarchyChange_createTaskFragment()
|
||||
throws RemoteException {
|
||||
mController.registerOrganizer(mIOrganizer);
|
||||
final ActivityRecord activity = createActivityRecord(mDisplayContent);
|
||||
final int uid = Binder.getCallingUid();
|
||||
activity.info.applicationInfo.uid = uid;
|
||||
activity.getTask().effectiveUid = uid;
|
||||
final ActivityRecord ownerActivity = createActivityRecord(mDisplayContent);
|
||||
final IBinder fragmentToken = new Binder();
|
||||
final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder(
|
||||
mOrganizerToken, fragmentToken, activity.token).build();
|
||||
mOrganizer.applyTransaction(mTransaction);
|
||||
|
||||
// Allow organizer to create TaskFragment and start/reparent activity to TaskFragment.
|
||||
mTransaction.createTaskFragment(params);
|
||||
createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken);
|
||||
mTransaction.startActivityInTaskFragment(
|
||||
mFragmentToken, null /* callerToken */, new Intent(), null /* activityOptions */);
|
||||
mTransaction.reparentActivityToTaskFragment(mFragmentToken, mock(IBinder.class));
|
||||
@@ -381,7 +375,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
final TaskFragment taskFragment = mAtm.mWindowOrganizerController
|
||||
.getTaskFragment(fragmentToken);
|
||||
assertNotNull(taskFragment);
|
||||
assertEquals(activity.getTask(), taskFragment.getTask());
|
||||
assertEquals(ownerActivity.getTask(), taskFragment.getTask());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -523,4 +517,43 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
mController.dispatchPendingEvents();
|
||||
verify(mOrganizer).onTaskFragmentInfoChanged(any());
|
||||
}
|
||||
|
||||
/**
|
||||
* When an embedded {@link TaskFragment} is removed, we should clean up the reference in the
|
||||
* {@link WindowOrganizerController}.
|
||||
*/
|
||||
@Test
|
||||
public void testTaskFragmentRemoved_cleanUpEmbeddedTaskFragment()
|
||||
throws RemoteException {
|
||||
mController.registerOrganizer(mIOrganizer);
|
||||
final ActivityRecord ownerActivity = createActivityRecord(mDisplayContent);
|
||||
final IBinder fragmentToken = new Binder();
|
||||
createTaskFragmentFromOrganizer(mTransaction, ownerActivity, fragmentToken);
|
||||
mAtm.getWindowOrganizerController().applyTransaction(mTransaction);
|
||||
final TaskFragment taskFragment = mAtm.mWindowOrganizerController
|
||||
.getTaskFragment(fragmentToken);
|
||||
|
||||
assertNotNull(taskFragment);
|
||||
|
||||
taskFragment.removeImmediately();
|
||||
|
||||
assertNull(mAtm.mWindowOrganizerController.getTaskFragment(fragmentToken));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link TaskFragment} with the {@link WindowContainerTransaction}. Calls
|
||||
* {@link WindowOrganizerController#applyTransaction} to apply the transaction,
|
||||
*/
|
||||
private void createTaskFragmentFromOrganizer(WindowContainerTransaction wct,
|
||||
ActivityRecord ownerActivity, IBinder fragmentToken) {
|
||||
final int uid = Binder.getCallingUid();
|
||||
ownerActivity.info.applicationInfo.uid = uid;
|
||||
ownerActivity.getTask().effectiveUid = uid;
|
||||
final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder(
|
||||
mOrganizerToken, fragmentToken, ownerActivity.token).build();
|
||||
mOrganizer.applyTransaction(wct);
|
||||
|
||||
// Allow organizer to create TaskFragment and start/reparent activity to TaskFragment.
|
||||
wct.createTaskFragment(params);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user