summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2014-12-03 18:10:36 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-12-03 18:10:38 +0000
commitde9848c641e1b1e0f73e5655c3f8c0c3b34a011c (patch)
tree00d8040429aec9dc3ec1b0a4a01c7e3ae3cbe4bc
parent5ce118d1f4bdaaa1e85626d06d473b2dece949c3 (diff)
parent740c3ac782675d190941b2ab1905e56f246c1b11 (diff)
downloadframeworks_base-de9848c641e1b1e0f73e5655c3f8c0c3b34a011c.zip
frameworks_base-de9848c641e1b1e0f73e5655c3f8c0c3b34a011c.tar.gz
frameworks_base-de9848c641e1b1e0f73e5655c3f8c0c3b34a011c.tar.bz2
Merge "Initial changes to add callback on task stack changes. (Bug 17672056, Bug 18291345)" into lmp-mr1-dev
-rw-r--r--Android.mk1
-rw-r--r--core/java/android/app/ActivityManagerNative.java20
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/app/ITaskStackListener.aidl22
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java2
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java87
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityRecord.java4
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityStack.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java1
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java4
15 files changed, 191 insertions, 64 deletions
diff --git a/Android.mk b/Android.mk
index ce72a85..ab66bec 100644
--- a/Android.mk
+++ b/Android.mk
@@ -69,6 +69,7 @@ LOCAL_SRC_FILES += \
core/java/android/app/IActivityPendingResult.aidl \
core/java/android/app/IAlarmManager.aidl \
core/java/android/app/IAppTask.aidl \
+ core/java/android/app/ITaskStackListener.aidl \
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
core/java/android/app/INotificationManager.aidl \
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 6ec48e5..06a26ec 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -774,6 +774,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ registerTaskStackListener(ITaskStackListener.Stub.asInterface(token));
+ reply.writeNoException();
+ return true;
+ }
+
case GET_TASK_FOR_ACTIVITY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -3266,6 +3274,18 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
+ @Override
+ public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(listener.asBinder());
+ mRemote.transact(REGISTER_TASK_STACK_LISTENER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException
{
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5362303..1ccbd27 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -139,6 +139,7 @@ public interface IActivityManager extends IInterface {
public StackInfo getStackInfo(int stackId) throws RemoteException;
public boolean isInHomeStack(int taskId) throws RemoteException;
public void setFocusedStack(int stackId) throws RemoteException;
+ public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
public ContentProviderHolder getContentProvider(IApplicationThread caller,
String name, int userId, boolean stable) throws RemoteException;
@@ -788,4 +789,5 @@ public interface IActivityManager extends IInterface {
int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241;
+ int REGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+242;
}
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
new file mode 100644
index 0000000..4b0935c
--- /dev/null
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2014, 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 android.app;
+
+/** @hide */
+oneway interface ITaskStackListener {
+ void onTaskStackChanged();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 29f291d..4f0700e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -19,6 +19,7 @@ package com.android.systemui.recents;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.app.ITaskStackListener;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
@@ -56,6 +57,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+
/** A proxy implementation for the recents component */
public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener {
@@ -79,6 +81,28 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
final static String sRecentsPackage = "com.android.systemui";
final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity";
+ /**
+ * An implementation of ITaskStackListener, that allows us to listen for changes to the system
+ * task stacks and update recents accordingly.
+ */
+ class TaskStackListenerImpl extends ITaskStackListener.Stub {
+ @Override
+ public void onTaskStackChanged() {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
+ // Load the next task only if we aren't svelte
+ RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+ RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
+ loader.preloadTasks(plan, true /* isTopTaskHome */);
+ RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+ launchOpts.numVisibleTasks = 1;
+ launchOpts.numVisibleTaskThumbnails = 1;
+ launchOpts.onlyLoadForCache = true;
+ loader.loadTasks(mContext, plan, launchOpts);
+ }
+ }
+ }
+
static RecentsComponent.Callbacks sRecentsComponentCallbacks;
static RecentsTaskLoadPlan sInstanceLoadPlan;
@@ -86,6 +110,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
LayoutInflater mInflater;
SystemServicesProxy mSystemServicesProxy;
Handler mHandler;
+ TaskStackListenerImpl mTaskStackListener;
boolean mBootCompleted;
boolean mStartAnimationTriggered;
boolean mCanReuseTaskStackViews = true;
@@ -116,6 +141,10 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
mSystemServicesProxy = new SystemServicesProxy(context);
mHandler = new Handler();
mTaskStackBounds = new Rect();
+
+ // Register the task stack listener
+ mTaskStackListener = new TaskStackListenerImpl();
+ mSystemServicesProxy.registerTaskStackListener(mTaskStackListener);
}
public void onStart() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 6dc2edb..a37bc54 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -167,10 +167,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
// When the screen turns off, dismiss Recents to Home
dismissRecentsToHome(false);
- // Preload the metadata for all tasks in the background
- RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
- RecentsTaskLoadPlan plan = loader.createLoadPlan(context);
- loader.preloadTasks(plan, true /* isTopTaskHome */);
} else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
// When the search activity changes, update the Search widget
refreshSearchWidget();
@@ -437,22 +433,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
onEnterAnimationTriggered();
}
- // Start listening for widget package changes if there is one bound, post it since we don't
- // want it stalling the startup
- if (mConfig.searchBarAppWidgetId >= 0) {
- final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> callback =
- new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(this);
- mRecentsView.post(new Runnable() {
- @Override
- public void run() {
- RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = callback.get();
- if (cb != null) {
- mAppWidgetHost.startListening(cb);
- }
- }
- });
- }
-
mStatusBar = ((SystemUIApplication) getApplication())
.getComponent(PhoneStatusBar.class);
}
@@ -539,15 +519,29 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
unregisterReceiver(mSystemBroadcastReceiver);
// Stop listening for widget package changes if there was one bound
- if (mAppWidgetHost.isListening()) {
- mAppWidgetHost.stopListening();
- }
+ mAppWidgetHost.stopListening();
}
public void onEnterAnimationTriggered() {
// Try and start the enter animation (or restart it on configuration changed)
ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
- mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t));
+ ViewAnimation.TaskViewEnterContext ctx = new ViewAnimation.TaskViewEnterContext(t);
+ mRecentsView.startEnterRecentsAnimation(ctx);
+ if (mConfig.searchBarAppWidgetId >= 0) {
+ final WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks> cbRef =
+ new WeakReference<RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks>(
+ RecentsActivity.this);
+ ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
+ @Override
+ public void run() {
+ // Start listening for widget package changes if there is one bound
+ RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks cb = cbRef.get();
+ if (cb != null) {
+ mAppWidgetHost.startListening(cb);
+ }
+ }
+ });
+ }
// Animate the SystemUI scrim views
mScrimViews.startEnterRecentsAnimation();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
index a63e167..5bae37a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
@@ -43,23 +43,23 @@ public class RecentsAppWidgetHost extends AppWidgetHost {
public void startListening(RecentsAppWidgetHostCallbacks cb) {
mCb = cb;
- mIsListening = true;
- super.startListening();
+ if (!mIsListening) {
+ mIsListening = true;
+ super.startListening();
+ }
}
@Override
public void stopListening() {
- super.stopListening();
+ if (mIsListening) {
+ super.stopListening();
+ }
// Ensure that we release any references to the callbacks
mCb = null;
mContext = null;
mIsListening = false;
}
- public boolean isListening() {
- return mIsListening;
- }
-
@Override
protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidgetInfo) {
if (mCb == null) return;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 9a4bd08..3fbd5a6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -21,6 +21,7 @@ import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityManager;
+import android.app.ITaskStackListener;
import android.app.SearchManager;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
@@ -536,4 +537,15 @@ public class SystemServicesProxy {
e.printStackTrace();
}
}
+
+ /** Registers a task stack listener with the system. */
+ public void registerTaskStackListener(ITaskStackListener listener) {
+ if (mIam == null) return;
+
+ try {
+ mIam.registerTaskStackListener(listener);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 46a5d8d..746a7df 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -204,6 +204,10 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
/** Requests all task stacks to start their enter-recents animation */
public void startEnterRecentsAnimation(ViewAnimation.TaskViewEnterContext ctx) {
+ // We have to increment/decrement the post animation trigger in case there are no children
+ // to ensure that it runs
+ ctx.postAnimationTrigger.increment();
+
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -212,6 +216,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
stackView.startEnterRecentsAnimation(ctx);
}
}
+ ctx.postAnimationTrigger.decrement();
}
/** Requests all task stacks to start their exit-recents animation */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
index 4586f12..e1d80fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
@@ -27,7 +27,7 @@ public class ViewAnimation {
public static class TaskViewEnterContext {
// A trigger to run some logic when all the animations complete. This works around the fact
// that it is difficult to coordinate ViewPropertyAnimators
- ReferenceCountedTrigger postAnimationTrigger;
+ public ReferenceCountedTrigger postAnimationTrigger;
// An update listener to notify as the enter animation progresses (used for the home transition)
ValueAnimator.AnimatorUpdateListener updateListener;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7e17043..6823119 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -37,6 +37,7 @@ import android.app.ApplicationThreadNative;
import android.app.IActivityContainer;
import android.app.IActivityContainerCallback;
import android.app.IAppTask;
+import android.app.ITaskStackListener;
import android.app.ProfilerInfo;
import android.app.admin.DevicePolicyManager;
import android.app.usage.UsageEvents;
@@ -292,7 +293,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
// Maximum number recent bitmaps to keep in memory.
- static final int MAX_RECENT_BITMAPS = 5;
+ static final int MAX_RECENT_BITMAPS = 3;
// Amount of time after a call to stopAppSwitches() during which we will
// prevent further untrusted switches from happening.
@@ -370,6 +371,9 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
+ // Delay in notifying task stack change listeners (in millis)
+ static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
+
/** All system services */
SystemServiceManager mSystemServiceManager;
@@ -378,6 +382,10 @@ public final class ActivityManagerService extends ActivityManagerNative
/** Run all ActivityStacks through this */
ActivityStackSupervisor mStackSupervisor;
+ /** Task stack change listeners. */
+ private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
+ new RemoteCallbackList<ITaskStackListener>();
+
public IntentFirewall mIntentFirewall;
// Whether we should show our dialogs (ANR, crash, etc) or just perform their
@@ -1219,6 +1227,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int START_USER_SWITCH_MSG = 46;
static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
static final int DISMISS_DIALOG_MSG = 48;
+ static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1738,6 +1747,22 @@ public final class ActivityManagerService extends ActivityManagerNative
d.dismiss();
break;
}
+ case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
+ synchronized (ActivityManagerService.this) {
+ int i = mTaskStackListeners.beginBroadcast();
+ while (i > 0) {
+ i--;
+ try {
+ // Make a one-way callback to the listener
+ mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
+ } catch (RemoteException e){
+ // Handled by the RemoteCallbackList
+ }
+ }
+ mTaskStackListeners.finishBroadcast();
+ }
+ break;
+ }
}
}
};
@@ -2332,6 +2357,16 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ /** Sets the task stack listener that gets callbacks when a task stack changes. */
+ @Override
+ public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
+ synchronized (ActivityManagerService.this) {
+ if (listener != null) {
+ mTaskStackListeners.register(listener);
+ }
+ }
+ }
+
@Override
public void notifyActivityDrawn(IBinder token) {
if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
@@ -3643,12 +3678,12 @@ public final class ActivityManagerService extends ActivityManagerNative
if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
+ " when finishing user" + userId);
mRecentTasks.remove(i);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
}
}
// Remove tasks from persistent storage.
- mTaskPersister.wakeup(null, true);
+ notifyTaskPersisterLocked(null, true);
}
// Sort by taskId
@@ -3660,7 +3695,7 @@ public final class ActivityManagerService extends ActivityManagerNative
};
// Extract the affiliates of the chain containing mRecentTasks[start].
- private int processNextAffiliateChain(int start) {
+ private int processNextAffiliateChainLocked(int start) {
final TaskRecord startTask = mRecentTasks.get(start);
final int affiliateId = startTask.mAffiliatedTaskId;
@@ -3695,7 +3730,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (first.mNextAffiliate != null) {
Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
first.setNextAffiliate(null);
- mTaskPersister.wakeup(first, false);
+ notifyTaskPersisterLocked(first, false);
}
// Everything in the middle is doubly linked from next to prev.
final int tmpSize = mTmpRecents.size();
@@ -3706,13 +3741,13 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
" setting prev=" + prev);
next.setPrevAffiliate(prev);
- mTaskPersister.wakeup(next, false);
+ notifyTaskPersisterLocked(next, false);
}
if (prev.mNextAffiliate != next) {
Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
" setting next=" + next);
prev.setNextAffiliate(next);
- mTaskPersister.wakeup(prev, false);
+ notifyTaskPersisterLocked(prev, false);
}
prev.inRecents = true;
}
@@ -3721,7 +3756,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (last.mPrevAffiliate != null) {
Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
last.setPrevAffiliate(null);
- mTaskPersister.wakeup(last, false);
+ notifyTaskPersisterLocked(last, false);
}
// Insert the group back into mRecentTasks at start.
@@ -3762,7 +3797,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (task.autoRemoveRecents && task.getTopActivity() == null) {
// This situation is broken, and we should just get rid of it now.
mRecentTasks.remove(i);
- task.removedFromRecents(mTaskPersister);
+ task.removedFromRecents();
i--;
N--;
Slog.w(TAG, "Removing auto-remove without activity: " + task);
@@ -3807,7 +3842,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
// Doesn't exist any more! Good-bye.
mRecentTasks.remove(i);
- task.removedFromRecents(mTaskPersister);
+ task.removedFromRecents();
i--;
N--;
Slog.w(TAG, "Removing no longer valid recent: " + task);
@@ -3843,7 +3878,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
// Verify the affiliate chain for each task.
- for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
+ for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
}
mTmpRecents.clear();
@@ -4009,12 +4044,12 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
- trimRecentsForTask(task, true);
+ trimRecentsForTaskLocked(task, true);
N = mRecentTasks.size();
while (N >= ActivityManager.getMaxRecentTasksStatic()) {
final TaskRecord tr = mRecentTasks.remove(N - 1);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
N--;
}
task.inRecents = true;
@@ -4079,7 +4114,7 @@ public final class ActivityManagerService extends ActivityManagerNative
* If needed, remove oldest existing entries in recents that are for the same kind
* of task as the given one.
*/
- int trimRecentsForTask(TaskRecord task, boolean doTrim) {
+ int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
int N = mRecentTasks.size();
final Intent intent = task.intent;
final boolean document = intent != null && intent.isDocument();
@@ -4126,7 +4161,7 @@ public final class ActivityManagerService extends ActivityManagerNative
tr.disposeThumbnail();
mRecentTasks.remove(i);
if (task != tr) {
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
}
i--;
N--;
@@ -7989,10 +8024,6 @@ public final class ActivityManagerService extends ActivityManagerNative
return list;
}
- TaskRecord getMostRecentTask() {
- return mRecentTasks.get(0);
- }
-
/**
* Creates a new RecentTaskInfo from a TaskRecord.
*/
@@ -8221,7 +8252,7 @@ public final class ActivityManagerService extends ActivityManagerNative
TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
intent, description);
- int trimIdx = trimRecentsForTask(task, false);
+ int trimIdx = trimRecentsForTaskLocked(task, false);
if (trimIdx >= 0) {
// If this would have caused a trim, then we'll abort because that
// means it would be added at the end of the list but then just removed.
@@ -8231,7 +8262,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final int N = mRecentTasks.size();
if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
final TaskRecord tr = mRecentTasks.remove(N - 1);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
}
task.inRecents = true;
@@ -8291,7 +8322,7 @@ public final class ActivityManagerService extends ActivityManagerNative
private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
mRecentTasks.remove(tr);
- tr.removedFromRecents(mTaskPersister);
+ tr.removedFromRecents();
ComponentName component = tr.getBaseIntent().getComponent();
if (component == null) {
Slog.w(TAG, "No component for base intent of task: " + tr);
@@ -9979,6 +10010,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ /** Pokes the task persister. */
void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
if (task != null && task.stack != null && task.stack.isHomeStack()) {
// Never persist the home stack.
@@ -9987,6 +10019,13 @@ public final class ActivityManagerService extends ActivityManagerNative
mTaskPersister.wakeup(task, flush);
}
+ /** Notifies all listeners when the task stack has changed. */
+ void notifyTaskStackChangedLocked() {
+ mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
+ Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
+ mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
+ }
+
@Override
public boolean shutdown(int timeout) {
if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
@@ -10010,12 +10049,12 @@ public final class ActivityManagerService extends ActivityManagerNative
mBatteryStatsService.shutdown();
synchronized (this) {
mProcessStats.shutdownLocked();
+ notifyTaskPersisterLocked(null, true);
}
- notifyTaskPersisterLocked(null, true);
return timedout;
}
-
+
public final void activitySlept(IBinder token) {
if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index c12cadb..e37d5f3 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -69,7 +69,7 @@ import java.util.Objects;
final class ActivityRecord {
static final String TAG = ActivityManagerService.TAG;
static final boolean DEBUG_SAVED_STATE = ActivityStackSupervisor.DEBUG_SAVED_STATE;
- final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recent";
+ final public static String RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
private static final String TAG_ACTIVITY = "activity";
private static final String ATTR_ID = "id";
@@ -792,7 +792,7 @@ final class ActivityRecord {
}
}
- void updateThumbnail(Bitmap newThumbnail, CharSequence description) {
+ void updateThumbnailLocked(Bitmap newThumbnail, CharSequence description) {
if (newThumbnail != null) {
if (ActivityManagerService.DEBUG_THUMBNAILS) Slog.i(ActivityManagerService.TAG,
"Setting thumbnail of " + this + " to " + newThumbnail);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ea694ad..ad86aea 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -65,7 +65,6 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Binder;
@@ -838,7 +837,7 @@ final class ActivityStack {
clearLaunchTime(prev);
final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
- prev.updateThumbnail(screenshotActivities(prev), null);
+ prev.updateThumbnailLocked(screenshotActivities(prev), null);
}
stopFullyDrawnTraceIfNeeded();
@@ -950,7 +949,7 @@ final class ActivityStack {
r.icicle = icicle;
r.haveState = true;
r.launchCount = 0;
- r.updateThumbnail(null, description);
+ r.updateThumbnailLocked(null, description);
}
if (!r.stopped) {
if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r + " (stop complete)");
@@ -1060,6 +1059,9 @@ final class ActivityStack {
}
prev.cpuTimeAtResume = 0; // reset it
}
+
+ // Notfiy when the task stack has changed
+ mService.notifyTaskStackChangedLocked();
}
/**
@@ -4105,7 +4107,7 @@ final class ActivityStack {
// Task creator asked to remove this when done, or this task was a voice
// interaction, so it should not remain on the recent tasks list.
mService.mRecentTasks.remove(task);
- task.removedFromRecents(mService.mTaskPersister);
+ task.removedFromRecents();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 38809cb..d9396d8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2871,6 +2871,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
final TaskRecord task = r.task;
task.setLastThumbnail(task.stack.screenshotActivities(r));
mService.addRecentTaskLocked(task);
+ mService.notifyTaskStackChangedLocked();
mWindowManager.setAppVisibility(r.appToken, false);
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ee93233..d726685 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -383,12 +383,12 @@ final class TaskRecord {
setNextAffiliate(null);
}
- void removedFromRecents(TaskPersister persister) {
+ void removedFromRecents() {
disposeThumbnail();
closeRecentsChain();
if (inRecents) {
inRecents = false;
- persister.wakeup(this, false);
+ mService.notifyTaskPersisterLocked(this, false);
}
}