OSDN Git Service

Merge "Refactored NetworkPolicyManagerService mUidRules." into nyc-dev
authorTreeHugger Robot <treehugger-gerrit@google.com>
Fri, 6 May 2016 21:41:38 +0000 (21:41 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Fri, 6 May 2016 21:41:41 +0000 (21:41 +0000)
29 files changed:
cmds/am/src/com/android/commands/am/Am.java
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
core/java/android/app/ActivityManagerNative.java
core/java/android/app/IActivityManager.java
core/java/android/bluetooth/le/ScanFilter.java
core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
core/res/AndroidManifest.xml
packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndCancelledEvent.java [new file with mode: 0644]
packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
packages/SystemUI/src/com/android/systemui/recents/model/Task.java
packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java
packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
packages/SystemUI/src/com/android/systemui/recents/tv/animations/DismissAnimationsHolder.java
packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/RecentTasks.java
services/core/java/com/android/server/job/controllers/IdleController.java

index 0bcee86..8ccd5d2 100644 (file)
@@ -1598,10 +1598,10 @@ public class Am extends BaseCommand {
         }
 
         System.out.println("Performing idle maintenance...");
-        Intent intent = new Intent(
-                "com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE");
-        mAm.broadcastIntent(null, intent, null, null, 0, null, null, null,
-                android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
+        try {
+            mAm.sendIdleJobTrigger();
+        } catch (RemoteException e) {
+        }
     }
 
     private void runScreenCompat() throws Exception {
index d5e8a11..3783fca 100644 (file)
@@ -65,7 +65,7 @@ interface IAccessibilityServiceConnection {
 
     boolean performGlobalAction(int action);
 
-    oneway void disableSelf();
+    void disableSelf();
 
     oneway void setOnKeyEventResult(boolean handled, int sequence);
 
index 1a7c746..6b62837 100644 (file)
@@ -1527,7 +1527,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
 
         case SET_LOCK_SCREEN_SHOWN_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            setLockScreenShown(data.readInt() != 0);
+            final boolean showing = data.readInt() != 0;
+            final boolean occluded = data.readInt() != 0;
+            setLockScreenShown(showing, occluded);
             reply.writeNoException();
             return true;
         }
@@ -2968,6 +2970,12 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
             reply.writeNoException();
             return true;
         }
+        case SEND_IDLE_JOB_TRIGGER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            sendIdleJobTrigger();
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -4922,12 +4930,13 @@ class ActivityManagerProxy implements IActivityManager
         reply.recycle();
         return pfd;
     }
-    public void setLockScreenShown(boolean shown) throws RemoteException
+    public void setLockScreenShown(boolean showing, boolean occluded) throws RemoteException
     {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(shown ? 1 : 0);
+        data.writeInt(showing ? 1 : 0);
+        data.writeInt(occluded ? 1 : 0);
         mRemote.transact(SET_LOCK_SCREEN_SHOWN_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -6244,6 +6253,16 @@ class ActivityManagerProxy implements IActivityManager
         reply.recycle();
     }
 
+    public void sendIdleJobTrigger() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(SEND_IDLE_JOB_TRIGGER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
             IActivityContainerCallback callback) throws RemoteException {
         Parcel data = Parcel.obtain();
index 55ce6c2..849fcec 100644 (file)
@@ -331,7 +331,7 @@ public interface IActivityManager extends IInterface {
     public void forceStopPackage(final String packageName, int userId) throws RemoteException;
 
     // Note: probably don't want to allow applications access to these.
-    public void setLockScreenShown(boolean shown) throws RemoteException;
+    public void setLockScreenShown(boolean showing, boolean occluded) throws RemoteException;
 
     public void unhandledBack() throws RemoteException;
     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException;
@@ -546,6 +546,8 @@ public interface IActivityManager extends IInterface {
 
     public void performIdleMaintenance() throws RemoteException;
 
+    public void sendIdleJobTrigger() throws RemoteException;
+
     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
             IActivityContainerCallback callback) throws RemoteException;
 
@@ -1035,4 +1037,5 @@ public interface IActivityManager extends IInterface {
     int SWAP_DOCKED_AND_FULLSCREEN_STACK = IBinder.FIRST_CALL_TRANSACTION + 372;
     int NOTIFY_LOCKED_PROFILE = IBinder.FIRST_CALL_TRANSACTION + 373;
     int START_CONFIRM_DEVICE_CREDENTIAL_INTENT = IBinder.FIRST_CALL_TRANSACTION + 374;
+    int SEND_IDLE_JOB_TRIGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 375;
 }
index 92a3817..17a802d 100644 (file)
@@ -385,9 +385,13 @@ public final class ScanFilter implements Parcelable {
 
     @Override
     public int hashCode() {
-        return Objects.hash(mDeviceName, mDeviceAddress, mManufacturerId, mManufacturerData,
-                mManufacturerDataMask, mServiceDataUuid, mServiceData, mServiceDataMask,
-                mServiceUuid, mServiceUuidMask);
+        return Objects.hash(mDeviceName, mDeviceAddress, mManufacturerId,
+                            Arrays.hashCode(mManufacturerData),
+                            Arrays.hashCode(mManufacturerDataMask),
+                            mServiceDataUuid,
+                            Arrays.hashCode(mServiceData),
+                            Arrays.hashCode(mServiceDataMask),
+                            mServiceUuid, mServiceUuidMask);
     }
 
     @Override
@@ -401,10 +405,10 @@ public final class ScanFilter implements Parcelable {
         ScanFilter other = (ScanFilter) obj;
         return Objects.equals(mDeviceName, other.mDeviceName) &&
                 Objects.equals(mDeviceAddress, other.mDeviceAddress) &&
-                        mManufacturerId == other.mManufacturerId &&
+                mManufacturerId == other.mManufacturerId &&
                 Objects.deepEquals(mManufacturerData, other.mManufacturerData) &&
                 Objects.deepEquals(mManufacturerDataMask, other.mManufacturerDataMask) &&
-                Objects.deepEquals(mServiceDataUuid, other.mServiceDataUuid) &&
+                Objects.equals(mServiceDataUuid, other.mServiceDataUuid) &&
                 Objects.deepEquals(mServiceData, other.mServiceData) &&
                 Objects.deepEquals(mServiceDataMask, other.mServiceDataMask) &&
                 Objects.equals(mServiceUuid, other.mServiceUuid) &&
index 458c584..f82c9e2 100644 (file)
@@ -35,6 +35,7 @@ import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -105,7 +106,7 @@ public class KeyphraseEnrollmentInfo {
         if (ris == null || ris.isEmpty()) {
             // No application capable of enrolling for voice keyphrases is present.
             mParseError = "No enrollment applications found";
-            mKeyphrasePackageMap = null;
+            mKeyphrasePackageMap = Collections.<KeyphraseMetadata, String>emptyMap();
             mKeyphrases = null;
             return;
         }
@@ -328,17 +329,15 @@ public class KeyphraseEnrollmentInfo {
      *         and locale, null otherwise.
      */
     public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, Locale locale) {
-        if (mKeyphrases == null || mKeyphrases.length == 0) {
-            Slog.w(TAG, "Enrollment application doesn't support keyphrases");
-            return null;
-        }
-        for (KeyphraseMetadata keyphraseMetadata : mKeyphrases) {
-            // Check if the given keyphrase is supported in the locale provided by
-            // the enrollment application.
-            if (keyphraseMetadata.supportsPhrase(keyphrase)
-                    && keyphraseMetadata.supportsLocale(locale)) {
-                return keyphraseMetadata;
-            }
+        if (mKeyphrases != null && mKeyphrases.length > 0) {
+          for (KeyphraseMetadata keyphraseMetadata : mKeyphrases) {
+              // Check if the given keyphrase is supported in the locale provided by
+              // the enrollment application.
+              if (keyphraseMetadata.supportsPhrase(keyphrase)
+                      && keyphraseMetadata.supportsLocale(locale)) {
+                  return keyphraseMetadata;
+              }
+          }
         }
         Slog.w(TAG, "No Enrollment application supports the given keyphrase/locale");
         return null;
index 9725e4f..e68d8a6 100644 (file)
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_START" />
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_END" />
 
-    <protected-broadcast android:name="com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE" />
+    <protected-broadcast android:name="com.android.server.ACTION_TRIGGER_IDLE" />
 
     <protected-broadcast android:name="android.intent.action.HDMI_PLUGGED" />
 
index 8611942..87f4682 100644 (file)
                 android:gravity="top"
                 systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
 
-            <com.android.systemui.statusbar.AlphaOptimizedButton
+            <com.android.systemui.statusbar.AlphaOptimizedImageView
                 android:id="@+id/alarm_status_collapsed"
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:drawablePadding="6dp"
-                android:drawableStart="@drawable/ic_access_alarms_small"
-                android:textColor="#64ffffff"
-                android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
+                android:layout_height="match_parent"
+                android:src="@drawable/ic_access_alarms_small"
                 android:paddingStart="6dp"
-                android:gravity="top"
-                android:background="?android:attr/selectableItemBackground"
+                android:gravity="center"
                 android:visibility="gone" />
         </LinearLayout>
 
index 55fa10b..cad7f64 100644 (file)
@@ -1542,7 +1542,7 @@ public class KeyguardViewMediator extends SystemUI {
 
     private void updateActivityLockScreenState() {
         try {
-            ActivityManagerNative.getDefault().setLockScreenShown(mShowing && !mOccluded);
+            ActivityManagerNative.getDefault().setLockScreenShown(mShowingmOccluded);
         } catch (RemoteException e) {
         }
     }
index afb2195..a5f3e77 100644 (file)
@@ -41,6 +41,7 @@ import android.view.WindowManager.LayoutParams;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Interpolators;
+import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
@@ -69,7 +70,6 @@ import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
 import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
 import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
 import com.android.systemui.recents.events.ui.UserInteractionEvent;
-import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
@@ -89,7 +89,7 @@ import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
 /**
- * The main Recents activity that is started from AlternateRecentsComponent.
+ * The main Recents activity that is started from RecentsComponent.
  */
 public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {
 
@@ -166,6 +166,13 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
             if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                 // When the screen turns off, dismiss Recents to Home
                 dismissRecentsToHomeIfVisible(false);
+            } else if (action.equals(Intent.ACTION_TIME_CHANGED)) {
+                // For the time being, if the time changes, then invalidate the
+                // last-stack-active-time, this ensures that we will just show the last N tasks
+                // the next time that Recents loads, but prevents really old tasks from showing
+                // up if the task time is set forward.
+                Prefs.putLong(RecentsActivity.this, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME,
+                        0);
             }
         }
     };
@@ -311,6 +318,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
         // Register the broadcast receiver to handle messages when the screen is turned off
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
+        filter.addAction(Intent.ACTION_TIME_CHANGED);
         registerReceiver(mSystemBroadcastReceiver, filter);
 
         getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION);
@@ -751,13 +759,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
         mIgnoreAltTabRelease = true;
     }
 
-    public final void onBusEvent(final DragEndEvent event) {
-        // Handle the case where we drop onto a dock region
-        if (event.dropTarget instanceof TaskStack.DockState) {
-            mScrimViews.animateScrimToCurrentNavBarState(false /* hasStackTasks */);
-        }
-    }
-
     public final void onBusEvent(final DockedTopTaskEvent event) {
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);
         mRecentsView.invalidate();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndCancelledEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/dragndrop/DragEndCancelledEvent.java
new file mode 100644 (file)
index 0000000..edd7995
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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.systemui.recents.events.ui.dragndrop;
+
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.DropTarget;
+import com.android.systemui.recents.views.TaskView;
+
+/**
+ * This event is sent whenever a drag end is cancelled because of an error.
+ */
+public class DragEndCancelledEvent extends EventBus.AnimatedEvent {
+
+    public final TaskStack stack;
+    public final Task task;
+    public final TaskView taskView;
+
+    public DragEndCancelledEvent(TaskStack stack, Task task, TaskView taskView) {
+        this.stack = stack;
+        this.task = task;
+        this.taskView = taskView;
+    }
+}
index 46b2612..08b52d9 100644 (file)
@@ -393,18 +393,19 @@ public class SystemServicesProxy {
     }
 
     /** Docks a task to the side of the screen and starts it. */
-    public void startTaskInDockedMode(int taskId, int createMode) {
-        if (mIam == null) return;
+    public boolean startTaskInDockedMode(int taskId, int createMode) {
+        if (mIam == null) return false;
 
         try {
-            // TODO: Determine what animation we want for the incoming task
             final ActivityOptions options = ActivityOptions.makeBasic();
             options.setDockCreateMode(createMode);
             options.setLaunchStackId(DOCKED_STACK_ID);
             mIam.startActivityFromRecents(taskId, options.toBundle());
-        } catch (RemoteException e) {
+            return true;
+        } catch (RemoteException | IllegalArgumentException e) {
             e.printStackTrace();
         }
+        return false;
     }
 
     /** Docks an already resumed task to the side of the screen. */
index f6cc12b..9fb8bd5 100644 (file)
@@ -226,6 +226,18 @@ public class Utilities {
     }
 
     /**
+     * Sets the given {@link View}'s frame from its current translation.
+     */
+    public static void setViewFrameFromTranslation(View v) {
+        RectF taskViewRect = new RectF(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
+        taskViewRect.offset(v.getTranslationX(), v.getTranslationY());
+        v.setTranslationX(0);
+        v.setTranslationY(0);
+        v.setLeftTopRightBottom((int) taskViewRect.left, (int) taskViewRect.top,
+                (int) taskViewRect.right, (int) taskViewRect.bottom);
+    }
+
+    /**
      * Returns a view stub for the given view id.
      */
     public static ViewStub findViewStubById(View v, int stubId) {
index 3979095..251ad71 100644 (file)
@@ -140,39 +140,10 @@ public class RecentsTaskLoadPlan {
             lastStackActiveTime = 0;
         }
         long newLastStackActiveTime = -1;
-        long prevLastActiveTime = lastStackActiveTime;
         int taskCount = mRawTasks.size();
         for (int i = 0; i < taskCount; i++) {
             ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
 
-            /*
-             * Affiliated tasks are returned in a specific order from ActivityManager but without a
-             * lastActiveTime since it hasn't yet been started. However, we later sort the task list
-             * by lastActiveTime, which rearranges the tasks. For now, we need to workaround this
-             * by updating the lastActiveTime of this task to the lastActiveTime of the task it is
-             * affiliated with, in the same order that we encounter it in the original list (just
-             * its index in the task group for the task it is affiliated with).
-             *
-             * If the parent task is not available, then we will use the last active time of the
-             * previous task as a base point (since the task itself may not have an active time)
-             * for the entire affiliated group.
-             */
-            if (t.persistentId != t.affiliatedTaskId) {
-                Task.TaskKey parentTask = affiliatedTasks.get(t.affiliatedTaskId);
-                long parentTaskLastActiveTime = parentTask != null
-                        ? parentTask.lastActiveTime
-                        : prevLastActiveTime;
-                if (RecentsDebugFlags.Static.EnableAffiliatedTaskGroups) {
-                    t.lastActiveTime = parentTaskLastActiveTime +
-                            affiliatedTaskCounts.get(t.affiliatedTaskId, 0) + 1;
-                } else {
-                    if (t.lastActiveTime == 0) {
-                        t.lastActiveTime = parentTaskLastActiveTime -
-                                affiliatedTaskCounts.get(t.affiliatedTaskId, 0) - 1;
-                    }
-                }
-            }
-
             // Compose the task key
             Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.stackId, t.baseIntent,
                     t.userId, t.firstActiveTime, t.lastActiveTime);
@@ -180,9 +151,14 @@ public class RecentsTaskLoadPlan {
             // This task is only shown in the stack if it statisfies the historical time or min
             // number of tasks constraints. Freeform tasks are also always shown.
             boolean isFreeformTask = SystemServicesProxy.isFreeformStack(t.stackId);
-            boolean isStackTask = isFreeformTask || (!isHistoricalTask(t) ||
-                    (t.lastActiveTime >= lastStackActiveTime && i >= (taskCount - MIN_NUM_TASKS)));
+            boolean isStackTask = isFreeformTask || !isHistoricalTask(t) ||
+                    (t.lastActiveTime >= lastStackActiveTime && i >= (taskCount - MIN_NUM_TASKS));
             boolean isLaunchTarget = taskKey.id == runningTaskId;
+
+            // The last stack active time is the baseline for which we show visible tasks.  Since
+            // the system will store all the tasks, we don't want to show the tasks prior to the
+            // last visible ones, otherwise, as you dismiss them, the previous tasks may satisfy
+            // the other stack-task constraints.
             if (isStackTask && newLastStackActiveTime < 0) {
                 newLastStackActiveTime = t.lastActiveTime;
             }
@@ -211,7 +187,6 @@ public class RecentsTaskLoadPlan {
             allTasks.add(task);
             affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1);
             affiliatedTasks.put(taskKey.id, taskKey);
-            prevLastActiveTime = t.lastActiveTime;
         }
         if (newLastStackActiveTime != -1) {
             Prefs.putLong(mContext, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME,
index c6528a1..86a0315 100644 (file)
@@ -118,6 +118,11 @@ public class Task {
     public TaskKey key;
 
     /**
+     * The temporary sort index in the stack, used when ordering the stack.
+     */
+    public int temporarySortIndexInStack;
+
+    /**
      * The group will be computed separately from the initialization of the task
      */
     @ViewDebug.ExportedProperty(deepExport=true, prefix="group_")
index c63a494..23739a0 100644 (file)
@@ -76,7 +76,8 @@ public class TaskKeyLruCache<V> {
     final V getAndInvalidateIfModified(Task.TaskKey key) {
         Task.TaskKey lastKey = mKeys.get(key.id);
         if (lastKey != null) {
-            if ((lastKey.stackId != key.stackId) || (lastKey.lastActiveTime < key.lastActiveTime)) {
+            if ((lastKey.stackId != key.stackId) ||
+                    (lastKey.lastActiveTime != key.lastActiveTime)) {
                 // The task has updated (been made active since the last time it was put into the
                 // LRU cache) or the stack id for the task has changed, invalidate that cache item
                 remove(key);
index f42eea3..50e28ca 100644 (file)
@@ -517,16 +517,8 @@ public class TaskStack {
         }
     }
 
-    // A comparator that sorts tasks by their last active time
-    private Comparator<Task> LAST_ACTIVE_TIME_COMPARATOR = new Comparator<Task>() {
-        @Override
-        public int compare(Task o1, Task o2) {
-            return Long.compare(o1.key.lastActiveTime, o2.key.lastActiveTime);
-        }
-    };
-
-    // A comparator that sorts tasks by their last active time and freeform state
-    private Comparator<Task> FREEFORM_LAST_ACTIVE_TIME_COMPARATOR = new Comparator<Task>() {
+    // A comparator that sorts tasks by their freeform state
+    private Comparator<Task> FREEFORM_COMPARATOR = new Comparator<Task>() {
         @Override
         public int compare(Task o1, Task o2) {
             if (o1.isFreeformTask() && !o2.isFreeformTask()) {
@@ -534,7 +526,7 @@ public class TaskStack {
             } else if (o2.isFreeformTask() && !o1.isFreeformTask()) {
                 return -1;
             }
-            return Long.compare(o1.key.lastActiveTime, o2.key.lastActiveTime);
+            return Long.compare(o1.temporarySortIndexInStack, o2.temporarySortIndexInStack);
         }
     };
 
@@ -696,7 +688,10 @@ public class TaskStack {
         }
 
         // Sort all the tasks to ensure they are ordered correctly
-        Collections.sort(allTasks, FREEFORM_LAST_ACTIVE_TIME_COMPARATOR);
+        for (int i = allTasks.size() - 1; i >= 0; i--) {
+            allTasks.get(i).temporarySortIndexInStack = i;
+        }
+        Collections.sort(allTasks, FREEFORM_COMPARATOR);
 
         mStackTaskList.set(allTasks);
         mRawTaskList = allTasks;
@@ -769,12 +764,11 @@ public class TaskStack {
     }
 
     /**
-     * Computes a set of all the active and historical tasks ordered by their last active time.
+     * Computes a set of all the active and historical tasks.
      */
     public ArrayList<Task> computeAllTasksList() {
         ArrayList<Task> tasks = new ArrayList<>();
         tasks.addAll(mStackTaskList.getTasks());
-        Collections.sort(tasks, LAST_ACTIVE_TIME_COMPARATOR);
         return tasks;
     }
 
index 9dc9c4c..acebf42 100644 (file)
@@ -350,13 +350,6 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
         } else {
             mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
         }
-        if(mTaskStackHorizontalGridView.getStack().getTaskCount() > 1 && !mLaunchedFromHome) {
-            // If there are 2 or more tasks, and we are not launching from home
-            // set the selected position to the 2nd task to allow for faster app switching
-            mTaskStackHorizontalGridView.setSelectedPosition(1);
-        } else {
-            mTaskStackHorizontalGridView.setSelectedPosition(0);
-        }
 
         // If this is a new instance from a configuration change, then we have to manually trigger
         // the enter animation state, or if recents was relaunched by AM, without going through
@@ -382,6 +375,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
         if(mLaunchedFromHome) {
             mHomeRecentsEnterExitAnimationHolder.startEnterAnimation(mPipManager.isPipShown());
         }
+        mTaskStackViewAdapter.setResetAddedCards(true);
         EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
     }
 
@@ -389,12 +383,20 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
     public void onResume() {
         super.onResume();
         mPipRecentsOverlayManager.onRecentsResumed();
+        if(mTaskStackHorizontalGridView.getStack().getTaskCount() > 1 && !mLaunchedFromHome) {
+            // If there are 2 or more tasks, and we are not launching from home
+            // set the selected position to the 2nd task to allow for faster app switching
+            mTaskStackHorizontalGridView.setSelectedPosition(1);
+        } else {
+            mTaskStackHorizontalGridView.setSelectedPosition(0);
+        }
     }
 
     @Override
     public void onPause() {
         super.onPause();
         mPipRecentsOverlayManager.onRecentsPaused();
+        mTaskStackViewAdapter.setResetAddedCards(false);
     }
 
     @Override
index 084fc87..65f5fff 100644 (file)
@@ -18,7 +18,6 @@ package com.android.systemui.recents.tv.animations;
 import android.animation.Animator.AnimatorListener;
 import android.content.res.Resources;
 import android.graphics.drawable.TransitionDrawable;
-import android.util.TypedValue;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -39,7 +38,7 @@ public class DismissAnimationsHolder {
     private TransitionDrawable mDismissDrawable;
     private TextView mDismissText;
 
-    private float mDismissUnselectedAlpha;
+    private float mDismissIconNotInDismissStateAlpha;
     private long mShortDuration;
     private long mLongDuration;
 
@@ -57,7 +56,7 @@ public class DismissAnimationsHolder {
         mDismissStartYDelta = mDismissEnterYDelta * 2;
         mShortDuration =  res.getInteger(R.integer.dismiss_short_duration);
         mLongDuration =  res.getInteger(R.integer.dismiss_long_duration);
-        mDismissUnselectedAlpha = res.getFloat(R.integer.dismiss_unselected_alpha);
+        mDismissIconNotInDismissStateAlpha = res.getFloat(R.integer.dismiss_unselected_alpha);
     }
 
     public void startEnterAnimation() {
@@ -94,7 +93,7 @@ public class DismissAnimationsHolder {
         mCardDismissIcon.animate()
                 .setDuration(mShortDuration)
                 .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .alpha(mDismissUnselectedAlpha)
+                .alpha(mDismissIconNotInDismissStateAlpha)
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
@@ -157,7 +156,7 @@ public class DismissAnimationsHolder {
         mInfoField.animate().setListener(null);
         mThumbnailView.setAlpha(1.0f);
         mThumbnailView.setTranslationY(0);
-        mCardDismissIcon.setAlpha(mDismissUnselectedAlpha);
+        mCardDismissIcon.setAlpha(0.0f);
         mDismissText.setAlpha(0.0f);
     }
 }
index eb3b02d..ed28ef1 100644 (file)
@@ -42,6 +42,7 @@ public class TaskStackHorizontalViewAdapter extends
     private static final String TAG = "TaskStackViewAdapter";
     private List<Task> mTaskList;
     private TaskStackHorizontalGridView mGridView;
+    private boolean mResetAddedCards;
 
     public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
         private TaskCardView mTaskCardView;
@@ -126,6 +127,13 @@ public class TaskStackHorizontalViewAdapter extends
     }
 
     @Override
+    public void onViewAttachedToWindow(ViewHolder holder) {
+        if (mResetAddedCards) {
+            holder.mTaskCardView.reset();
+        }
+    }
+
+    @Override
     public void onViewDetachedFromWindow(ViewHolder holder) {
         // We only want to reset on view detach if this is the last task being dismissed.
         // This is so that we do not reset when shifting to apps etc, as it is not needed.
@@ -171,4 +179,8 @@ public class TaskStackHorizontalViewAdapter extends
         mTaskList.add(position, task);
         notifyItemInserted(position);
     }
+
+    public void setResetAddedCards(boolean reset) {
+        mResetAddedCards = reset;
+    }
 }
index fd27b4f..a893910 100644 (file)
@@ -64,6 +64,7 @@ import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
 import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
 import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
+import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
@@ -510,45 +511,43 @@ public class RecentsView extends FrameLayout {
 
             // We translated the view but we need to animate it back from the current layout-space
             // rect to its final layout-space rect
-            int x = (int) event.taskView.getTranslationX();
-            int y = (int) event.taskView.getTranslationY();
-            Rect taskViewRect = new Rect(event.taskView.getLeft(), event.taskView.getTop(),
-                    event.taskView.getRight(), event.taskView.getBottom());
-            taskViewRect.offset(x, y);
-            event.taskView.setTranslationX(0);
-            event.taskView.setTranslationY(0);
-            event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
-                    taskViewRect.right, taskViewRect.bottom);
-
-            final OnAnimationStartedListener startedListener = new OnAnimationStartedListener() {
-                @Override
-                public void onAnimationStarted() {
-                    EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
-                    // Remove the task and don't bother relaying out, as all the tasks will be
-                    // relaid out when the stack changes on the multiwindow change event
-                    mTaskStackView.getStack().removeTask(event.task, null,
-                            true /* fromDockGesture */);
-                }
-            };
+            Utilities.setViewFrameFromTranslation(event.taskView);
 
             // Dock the task and launch it
             SystemServicesProxy ssp = Recents.getSystemServices();
-            ssp.startTaskInDockedMode(event.task.key.id, dockState.createMode);
-            final Rect taskRect = getTaskRect(event.taskView);
-            IAppTransitionAnimationSpecsFuture future = mTransitionHelper.getAppTransitionFuture(
-                    new AnimationSpecComposer() {
-                        @Override
-                        public List<AppTransitionAnimationSpec> composeSpecs() {
-                            return mTransitionHelper.composeDockAnimationSpec(
-                                    event.taskView, taskRect);
-                        }
-                    });
-            ssp.overridePendingAppTransitionMultiThumbFuture(future,
-                    mTransitionHelper.wrapStartedListener(startedListener),
-                    true /* scaleUp */);
-
-            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
-                    event.task.getTopComponent().flattenToShortString());
+            if (ssp.startTaskInDockedMode(event.task.key.id, dockState.createMode)) {
+                final OnAnimationStartedListener startedListener =
+                        new OnAnimationStartedListener() {
+                    @Override
+                    public void onAnimationStarted() {
+                        EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
+                        // Remove the task and don't bother relaying out, as all the tasks will be
+                        // relaid out when the stack changes on the multiwindow change event
+                        mTaskStackView.getStack().removeTask(event.task, null,
+                                true /* fromDockGesture */);
+                    }
+                };
+
+                final Rect taskRect = getTaskRect(event.taskView);
+                IAppTransitionAnimationSpecsFuture future =
+                        mTransitionHelper.getAppTransitionFuture(
+                                new AnimationSpecComposer() {
+                                    @Override
+                                    public List<AppTransitionAnimationSpec> composeSpecs() {
+                                        return mTransitionHelper.composeDockAnimationSpec(
+                                                event.taskView, taskRect);
+                                    }
+                                });
+                ssp.overridePendingAppTransitionMultiThumbFuture(future,
+                        mTransitionHelper.wrapStartedListener(startedListener),
+                        true /* scaleUp */);
+
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
+                        event.task.getTopComponent().flattenToShortString());
+            } else {
+                EventBus.getDefault().send(new DragEndCancelledEvent(mStack, event.task,
+                        event.taskView));
+            }
         } else {
             // Animate the overlay alpha back to 0
             updateVisibleDockRegions(null, true /* isDefaultDockState */, -1, -1,
@@ -565,6 +564,12 @@ public class RecentsView extends FrameLayout {
         }
     }
 
+    public final void onBusEvent(final DragEndCancelledEvent event) {
+        // Animate the overlay alpha back to 0
+        updateVisibleDockRegions(null, true /* isDefaultDockState */, -1, -1,
+                true /* animateAlpha */, false /* animateBounds */);
+    }
+
     private Rect getTaskRect(TaskView taskView) {
         int[] location = taskView.getLocationOnScreen();
         int viewX = location[0];
index 995f9f7..8f784b8 100644 (file)
@@ -28,6 +28,9 @@ import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimatio
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
 import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
+import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
+import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
+import com.android.systemui.recents.model.TaskStack;
 
 /** Manages the scrims for the various system bars. */
 public class SystemBarScrimViews {
@@ -154,10 +157,22 @@ public class SystemBarScrimViews {
         animateScrimToCurrentNavBarState(event.stack.getStackTaskCount() > 0);
     }
 
+    public final void onBusEvent(final DragEndEvent event) {
+        // Hide the nav bar scrims once we drop to a dock region
+        if (event.dropTarget instanceof TaskStack.DockState) {
+            animateScrimToCurrentNavBarState(false /* hasStackTasks */);
+        }
+    }
+
+    public final void onBusEvent(final DragEndCancelledEvent event) {
+        // Restore the scrims to the normal state
+        animateScrimToCurrentNavBarState(event.stack.getStackTaskCount() > 0);
+    }
+
     /**
      * Animates the scrim to match the state of the current nav bar.
      */
-    public void animateScrimToCurrentNavBarState(boolean hasStackTasks) {
+    private void animateScrimToCurrentNavBarState(boolean hasStackTasks) {
         boolean hasNavBarScrim = isNavBarScrimRequired(hasStackTasks);
         if (mHasNavBarScrim != hasNavBarScrim) {
             AnimationProps animation = hasNavBarScrim
index 773e587..3d0de1c 100644 (file)
@@ -79,6 +79,7 @@ import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEv
 import com.android.systemui.recents.events.ui.UserInteractionEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
+import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartInitializeDropTargetsEvent;
 import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
@@ -640,19 +641,23 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
     }
 
     /**
-     * @see #relayoutTaskViews(AnimationProps, boolean)
+     * @see #relayoutTaskViews(AnimationProps, ArrayMap<Task, AnimationProps>, boolean)
      */
     public void relayoutTaskViews(AnimationProps animation) {
-        relayoutTaskViews(animation, false /* ignoreTaskOverrides */);
+        relayoutTaskViews(animation, null /* animationOverrides */,
+                false /* ignoreTaskOverrides */);
     }
 
     /**
      * Relayout the the visible {@link TaskView}s to their current transforms as specified by the
      * {@link TaskStackLayoutAlgorithm} with the given {@param animation}. This call cancels any
      * animations that are current running on those task views, and will ensure that the children
-     * {@link TaskView}s will match the set of visible tasks in the stack.
+     * {@link TaskView}s will match the set of visible tasks in the stack.  If a {@link Task} has
+     * an animation provided in {@param animationOverrides}, that will be used instead.
      */
-    private void relayoutTaskViews(AnimationProps animation, boolean ignoreTaskOverrides) {
+    private void relayoutTaskViews(AnimationProps animation,
+            ArrayMap<Task, AnimationProps> animationOverrides,
+            boolean ignoreTaskOverrides) {
         // If we had a deferred animation, cancel that
         cancelDeferredTaskViewLayoutAnimation();
 
@@ -665,13 +670,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
         int taskViewCount = taskViews.size();
         for (int i = 0; i < taskViewCount; i++) {
             TaskView tv = taskViews.get(i);
-            int taskIndex = mStack.indexOfStackTask(tv.getTask());
+            Task task = tv.getTask();
+            int taskIndex = mStack.indexOfStackTask(task);
             TaskViewTransform transform = mCurrentTaskTransforms.get(taskIndex);
 
-            if (mIgnoreTasks.contains(tv.getTask().key)) {
+            if (mIgnoreTasks.contains(task.key)) {
                 continue;
             }
 
+            if (animationOverrides != null && animationOverrides.containsKey(task)) {
+                animation = animationOverrides.get(task);
+            }
+
             updateTaskViewToTransform(tv, transform, animation);
         }
     }
@@ -829,6 +839,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
         }
     }
 
+    /**
+     * Updates the stack layout to its stable places.
+     */
+    private void updateLayoutToStableBounds() {
+        mWindowRect.set(mStableWindowRect);
+        mStackBounds.set(mStableStackBounds);
+        mLayoutAlgorithm.setSystemInsets(mStableLayoutAlgorithm.mSystemInsets);
+        mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
+                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+        updateLayoutAlgorithm(true /* boundScroll */);
+    }
+
     /** Returns the scroller. */
     public TaskStackViewScroller getScroller() {
         return mStackScroller;
@@ -1820,16 +1842,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
         } else {
             // Restore the pre-drag task stack bounds, but ensure that we don't layout the dragging
             // task view, so add it back to the ignore set after updating the layout
-            mWindowRect.set(mStableWindowRect);
-            mStackBounds.set(mStableStackBounds);
             removeIgnoreTask(event.task);
-            mLayoutAlgorithm.setSystemInsets(mStableLayoutAlgorithm.mSystemInsets);
-            mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
-                    TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
-            updateLayoutAlgorithm(true /* boundScroll */);
+            updateLayoutToStableBounds();
             addIgnoreTask(event.task);
         }
-        relayoutTaskViews(animation, ignoreTaskOverrides);
+        relayoutTaskViews(animation, null /* animationOverrides */, ignoreTaskOverrides);
     }
 
     public final void onBusEvent(final DragEndEvent event) {
@@ -1867,30 +1884,38 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
             });
         }
 
-        // We translated the view but we need to animate it back from the current layout-space rect
-        // to its final layout-space rect
-        int x = (int) event.taskView.getTranslationX();
-        int y = (int) event.taskView.getTranslationY();
-        Rect taskViewRect = new Rect(event.taskView.getLeft(), event.taskView.getTop(),
-                event.taskView.getRight(), event.taskView.getBottom());
-        taskViewRect.offset(x, y);
-        event.taskView.setTranslationX(0);
-        event.taskView.setTranslationY(0);
-        event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
-                taskViewRect.right, taskViewRect.bottom);
+        // Restore the task, so that relayout will apply to it below
+        removeIgnoreTask(event.task);
 
-        // Animate the non-drag TaskViews back into position
-        mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
-                mTmpTransform, null);
-        event.getAnimationTrigger().increment();
-        relayoutTaskViews(new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
+        // Convert the dragging task view back to its final layout-space rect
+        Utilities.setViewFrameFromTranslation(event.taskView);
+
+        // Animate all the tasks into place
+        ArrayMap<Task, AnimationProps> animationOverrides = new ArrayMap<>();
+        animationOverrides.put(event.task, new AnimationProps(SLOW_SYNC_STACK_DURATION,
+                Interpolators.FAST_OUT_SLOW_IN,
+                event.getAnimationTrigger().decrementOnAnimationEnd()));
+        relayoutTaskViews(new AnimationProps(SLOW_SYNC_STACK_DURATION,
                 Interpolators.FAST_OUT_SLOW_IN));
+        event.getAnimationTrigger().increment();
+    }
 
-        // Animate the drag TaskView back into position
-        updateTaskViewToTransform(event.taskView, mTmpTransform,
-                new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN,
-                        event.getAnimationTrigger().decrementOnAnimationEnd()));
+    public final void onBusEvent(final DragEndCancelledEvent event) {
+        // Restore the pre-drag task stack bounds, including the dragging task view
         removeIgnoreTask(event.task);
+        updateLayoutToStableBounds();
+
+        // Convert the dragging task view back to its final layout-space rect
+        Utilities.setViewFrameFromTranslation(event.taskView);
+
+        // Animate all the tasks into place
+        ArrayMap<Task, AnimationProps> animationOverrides = new ArrayMap<>();
+        animationOverrides.put(event.task, new AnimationProps(SLOW_SYNC_STACK_DURATION,
+                Interpolators.FAST_OUT_SLOW_IN,
+                event.getAnimationTrigger().decrementOnAnimationEnd()));
+        relayoutTaskViews(new AnimationProps(SLOW_SYNC_STACK_DURATION,
+                Interpolators.FAST_OUT_SLOW_IN));
+        event.getAnimationTrigger().increment();
     }
 
     public final void onBusEvent(IterateRecentsEvent event) {
index c1e7e04..612c41d 100644 (file)
@@ -49,6 +49,7 @@ import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.LaunchTaskEvent;
 import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
 import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
+import com.android.systemui.recents.events.ui.dragndrop.DragEndCancelledEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
@@ -695,15 +696,18 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
 
     public final void onBusEvent(DragEndEvent event) {
         if (!(event.dropTarget instanceof TaskStack.DockState)) {
-            event.addPostAnimationCallback(new Runnable() {
-                @Override
-                public void run() {
-                    // Animate the drag view back from where it is, to the view location, then after
-                    // it returns, update the clip state
-                    setClipViewInStack(true);
-                }
+            event.addPostAnimationCallback(() -> {
+                // Reset the clip state for the drag view after the end animation completes
+                setClipViewInStack(true);
             });
         }
         EventBus.getDefault().unregister(this);
     }
+
+    public final void onBusEvent(DragEndCancelledEvent event) {
+        // Reset the clip state for the drag view after the cancel animation completes
+        event.addPostAnimationCallback(() -> {
+            setClipViewInStack(true);
+        });
+    }
 }
index ec45d60..ee4a102 100644 (file)
@@ -282,6 +282,12 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi
             final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId());
             if (indexOfKey >= 0) {
                 mButtonDispatchers.valueAt(indexOfKey).addView(v);
+            } else if (v instanceof ViewGroup) {
+                final ViewGroup viewGroup = (ViewGroup)v;
+                final int N = viewGroup.getChildCount();
+                for (int i = 0; i < N; i++) {
+                    addToDispatchers(viewGroup.getChildAt(i));
+                }
             }
         }
     }
index e32d51a..d6deba0 100644 (file)
@@ -57,7 +57,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
     protected View mSettingsContainer;
 
     private TextView mAlarmStatus;
-    private TextView mAlarmStatusCollapsed;
+    private View mAlarmStatusCollapsed;
 
     private QSPanel mQsPanel;
 
@@ -117,7 +117,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
         mSettingsContainer = findViewById(R.id.settings_button_container);
         mSettingsButton.setOnClickListener(this);
 
-        mAlarmStatusCollapsed = (TextView) findViewById(R.id.alarm_status_collapsed);
+        mAlarmStatusCollapsed = findViewById(R.id.alarm_status_collapsed);
         mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
         mAlarmStatus.setOnClickListener(this);
 
index 94118e6..f52bda9 100644 (file)
@@ -390,6 +390,11 @@ public final class ActivityManagerService extends ActivityManagerNative
     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
 
+    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
+    // here so that while the job scheduler can depend on AMS, the other way around
+    // need not be the case.
+    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
+
     /** Control over CPU and battery monitoring */
     // write battery stats every 30 minutes.
     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
@@ -11476,7 +11481,7 @@ public final class ActivityManagerService extends ActivityManagerNative
         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
     }
 
-    public void setLockScreenShown(boolean shown) {
+    public void setLockScreenShown(boolean showing, boolean occluded) {
         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
@@ -11486,8 +11491,17 @@ public final class ActivityManagerService extends ActivityManagerNative
         synchronized(this) {
             long ident = Binder.clearCallingIdentity();
             try {
-                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
-                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
+                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
+                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
+                if (showing && occluded) {
+                    // The lock screen is currently showing, but is occluded by a window that can
+                    // show on top of the lock screen. In this can we want to dismiss the docked
+                    // stack since it will be complicated/risky to try to put the activity on top
+                    // of the lock screen in the right fullscreen configuration.
+                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
+                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
+                }
+
                 updateSleepIfNeededLocked();
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -12649,6 +12663,26 @@ public final class ActivityManagerService extends ActivityManagerNative
         }
     }
 
+    @Override
+    public void sendIdleJobTrigger() {
+        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires permission "
+                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
+        }
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
+                    .setPackage("android")
+                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            broadcastIntent(null, intent, null, null, 0, null, null, null,
+                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     private void retrieveSettings() {
         final ContentResolver resolver = mContext.getContentResolver();
         final boolean freeformWindowManagement =
index 88faee7..cea76f2 100644 (file)
@@ -65,6 +65,9 @@ class RecentTasks extends ArrayList<TaskRecord> {
     private static final int MAX_RECENT_BITMAPS = 3;
     private static final int DEFAULT_INITIAL_CAPACITY = 5;
 
+    // Whether or not to move all affiliated tasks to the front when one of the tasks is launched
+    private static final boolean MOVE_AFFILIATED_TASKS_TO_FRONT = false;
+
     /**
      * Save recent tasks information across reboots.
      */
@@ -513,7 +516,7 @@ class RecentTasks extends ArrayList<TaskRecord> {
         if (task.inRecents) {
             int taskIndex = indexOf(task);
             if (taskIndex >= 0) {
-                if (!isAffiliated) {
+                if (!isAffiliated || MOVE_AFFILIATED_TASKS_TO_FRONT) {
                     // Simple case: this is not an affiliated task, so we just move it to the front.
                     remove(taskIndex);
                     add(0, task);
index c7a679c..5899d16 100644 (file)
@@ -28,15 +28,13 @@ import android.content.IntentFilter;
 import android.os.SystemClock;
 import android.util.Slog;
 
+import com.android.server.am.ActivityManagerService;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.StateChangedListener;
 
 public class IdleController extends StateController {
     private static final String TAG = "IdleController";
 
-    private static final String ACTION_TRIGGER_IDLE =
-            "com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE";
-
     // Policy: we decide that we're "idle" if the device has been unused /
     // screen off or dreaming for at least this long
     private long mInactivityIdleThreshold;
@@ -113,7 +111,7 @@ public class IdleController extends StateController {
         public IdlenessTracker() {
             mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
 
-            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
+            Intent intent = new Intent(ActivityManagerService.ACTION_TRIGGER_IDLE)
                     .setPackage("android")
                     .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
             mIdleTriggerIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
@@ -140,7 +138,7 @@ public class IdleController extends StateController {
             filter.addAction(Intent.ACTION_DREAMING_STOPPED);
 
             // Debugging/instrumentation
-            filter.addAction(ACTION_TRIGGER_IDLE);
+            filter.addAction(ActivityManagerService.ACTION_TRIGGER_IDLE);
 
             mContext.registerReceiver(this, filter);
         }
@@ -176,7 +174,7 @@ public class IdleController extends StateController {
                 mScreenOn = false;
                 mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                         when, mIdleWindowSlop, mIdleTriggerIntent);
-            } else if (action.equals(ACTION_TRIGGER_IDLE)) {
+            } else if (action.equals(ActivityManagerService.ACTION_TRIGGER_IDLE)) {
                 // idle time starts now. Do not set mIdle if screen is on.
                 if (!mIdle && !mScreenOn) {
                     if (DEBUG) {