OSDN Git Service

Merge "Unblock 'am start -W' if activity is brought to front without launching" into...
authorChong Zhang <chz@google.com>
Wed, 22 Jun 2016 17:17:47 +0000 (17:17 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Wed, 22 Jun 2016 17:17:48 +0000 (17:17 +0000)
20 files changed:
core/java/android/app/job/JobInfo.java
core/java/android/service/quicksettings/IQSService.aidl
core/java/android/service/quicksettings/TileService.java
packages/CtsShim/CtsShim.apk
packages/CtsShim/CtsShimPriv.apk
packages/SystemUI/res/values/strings_tv.xml
packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
services/core/java/com/android/server/am/ActivityStackSupervisor.java
services/core/java/com/android/server/am/UserController.java
services/core/java/com/android/server/job/controllers/ContentObserverController.java
services/core/java/com/android/server/notification/NotificationManagerService.java
services/core/java/com/android/server/pm/UserManagerService.java

index c4ca82e..5823abf 100644 (file)
@@ -28,6 +28,7 @@ import android.os.PersistableBundle;
 import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Objects;
 
 /**
  * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
@@ -494,6 +495,20 @@ public class JobInfo implements Parcelable {
             return mFlags;
         }
 
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof TriggerContentUri)) {
+                return false;
+            }
+            TriggerContentUri t = (TriggerContentUri) o;
+            return Objects.equals(t.mUri, mUri) && t.mFlags == mFlags;
+        }
+
+        @Override
+        public int hashCode() {
+            return (mUri == null ? 0 : mUri.hashCode()) ^ mFlags;
+        }
+
         private TriggerContentUri(Parcel in) {
             mUri = Uri.CREATOR.createFromParcel(in);
             mFlags = in.readInt();
index 747f185..bf96357 100644 (file)
@@ -23,6 +23,7 @@ import android.service.quicksettings.Tile;
  * @hide
  */
 interface IQSService {
+    Tile getTile(in ComponentName component);
     void updateQsTile(in Tile tile);
     void updateStatusIcon(in Tile tile, in Icon icon,
             String contentDescription);
index 67793fd..55cfb49 100644 (file)
@@ -123,11 +123,6 @@ public class TileService extends Service {
     /**
      * @hide
      */
-    public static final String EXTRA_TILE = "tile";
-
-    /**
-     * @hide
-     */
     public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
 
     private final H mHandler = new H(Looper.getMainLooper());
@@ -315,9 +310,16 @@ public class TileService extends Service {
 
     @Override
     public IBinder onBind(Intent intent) {
-        mTile = intent.getParcelableExtra(EXTRA_TILE);
         mService = IQSService.Stub.asInterface(intent.getIBinderExtra(EXTRA_SERVICE));
-        mTile.setService(mService);
+        try {
+            mTile = mService.getTile(new ComponentName(getPackageName(), getClass().getName()));
+        } catch (RemoteException e) {
+            throw new RuntimeException("Unable to reach IQSService", e);
+        }
+        if (mTile != null) {
+            mTile.setService(mService);
+            mHandler.sendEmptyMessage(H.MSG_START_SUCCESS);
+        }
         return new IQSTileService.Stub() {
             @Override
             public void onTileRemoved() throws RemoteException {
@@ -358,6 +360,7 @@ public class TileService extends Service {
         private static final int MSG_TILE_REMOVED = 4;
         private static final int MSG_TILE_CLICKED = 5;
         private static final int MSG_UNLOCK_COMPLETE = 6;
+        private static final int MSG_START_SUCCESS = 7;
 
         public H(Looper looper) {
             super(looper);
@@ -397,6 +400,12 @@ public class TileService extends Service {
                         mUnlockRunnable.run();
                     }
                     break;
+                case MSG_START_SUCCESS:
+                    try {
+                        mService.onStartSuccessful(mTile);
+                    } catch (RemoteException e) {
+                    }
+                    break;
             }
         }
     }
index 7a27a43..2728903 100644 (file)
Binary files a/packages/CtsShim/CtsShim.apk and b/packages/CtsShim/CtsShim.apk differ
index 63e8688..9a8e75c 100644 (file)
Binary files a/packages/CtsShim/CtsShimPriv.apk and b/packages/CtsShim/CtsShimPriv.apk differ
index b1d23d8..f49d201 100644 (file)
@@ -44,4 +44,8 @@
     <string name="font_roboto_regular" translatable="false">sans-serif</string>
     <!-- DO NOT TRANSLATE -->
     <string name="font_roboto_light" translatable="false">sans-serif-light</string>
+    <!-- Package names to be blacklisted in Recents, add package names into overlay as needed -->
+    <string-array name="recents_tv_blacklist_array">
+    </string-array>
+
 </resources>
index 8a0079d..0de1e30 100644 (file)
@@ -233,6 +233,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
                 setVisibility(View.GONE);
             }
             mNotifQsContainer.setCustomizerAnimating(false);
+            mRecyclerView.setAdapter(mTileAdapter);
         }
 
         @Override
index f060502..8e4ed91 100644 (file)
@@ -112,6 +112,9 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
     }
 
     public void setTileSpecs(List<String> currentSpecs) {
+        if (currentSpecs.equals(mCurrentSpecs)) {
+            return;
+        }
         mCurrentSpecs = currentSpecs;
         recalcSpecs();
     }
@@ -257,7 +260,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
         }
         holder.mTileView.onStateChanged(info.state);
         holder.mTileView.setAppLabel(info.appLabel);
-        holder.mTileView.setShowAppLabel(mTileDividerIndex > -1 && position > mTileDividerIndex);
+        holder.mTileView.setShowAppLabel(position > mEditIndex && !info.isSystem);
 
         if (mAccessibilityManager.isTouchExplorationEnabled()) {
             final boolean selectable = !mAccessibilityMoving || position < mEditIndex;
@@ -292,13 +295,11 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
         mTiles.remove(mEditIndex--);
         notifyItemRemoved(mEditIndex - 1);
         move(mAccessibilityFromIndex, position, v);
-        updateDividerLocations();
         notifyDataSetChanged();
-        saveSpecs(mHost);
     }
 
     private void showAccessibilityDialog(final int position, final View v) {
-        TileInfo info = mTiles.get(position);
+        final TileInfo info = mTiles.get(position);
         CharSequence[] options = new CharSequence[] {
                 mContext.getString(R.string.accessibility_qs_edit_move_tile, info.state.label),
                 mContext.getString(R.string.accessibility_qs_edit_remove_tile, info.state.label),
@@ -310,7 +311,9 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
                         if (which == 0) {
                             startAccessibleDrag(position);
                         } else {
-                            move(position, mEditIndex, v);
+                            move(position, info.isSystem ? mEditIndex : mTileDividerIndex, v);
+                            notifyItemChanged(mTileDividerIndex);
+                            notifyDataSetChanged();
                         }
                     }
                 }).setNegativeButton(android.R.string.cancel, null)
@@ -334,40 +337,12 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
     }
 
     private boolean move(int from, int to, View v) {
-        if (to >= mEditIndex) {
-            if (from < mEditIndex) {
-                // Removing a tile.
-                // Sort tiles into system/non-system groups.
-                TileInfo tile = mTiles.get(from);
-                if (tile.isSystem) {
-                    if (to > mTileDividerIndex) {
-                        to = mTileDividerIndex;
-                    }
-                } else {
-                    if (mTileDividerIndex == mTiles.size() - 1) {
-                        notifyItemChanged(mTileDividerIndex);
-                    }
-                    if (to <= mTileDividerIndex) {
-                        to = mTileDividerIndex;
-                    }
-                }
-            } else {
-                if (to > mEditIndex) {
-                    // Don't allow tiles to be dragged around when they aren't added.
-                    to = from;
-                }
-                // Allow the case where to == mEditIndex to fall through and swap which
-                // side the tile is currently on.
-                // This lets the the cases where all tiles are on one side of the line
-                // work.
-            }
+        if (to == from) {
+            return true;
         }
         CharSequence fromLabel = mTiles.get(from).state.label;
         move(from, to, mTiles);
         updateDividerLocations();
-        if (to == from) {
-            return true;
-        }
         CharSequence announcement;
         if (to >= mEditIndex) {
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE_SPEC,
@@ -427,7 +402,6 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
     private <T> void move(int from, int to, List<T> list) {
         list.add(to, list.remove(from));
         notifyItemMoved(from, to);
-        notifyItemChanged(to);
     }
 
     public class Holder extends ViewHolder {
@@ -499,7 +473,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
             for (int i = 0; i < childCount; i++) {
                 final View child = parent.getChildAt(i);
                 final ViewHolder holder = parent.getChildViewHolder(child);
-                if (holder.getAdapterPosition() < mEditIndex) {
+                if (holder.getAdapterPosition() < mEditIndex && !(child instanceof TextView)) {
                     continue;
                 }
 
@@ -530,7 +504,15 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
         @Override
         public void onSelectedChanged(ViewHolder viewHolder, int actionState) {
             super.onSelectedChanged(viewHolder, actionState);
+            if (actionState != ItemTouchHelper.ACTION_STATE_DRAG) {
+                viewHolder = null;
+            }
+            if (viewHolder == mCurrentDrag) return;
             if (mCurrentDrag != null) {
+                int position = mCurrentDrag.getAdapterPosition();
+                TileInfo info = mTiles.get(position);
+                mCurrentDrag.mTileView.setShowAppLabel(
+                        position > mEditIndex && !info.isSystem);
                 mCurrentDrag.stopDrag();
                 mCurrentDrag = null;
             }
@@ -547,6 +529,12 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
         }
 
         @Override
+        public boolean canDropOver(RecyclerView recyclerView, ViewHolder current,
+                ViewHolder target) {
+            return target.getAdapterPosition() <= mEditIndex + 1;
+        }
+
+        @Override
         public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
             if (viewHolder.getItemViewType() == TYPE_EDIT) {
                 return makeMovementFlags(0, 0);
index 777ed6a..1431b22 100644 (file)
@@ -155,7 +155,7 @@ public class TileQueryHelper {
                     addTile(spec, appLabel, state, false);
                     continue;
                 }
-                if (info.serviceInfo.icon == 0) {
+                if (info.serviceInfo.icon == 0 && info.serviceInfo.applicationInfo.icon == 0) {
                     continue;
                 }
                 Drawable icon = info.serviceInfo.loadIcon(pm);
index 46e7277..d3f5d26 100644 (file)
@@ -84,11 +84,13 @@ public class CustomTile extends QSTile<QSTile.State> implements TileChangeListen
             PackageManager pm = mContext.getPackageManager();
             ServiceInfo info = pm.getServiceInfo(mComponent,
                     PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE);
+            int icon = info.icon != 0 ? info.icon
+                    : info.applicationInfo.icon;
             // Update the icon if its not set or is the default icon.
             boolean updateIcon = mTile.getIcon() == null
                     || iconEquals(mTile.getIcon(), mDefaultIcon);
-            mDefaultIcon = info.icon != 0 ? android.graphics.drawable.Icon
-                    .createWithResource(mComponent.getPackageName(), info.icon) : null;
+            mDefaultIcon = icon != 0 ? android.graphics.drawable.Icon
+                    .createWithResource(mComponent.getPackageName(), icon) : null;
             if (updateIcon) {
                 mTile.setIcon(mDefaultIcon);
             }
index dd46779..d68502e 100644 (file)
@@ -88,7 +88,6 @@ public class TileLifecycleManager extends BroadcastReceiver implements
         mHandler = handler;
         mIntent = intent;
         mIntent.putExtra(TileService.EXTRA_SERVICE, service.asBinder());
-        mIntent.putExtra(TileService.EXTRA_TILE, tile);
         mUser = user;
         if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser);
     }
index f84c5d0..6f0bed2 100644 (file)
@@ -263,6 +263,16 @@ public class TileServices extends IQSService.Stub {
     }
 
     @Override
+    public Tile getTile(ComponentName componentName) {
+        verifyCaller(componentName.getPackageName());
+        CustomTile customTile = getTileForComponent(componentName);
+        if (customTile != null) {
+            return customTile.getQsTile();
+        }
+        return null;
+    }
+
+    @Override
     public void startUnlockAndRun(Tile tile) {
         ComponentName componentName = tile.getComponentName();
         verifyCaller(componentName.getPackageName());
index 1a944ce..94231c6 100644 (file)
@@ -29,6 +29,7 @@ import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.ITaskStackListener;
+import android.app.UiModeManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -38,6 +39,7 @@ import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -83,6 +85,7 @@ import com.android.systemui.recents.model.ThumbnailData;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
@@ -234,6 +237,13 @@ public class SystemServicesProxy {
             mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
             mDummyIcon.eraseColor(0xFF999999);
         }
+
+        UiModeManager uiModeManager = (UiModeManager) context.
+                getSystemService(Context.UI_MODE_SERVICE);
+        if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
+            Collections.addAll(sRecentsBlacklist,
+                    res.getStringArray(R.array.recents_tv_blacklist_array));
+        }
     }
 
     /**
index 9041341..4664851 100644 (file)
 
 package com.android.systemui.statusbar.policy;
 
+import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiManager;
+import android.os.UserManager;
 import android.util.Log;
 
 import java.io.FileDescriptor;
@@ -49,7 +51,8 @@ public class HotspotControllerImpl implements HotspotController {
     @Override
     public boolean isHotspotSupported() {
         return mConnectivityManager.isTetheringSupported()
-                && mConnectivityManager.getTetherableWifiRegexs().length != 0;
+                && mConnectivityManager.getTetherableWifiRegexs().length != 0
+                && UserManager.get(mContext).isUserAdmin(ActivityManager.getCurrentUser());
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
index c8c7d3d..5eaea90 100644 (file)
@@ -152,8 +152,10 @@ public class StackScrollAlgorithm {
             float newYTranslation = state.yTranslation;
             float newHeight = state.height;
             float newNotificationEnd = newYTranslation + newHeight;
-
-            if (newYTranslation < previousNotificationEnd) {
+            boolean isHeadsUp = (child instanceof ExpandableNotificationRow)
+                    && ((ExpandableNotificationRow) child).isPinned();
+            if (newYTranslation < previousNotificationEnd && ambientState.isShadeExpanded()
+                    && !isHeadsUp) {
                 // The previous view is overlapping on top, clip!
                 float overlapAmount = previousNotificationEnd - newYTranslation;
                 state.clipTopAmount = (int) overlapAmount;
index 033471c..36207c4 100644 (file)
@@ -3045,8 +3045,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
 
     /** Checks whether the activity should be shown for current user. */
     boolean okToShowLocked(ActivityRecord r) {
-        return r != null && (isCurrentProfileLocked(r.userId)
-                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
+        return r != null && ((r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
+                || (isCurrentProfileLocked(r.userId)
+                && !mService.mUserController.isUserStoppingOrShuttingDownLocked(r.userId)));
     }
 
     final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
index 4380af3..b685dd3 100644 (file)
@@ -1335,6 +1335,15 @@ final class UserController {
         return mStartedUserArray;
     }
 
+    boolean isUserStoppingOrShuttingDownLocked(int userId) {
+        UserState state = getStartedUserStateLocked(userId);
+        if (state == null) {
+            return false;
+        }
+        return state.state == UserState.STATE_STOPPING
+                || state.state == UserState.STATE_SHUTDOWN;
+    }
+
     boolean isUserRunningLocked(int userId, int flags) {
         UserState state = getStartedUserStateLocked(userId);
         if (state == null) {
index 26660e8..9dce070 100644 (file)
@@ -57,7 +57,7 @@ public class ContentObserverController extends StateController {
     private static volatile ContentObserverController sController;
 
     final private List<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
-    ArrayMap<Uri, ObserverInstance> mObservers = new ArrayMap<>();
+    ArrayMap<JobInfo.TriggerContentUri, ObserverInstance> mObservers = new ArrayMap<>();
     final Handler mHandler;
 
     public static ContentObserverController get(JobSchedulerService taskManagerService) {
@@ -253,10 +253,10 @@ public class ContentObserverController extends StateController {
             final JobInfo.TriggerContentUri[] uris = jobStatus.getJob().getTriggerContentUris();
             if (uris != null) {
                 for (JobInfo.TriggerContentUri uri : uris) {
-                    ObserverInstance obs = mObservers.get(uri.getUri());
+                    ObserverInstance obs = mObservers.get(uri);
                     if (obs == null) {
                         obs = new ObserverInstance(mHandler, uri.getUri());
-                        mObservers.put(uri.getUri(), obs);
+                        mObservers.put(uri, obs);
                         mContext.getContentResolver().registerContentObserver(
                                 uri.getUri(),
                                 (uri.getFlags() &
@@ -316,7 +316,7 @@ public class ContentObserverController extends StateController {
                 obs.mJobs.remove(this);
                 if (obs.mJobs.size() == 0) {
                     mContext.getContentResolver().unregisterContentObserver(obs);
-                    mObservers.remove(obs.mUri);
+                    mObservers.remove(obs);
                 }
             }
         }
@@ -355,7 +355,10 @@ public class ContentObserverController extends StateController {
                     continue;
                 }
                 pw.print("    ");
-                pw.print(mObservers.keyAt(i));
+                JobInfo.TriggerContentUri trigger = mObservers.keyAt(i);
+                pw.print(trigger.getUri());
+                pw.print(" 0x");
+                pw.print(Integer.toHexString(trigger.getFlags()));
                 pw.print(" (");
                 pw.print(System.identityHashCode(obs));
                 pw.println("):");
index ce94220..73850de 100644 (file)
@@ -3898,7 +3898,9 @@ public class NotificationManagerService extends SystemService {
         @Override
         public void onUserSwitched(int user) {
             synchronized (mNotificationList) {
-                for (ManagedServiceInfo info : mServices) {
+                int i = mServices.size()-1;
+                while (i --> 0) {
+                    final ManagedServiceInfo info = mServices.get(i);
                     unregisterService(info.service, info.userid);
                 }
             }
index 4c515f0..d8a1c77 100644 (file)
@@ -732,9 +732,9 @@ public class UserManagerService extends IUserManager.Stub {
             long identity = Binder.clearCallingIdentity();
             try {
                 if (enableQuietMode) {
+                    ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null);
                     LocalServices.getService(ActivityManagerInternal.class)
                             .killForegroundAppsForUser(userHandle);
-                    ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null);
                 } else {
                     ActivityManagerNative.getDefault().startUserInBackground(userHandle);
                 }