Merge "Track process with visible activities"
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 463ba6d..5dbaaaf 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1252,7 +1252,6 @@
void setHasForegroundActivities(boolean hasForegroundActivities) {
mHasForegroundActivities = hasForegroundActivities;
- mWindowProcessController.setHasForegroundActivities(hasForegroundActivities);
}
boolean hasForegroundActivities() {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 4b5518c..33df8b8 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -445,7 +445,6 @@
private Task task; // the task this is in.
private long createTime = System.currentTimeMillis();
long lastVisibleTime; // last time this activity became visible
- long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
long pauseTime; // last time we started pausing the activity
long launchTickTime; // base time for launch tick messages
long topResumedStateLossTime; // last time we reported top resumed state loss to an activity
@@ -5010,16 +5009,6 @@
resumeKeyDispatchingLocked();
final Task stack = getRootTask();
mStackSupervisor.mNoAnimActivities.clear();
-
- // Mark the point when the activity is resuming
- // TODO: To be more accurate, the mark should be before the onCreate,
- // not after the onResume. But for subsequent starts, onResume is fine.
- if (hasProcess()) {
- cpuTimeAtResume = app.getCpuTime();
- } else {
- cpuTimeAtResume = 0; // Couldn't get the cpu time of process
- }
-
returningOptions = null;
if (canTurnScreenOn()) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 73c4713..333455d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -366,6 +366,8 @@
PendingIntentController mPendingIntentController;
IntentFirewall mIntentFirewall;
+ final VisibleActivityProcessTracker mVisibleActivityProcessTracker;
+
/* Global service lock used by the package the owns this service. */
final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock();
/**
@@ -741,6 +743,7 @@
mSystemThread = ActivityThread.currentActivityThread();
mUiContext = mSystemThread.getSystemUiContext();
mLifecycleManager = new ClientLifecycleManager();
+ mVisibleActivityProcessTracker = new VisibleActivityProcessTracker(this);
mInternal = new LocalService();
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
mWindowOrganizerController = new WindowOrganizerController(this);
@@ -6103,16 +6106,7 @@
@Override
public boolean hasResumedActivity(int uid) {
- synchronized (mGlobalLock) {
- final ArraySet<WindowProcessController> processes = mProcessMap.getProcesses(uid);
- for (int i = 0, n = processes.size(); i < n; i++) {
- final WindowProcessController process = processes.valueAt(i);
- if (process.hasResumedActivity()) {
- return true;
- }
- }
- }
- return false;
+ return mVisibleActivityProcessTracker.hasResumedActivity(uid);
}
public void setBackgroundActivityStartCallback(
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 0b2ba87..1255bb2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -162,7 +162,6 @@
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityManager.TaskSnapshot;
-import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.AppGlobals;
@@ -5689,19 +5688,6 @@
if (prev != null) {
prev.resumeKeyDispatchingLocked();
-
- if (prev.hasProcess() && prev.cpuTimeAtResume > 0) {
- final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
- if (diff > 0) {
- final Runnable r = PooledLambda.obtainRunnable(
- ActivityManagerInternal::updateForegroundTimeIfOnBattery,
- mAtmService.mAmInternal, prev.info.packageName,
- prev.info.applicationInfo.uid,
- diff);
- mAtmService.mH.post(r);
- }
- }
- prev.cpuTimeAtResume = 0; // reset it
}
mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
diff --git a/services/core/java/com/android/server/wm/VisibleActivityProcessTracker.java b/services/core/java/com/android/server/wm/VisibleActivityProcessTracker.java
new file mode 100644
index 0000000..7f62630
--- /dev/null
+++ b/services/core/java/com/android/server/wm/VisibleActivityProcessTracker.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A quick lookup for all processes with visible activities. It also tracks the CPU usage of
+ * host process with foreground (resumed) activity.
+ */
+class VisibleActivityProcessTracker {
+ @GuardedBy("mProcMap")
+ private final ArrayMap<WindowProcessController, CpuTimeRecord> mProcMap = new ArrayMap<>();
+ final Executor mBgExecutor = BackgroundThread.getExecutor();
+ final ActivityTaskManagerService mAtms;
+
+ VisibleActivityProcessTracker(ActivityTaskManagerService atms) {
+ mAtms = atms;
+ }
+
+ /** Called when any activity is visible in the process that didn't have one. */
+ void onAnyActivityVisible(WindowProcessController wpc) {
+ final CpuTimeRecord r = new CpuTimeRecord(wpc);
+ synchronized (mProcMap) {
+ mProcMap.put(wpc, r);
+ }
+ if (wpc.hasResumedActivity()) {
+ r.mShouldGetCpuTime = true;
+ mBgExecutor.execute(r);
+ }
+ }
+
+ /** Called when all visible activities of the process are no longer visible. */
+ void onAllActivitiesInvisible(WindowProcessController wpc) {
+ final CpuTimeRecord r = removeProcess(wpc);
+ if (r != null && r.mShouldGetCpuTime) {
+ mBgExecutor.execute(r);
+ }
+ }
+
+ /** Called when an activity is resumed on a process which is known to have visible activity. */
+ void onActivityResumedWhileVisible(WindowProcessController wpc) {
+ final CpuTimeRecord r;
+ synchronized (mProcMap) {
+ r = mProcMap.get(wpc);
+ }
+ if (r != null && !r.mShouldGetCpuTime) {
+ r.mShouldGetCpuTime = true;
+ mBgExecutor.execute(r);
+ }
+ }
+
+ boolean hasResumedActivity(int uid) {
+ synchronized (mProcMap) {
+ for (int i = mProcMap.size() - 1; i >= 0; i--) {
+ final WindowProcessController wpc = mProcMap.keyAt(i);
+ if (wpc.mUid == uid && wpc.hasResumedActivity()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ CpuTimeRecord removeProcess(WindowProcessController wpc) {
+ synchronized (mProcMap) {
+ return mProcMap.remove(wpc);
+ }
+ }
+
+ /**
+ * Get CPU time in background thread because it will access proc files or the lock of cpu
+ * tracker is held by a background thread.
+ */
+ private class CpuTimeRecord implements Runnable {
+ private final WindowProcessController mProc;
+ private long mCpuTime;
+ private boolean mHasStartCpuTime;
+ boolean mShouldGetCpuTime;
+
+ CpuTimeRecord(WindowProcessController wpc) {
+ mProc = wpc;
+ }
+
+ @Override
+ public void run() {
+ if (mProc.getPid() == 0) {
+ // The process is dead.
+ return;
+ }
+ if (!mHasStartCpuTime) {
+ mHasStartCpuTime = true;
+ mCpuTime = mProc.getCpuTime();
+ } else {
+ final long diff = mProc.getCpuTime() - mCpuTime;
+ if (diff > 0) {
+ mAtms.mAmInternal.updateForegroundTimeIfOnBattery(
+ mProc.mInfo.packageName, mProc.mInfo.uid, diff);
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 5bfa662..0431d11 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -137,8 +137,6 @@
private volatile String mRequiredAbi;
// Running any services that are foreground?
private volatile boolean mHasForegroundServices;
- // Running any activities that are foreground?
- private volatile boolean mHasForegroundActivities;
// Are there any client services with activities?
private volatile boolean mHasClientActivities;
// Is this process currently showing a non-activity UI that the user is interacting with?
@@ -226,10 +224,12 @@
private final BackgroundActivityStartCallback mBackgroundActivityStartCallback;
// The bits used for mActivityStateFlags.
- private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 0x10000000;
- private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 0x20000000;
- private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 0x40000000;
- private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 0x80000000;
+ private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
+ private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
+ private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18;
+ private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
+ private static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
+ private static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
/**
@@ -281,6 +281,9 @@
// configuration will update when display is ready.
if (thread != null) {
setLastReportedConfiguration(getConfiguration());
+ } else {
+ // The process is inactive.
+ mAtm.mVisibleActivityProcessTracker.removeProcess(this);
}
}
}
@@ -349,12 +352,10 @@
return mHasForegroundServices;
}
- public void setHasForegroundActivities(boolean hasForegroundActivities) {
- mHasForegroundActivities = hasForegroundActivities;
- }
-
boolean hasForegroundActivities() {
- return mHasForegroundActivities;
+ return mAtm.mTopApp == this || (mActivityStateFlags
+ & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED
+ | ACTIVITY_STATE_FLAG_IS_STOPPING)) != 0;
}
public void setHasClientActivities(boolean hasClientActivities) {
@@ -892,16 +893,9 @@
}
boolean hasResumedActivity() {
- for (int i = mActivities.size() - 1; i >= 0; --i) {
- final ActivityRecord activity = mActivities.get(i);
- if (activity.isState(RESUMED)) {
- return true;
- }
- }
- return false;
+ return (mActivityStateFlags & ACTIVITY_STATE_FLAG_HAS_RESUMED) != 0;
}
-
void updateIntentForHeavyWeightActivity(Intent intent) {
if (mActivities.isEmpty()) {
return;
@@ -1041,10 +1035,14 @@
// Since there could be more than one activities in a process record, we don't need to
// compute the OomAdj with each of them, just need to find out the activity with the
// "best" state, the order would be visible, pausing, stopping...
- Task.ActivityState best = DESTROYED;
- boolean finishing = true;
+ Task.ActivityState bestInvisibleState = DESTROYED;
+ boolean allStoppingFinishing = true;
boolean visible = false;
int minTaskLayer = Integer.MAX_VALUE;
+ int stateFlags = 0;
+ final boolean wasResumed = hasResumedActivity();
+ final boolean wasAnyVisible = (mActivityStateFlags
+ & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0;
for (int i = mActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = mActivities.get(i);
if (r.app != this) {
@@ -1057,7 +1055,13 @@
continue;
}
}
+ if (r.isVisible()) {
+ stateFlags |= ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE;
+ }
if (r.mVisibleRequested) {
+ if (r.isState(RESUMED)) {
+ stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED;
+ }
final Task task = r.getTask();
if (task != null && minTaskLayer > 0) {
final int layer = task.mLayerRank;
@@ -1069,29 +1073,39 @@
// continue the loop, in case there are multiple visible activities in
// this process, we'd find out the one with the minimal layer, thus it'll
// get a higher adj score.
- } else if (best != PAUSING && best != PAUSED) {
+ } else if (!visible && bestInvisibleState != PAUSING) {
if (r.isState(PAUSING, PAUSED)) {
- best = PAUSING;
+ bestInvisibleState = PAUSING;
} else if (r.isState(STOPPING)) {
- best = STOPPING;
+ bestInvisibleState = STOPPING;
// Not "finishing" if any of activity isn't finishing.
- finishing &= r.finishing;
+ allStoppingFinishing &= r.finishing;
}
}
}
- int stateFlags = minTaskLayer & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
+ stateFlags |= minTaskLayer & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
if (visible) {
stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE;
- } else if (best == PAUSING) {
+ } else if (bestInvisibleState == PAUSING) {
stateFlags |= ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
- } else if (best == STOPPING) {
+ } else if (bestInvisibleState == STOPPING) {
stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING;
- if (finishing) {
+ if (allStoppingFinishing) {
stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING;
}
}
mActivityStateFlags = stateFlags;
+
+ final boolean anyVisible = (stateFlags
+ & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0;
+ if (!wasAnyVisible && anyVisible) {
+ mAtm.mVisibleActivityProcessTracker.onAnyActivityVisible(this);
+ } else if (wasAnyVisible && !anyVisible) {
+ mAtm.mVisibleActivityProcessTracker.onAllActivitiesInvisible(this);
+ } else if (wasAnyVisible && !wasResumed && hasResumedActivity()) {
+ mAtm.mVisibleActivityProcessTracker.onActivityResumedWhileVisible(this);
+ }
}
/** Called when the process has some oom related changes and it is going to update oom-adj. */
@@ -1643,6 +1657,32 @@
pw.println(prefix + " Configuration=" + getConfiguration());
pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
+
+ final int stateFlags = mActivityStateFlags;
+ if (stateFlags != ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER) {
+ pw.print(prefix + " mActivityStateFlags=");
+ if ((stateFlags & ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE) != 0) {
+ pw.print("W|");
+ }
+ if ((stateFlags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
+ pw.print("V|");
+ if ((stateFlags & ACTIVITY_STATE_FLAG_HAS_RESUMED) != 0) {
+ pw.print("R|");
+ }
+ } else if ((stateFlags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
+ pw.print("P|");
+ } else if ((stateFlags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
+ pw.print("S|");
+ if ((stateFlags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0) {
+ pw.print("F|");
+ }
+ }
+ final int taskLayer = stateFlags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
+ if (taskLayer != ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER) {
+ pw.print("taskLayer=" + taskLayer);
+ }
+ pw.println();
+ }
}
void dumpDebug(ProtoOutputStream proto, long fieldId) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index a7ced1d..c05eb8e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -662,8 +662,8 @@
ai.uid = callingUid;
ai.packageName = "com.android.test.package";
final WindowProcessController callerApp =
- new WindowProcessController(mAtm, ai, null, callingUid, -1, null, listener);
- callerApp.setHasForegroundActivities(hasForegroundActivities);
+ spy(new WindowProcessController(mAtm, ai, null, callingUid, -1, null, listener));
+ doReturn(hasForegroundActivities).when(callerApp).hasForegroundActivities();
doReturn(callerApp).when(mAtm).getProcessController(caller);
// caller is recents
RecentTasks recentTasks = mock(RecentTasks.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 21be6ef..5afcedb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -22,6 +22,9 @@
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -168,11 +171,7 @@
mAtm, applicationInfo, null, 0, -1, null, mMockListener);
wpc.setThread(mock(IApplicationThread.class));
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setCreateTask(true)
- .setUseProcess(wpc)
- .build();
-
+ final ActivityRecord activity = createActivityRecord(wpc);
wpc.addActivityIfNeeded(activity);
// System UI owned processes should not be registered for activity config changes.
assertFalse(wpc.registeredForActivityConfigChanges());
@@ -185,11 +184,7 @@
// Notify WPC that this process has started an IME service.
mWpc.onServiceStarted(serviceInfo);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setCreateTask(true)
- .setUseProcess(mWpc)
- .build();
-
+ final ActivityRecord activity = createActivityRecord(mWpc);
mWpc.addActivityIfNeeded(activity);
// IME processes should not be registered for activity config changes.
assertFalse(mWpc.registeredForActivityConfigChanges());
@@ -202,11 +197,7 @@
// Notify WPC that this process has started an ally service.
mWpc.onServiceStarted(serviceInfo);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setCreateTask(true)
- .setUseProcess(mWpc)
- .build();
-
+ final ActivityRecord activity = createActivityRecord(mWpc);
mWpc.addActivityIfNeeded(activity);
// Ally processes should not be registered for activity config changes.
assertFalse(mWpc.registeredForActivityConfigChanges());
@@ -219,11 +210,7 @@
// Notify WPC that this process has started an voice interaction service.
mWpc.onServiceStarted(serviceInfo);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setCreateTask(true)
- .setUseProcess(mWpc)
- .build();
-
+ final ActivityRecord activity = createActivityRecord(mWpc);
mWpc.addActivityIfNeeded(activity);
// Voice interaction service processes should not be registered for activity config changes.
assertFalse(mWpc.registeredForActivityConfigChanges());
@@ -244,7 +231,7 @@
final int globalSeq = 100;
mRootWindowContainer.getConfiguration().seq = globalSeq;
invertOrientation(mWpc.getConfiguration());
- new ActivityBuilder(mAtm).setCreateTask(true).setUseProcess(mWpc).build();
+ createActivityRecord(mWpc);
assertTrue(mWpc.registeredForActivityConfigChanges());
assertEquals("Config seq of process should not be affected by activity",
@@ -253,10 +240,7 @@
@Test
public void testComputeOomAdjFromActivities() {
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setCreateTask(true)
- .setUseProcess(mWpc)
- .build();
+ final ActivityRecord activity = createActivityRecord(mWpc);
activity.mVisibleRequested = true;
final int[] callbackResult = { 0 };
final int visible = 1;
@@ -308,6 +292,41 @@
assertEquals(other, callbackResult[0]);
}
+ @Test
+ public void testComputeProcessActivityState() {
+ final VisibleActivityProcessTracker tracker = mAtm.mVisibleActivityProcessTracker;
+ spyOn(tracker);
+ final ActivityRecord activity = createActivityRecord(mWpc);
+ activity.mVisibleRequested = true;
+ activity.setState(Task.ActivityState.STARTED, "test");
+
+ verify(tracker).onAnyActivityVisible(mWpc);
+ assertTrue(mWpc.hasVisibleActivities());
+
+ activity.setState(Task.ActivityState.RESUMED, "test");
+
+ verify(tracker).onActivityResumedWhileVisible(mWpc);
+ assertTrue(tracker.hasResumedActivity(mWpc.mUid));
+
+ activity.makeFinishingLocked();
+ activity.setState(Task.ActivityState.PAUSING, "test");
+
+ assertFalse(tracker.hasResumedActivity(mWpc.mUid));
+ assertTrue(mWpc.hasForegroundActivities());
+
+ activity.setVisibility(false);
+ activity.mVisibleRequested = false;
+ activity.setState(Task.ActivityState.STOPPED, "test");
+
+ verify(tracker).onAllActivitiesInvisible(mWpc);
+ assertFalse(mWpc.hasVisibleActivities());
+ assertFalse(mWpc.hasForegroundActivities());
+ }
+
+ private ActivityRecord createActivityRecord(WindowProcessController wpc) {
+ return new ActivityBuilder(mAtm).setCreateTask(true).setUseProcess(wpc).build();
+ }
+
private TestDisplayContent createTestDisplayContentInContainer() {
return new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
}