Merge "Don't dock tasks that are non-dockable" into nyc-dev
diff --git a/api/system-current.txt b/api/system-current.txt
index 59d53e0..a0035fb 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -36958,37 +36958,6 @@
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
   }
 
-  public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
-    ctor public NotificationAssistantService();
-    method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAssistantService.Adjustment);
-    method public final android.os.IBinder onBind(android.content.Intent);
-    method public void onNotificationActionClick(java.lang.String, long, int);
-    method public void onNotificationClick(java.lang.String, long);
-    method public abstract android.service.notification.NotificationAssistantService.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
-    method public void onNotificationRemoved(java.lang.String, long, int);
-    method public void onNotificationVisibilityChanged(java.lang.String, long, boolean);
-    field public static final int REASON_APP_CANCEL = 8; // 0x8
-    field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9
-    field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2
-    field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3
-    field public static final int REASON_DELEGATE_CLICK = 1; // 0x1
-    field public static final int REASON_DELEGATE_ERROR = 4; // 0x4
-    field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd
-    field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc
-    field public static final int REASON_LISTENER_CANCEL = 10; // 0xa
-    field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb
-    field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
-    field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
-    field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe
-    field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf
-    field public static final int REASON_USER_STOPPED = 6; // 0x6
-    field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
-  }
-
-  public class NotificationAssistantService.Adjustment {
-    ctor public NotificationAssistantService.Adjustment(int, java.lang.CharSequence, android.net.Uri);
-  }
-
   public abstract class NotificationListenerService extends android.app.Service {
     ctor public NotificationListenerService();
     method public final void cancelAllNotifications();
@@ -37058,6 +37027,37 @@
     field public static final android.os.Parcelable.Creator<android.service.notification.NotificationListenerService.RankingMap> CREATOR;
   }
 
+  public abstract class NotificationRankerService extends android.service.notification.NotificationListenerService {
+    ctor public NotificationRankerService();
+    method public final void adjustImportance(java.lang.String, android.service.notification.NotificationRankerService.Adjustment);
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public void onNotificationActionClick(java.lang.String, long, int);
+    method public void onNotificationClick(java.lang.String, long);
+    method public abstract android.service.notification.NotificationRankerService.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+    method public void onNotificationRemoved(java.lang.String, long, int);
+    method public void onNotificationVisibilityChanged(java.lang.String, long, boolean);
+    field public static final int REASON_APP_CANCEL = 8; // 0x8
+    field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9
+    field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2
+    field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3
+    field public static final int REASON_DELEGATE_CLICK = 1; // 0x1
+    field public static final int REASON_DELEGATE_ERROR = 4; // 0x4
+    field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd
+    field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc
+    field public static final int REASON_LISTENER_CANCEL = 10; // 0xa
+    field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb
+    field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
+    field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
+    field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe
+    field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf
+    field public static final int REASON_USER_STOPPED = 6; // 0x6
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationRankerService";
+  }
+
+  public class NotificationRankerService.Adjustment {
+    ctor public NotificationRankerService.Adjustment(int, java.lang.CharSequence, android.net.Uri);
+  }
+
   public class StatusBarNotification implements android.os.Parcelable {
     ctor public StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long);
     ctor public StatusBarNotification(android.os.Parcel);
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 5697924..2c270fc 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -61,7 +61,7 @@
     StatusBarNotification[] getActiveNotifications(String callingPkg);
     StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count);
 
-    void registerListener(in INotificationListener listener, in ComponentName component, int userid);
+    void registerListener(in INotificationListener listener, in ComponentName component, int userid, boolean asRanker);
     void unregisterListener(in INotificationListener listener, int userid);
 
     void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id);
@@ -80,7 +80,7 @@
     void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
     void setInterruptionFilter(String pkg, int interruptionFilter);
 
-    void setImportanceFromAssistant(in INotificationListener token, String key, int importance, CharSequence explanation);
+    void setImportanceFromRankerService(in INotificationListener token, String key, int importance, CharSequence explanation);
 
     ComponentName getEffectsSuppressor();
     boolean matchesCallFilter(in Bundle extras);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index b4e9f60..c684447 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -120,6 +120,8 @@
 
     int checkUidSignatures(int uid1, int uid2);
 
+    List<String> getAllPackages();
+
     String[] getPackagesForUid(int uid);
 
     String getNameForUid(int uid);
@@ -380,6 +382,13 @@
      */
     void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);
 
+    /**
+     * Clear the profile data of an application.
+     * @param packageName The package name of the application whose profile data
+     * need to be deleted
+     */
+    void clearApplicationProfileData(in String packageName);
+
    /**
      * Get package statistics including the code, data and cache size for
      * an already installed package
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4f185e6..d43ff4e 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5867,15 +5867,6 @@
         public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
 
         /**
-         * Names of the service component that the current user has explicitly allowed to
-         * see and change the importance of all of the user's notifications.
-         *
-         * @hide
-         */
-        public static final String ENABLED_NOTIFICATION_ASSISTANT
-                = "enabled_notification_assistant";
-
-        /**
          * Names of the service components that the current user has explicitly allowed to
          * see all of the user's notifications, separated by ':'.
          *
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index a0de17f..8c35901 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -23,7 +23,7 @@
 /** @hide */
 oneway interface INotificationListener
 {
-    // listeners and assistants
+    // listeners and rankers
     void onListenerConnected(in NotificationRankingUpdate update);
     void onNotificationPosted(in IStatusBarNotificationHolder notificationHolder,
             in NotificationRankingUpdate update);
@@ -33,7 +33,7 @@
     void onListenerHintsChanged(int hints);
     void onInterruptionFilterChanged(int interruptionFilter);
 
-    // assistants only
+    // rankers only
     void onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder, int importance, boolean user);
     void onNotificationVisibilityChanged(String key, long time, boolean visible);
     void onNotificationClick(String key, long time);
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index b8f9812..a8b8da1 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -170,13 +170,18 @@
 
     private INotificationManager mNoMan;
 
-    /** Only valid after a successful call to (@link registerAsService}. */
-    private int mCurrentUser;
+    /**
+     * Only valid after a successful call to (@link registerAsService}.
+     * @hide
+     */
+    protected int mCurrentUser;
 
-
-    // This context is required for system services since NotificationListenerService isn't
-    // started as a real Service and hence no context is available.
-    private Context mSystemContext;
+    /**
+     * This context is required for system services since NotificationListenerService isn't
+     * started as a real Service and hence no context is available..
+     * @hide
+     */
+    protected Context mSystemContext;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -675,12 +680,18 @@
     @SystemApi
     public void registerAsSystemService(Context context, ComponentName componentName,
             int currentUser) throws RemoteException {
+        registerAsSystemServiceImpl(context, componentName, currentUser, false /* asRanker */);
+    }
+
+    /** @hide */
+    protected void registerAsSystemServiceImpl(Context context, ComponentName componentName,
+            int currentUser, boolean asRanker) throws RemoteException {
         mSystemContext = context;
         if (mWrapper == null) {
             mWrapper = new NotificationListenerWrapper();
         }
         INotificationManager noMan = getNotificationInterface();
-        noMan.registerListener(mWrapper, componentName, currentUser);
+        noMan.registerListener(mWrapper, componentName, currentUser, asRanker);
         mCurrentUser = currentUser;
         mHandler = new MyHandler(context.getMainLooper());
     }
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationRankerService.java
similarity index 90%
rename from core/java/android/service/notification/NotificationAssistantService.java
rename to core/java/android/service/notification/NotificationRankerService.java
index 41af837..520b4c2 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationRankerService.java
@@ -31,31 +31,20 @@
 import com.android.internal.os.SomeArgs;
 
 /**
- * A service that helps the user manage notifications by modifying the
- * relative importance of notifications.
- * <p>To extend this class, you must declare the service in your manifest file with
- * the {@link android.Manifest.permission#BIND_NOTIFICATION_ASSISTANT_SERVICE} permission
- * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
- * <pre>
- * &lt;service android:name=".NotificationAssistant"
- *          android:label="&#64;string/service_name"
- *          android:permission="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE">
- *     &lt;intent-filter>
- *         &lt;action android:name="android.service.notification.NotificationAssistantService" />
- *     &lt;/intent-filter>
- * &lt;/service></pre>
+ * A service that helps the user manage notifications. This class is only used to
+ * extend the framework service and may not be implemented by non-framework components.
  * @hide
  */
 @SystemApi
-public abstract class NotificationAssistantService extends NotificationListenerService {
-    private static final String TAG = "NotificationAssistant";
+public abstract class NotificationRankerService extends NotificationListenerService {
+    private static final String TAG = "NotificationRanker";
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
      */
     @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
     public static final String SERVICE_INTERFACE
-            = "android.service.notification.NotificationAssistantService";
+            = "android.service.notification.NotificationRankerService";
 
     /** Notification was canceled by the status bar reporting a click. */
     public static final int REASON_DELEGATE_CLICK = 1;
@@ -130,7 +119,7 @@
     @Override
     public void registerAsSystemService(Context context, ComponentName componentName,
             int currentUser) throws RemoteException {
-        super.registerAsSystemService(context, componentName, currentUser);
+        registerAsSystemServiceImpl(context, componentName, currentUser, true /* as Ranker */);
         mHandler = new MyHandler(getContext().getMainLooper());
     }
 
@@ -143,7 +132,7 @@
     @Override
     public final IBinder onBind(Intent intent) {
         if (mWrapper == null) {
-            mWrapper = new NotificationAssistantWrapper();
+            mWrapper = new NotificationRankingServiceWrapper();
         }
         return mWrapper;
     }
@@ -216,14 +205,14 @@
     public final void adjustImportance(String key, Adjustment adjustment) {
         if (!isBound()) return;
         try {
-            getNotificationInterface().setImportanceFromAssistant(mWrapper, key,
+            getNotificationInterface().setImportanceFromRankerService(mWrapper, key,
                     adjustment.mImportance, adjustment.mExplanation);
         } catch (android.os.RemoteException ex) {
             Log.v(TAG, "Unable to contact notification manager", ex);
         }
     }
 
-    private class NotificationAssistantWrapper extends NotificationListenerWrapper {
+    private class NotificationRankingServiceWrapper extends NotificationListenerWrapper {
         @Override
         public void onNotificationEnqueued(IStatusBarNotificationHolder sbnHolder,
                 int importance, boolean user) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 451669b..fbc96c2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2774,12 +2774,11 @@
         android:protectionLevel="signature" />
 
     <!-- Must be required by an {@link
-         android.service.notification.NotificationAssistantService},
-         to ensure that only the system can bind to it.
+         android.service.notification.NotificationRankerService         to ensure that only the system can bind to it.
          <p>Protection level: signature
          @hide This is not a third-party API (intended for system apps). -->
     -->
-    <permission android:name="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"
+    <permission android:name="android.permission.BIND_NOTIFICATION_RANKER_SERVICE"
         android:protectionLevel="signature" />
 
     <!-- Must be required by a {@link
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a99ee92..1d7034d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3138,7 +3138,7 @@
     <string name="condition_provider_service_binding_label">Condition provider</string>
     <!-- Label to show for a service that is running because it is observing and modifying the
          importance of the user's notifications. -->
-    <string name="notification_assistant_binding_label">Notification assistant</string>
+    <string name="notification_ranker_binding_label">Notification ranker service</string>
 
     <!-- Do Not Translate: Alternate eri.xml -->
     <string name="alternate_eri_file">/data/eri.xml</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0934c3b..0120128 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1844,7 +1844,7 @@
   <java-symbol type="string" name="notification_listener_binding_label" />
   <java-symbol type="string" name="vr_listener_binding_label" />
   <java-symbol type="string" name="condition_provider_service_binding_label" />
-  <java-symbol type="string" name="notification_assistant_binding_label" />
+  <java-symbol type="string" name="notification_ranker_binding_label" />
   <java-symbol type="string" name="report" />
   <java-symbol type="string" name="select_input_method" />
   <java-symbol type="string" name="select_keyboard_layout_notification_title" />
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 881e8f0..24ffe1f 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,21 +16,21 @@
 
 package com.android.server.notification;
 
-import static android.service.notification.NotificationAssistantService.REASON_APP_CANCEL;
-import static android.service.notification.NotificationAssistantService.REASON_APP_CANCEL_ALL;
-import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_CANCEL;
-import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_CANCEL_ALL;
-import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_CLICK;
-import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_ERROR;
-import static android.service.notification.NotificationAssistantService.REASON_GROUP_OPTIMIZATION;
-import static android.service.notification.NotificationAssistantService.REASON_GROUP_SUMMARY_CANCELED;
-import static android.service.notification.NotificationAssistantService.REASON_LISTENER_CANCEL;
-import static android.service.notification.NotificationAssistantService.REASON_LISTENER_CANCEL_ALL;
-import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_BANNED;
-import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_CHANGED;
-import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_SUSPENDED;
-import static android.service.notification.NotificationAssistantService.REASON_PROFILE_TURNED_OFF;
-import static android.service.notification.NotificationAssistantService.REASON_USER_STOPPED;
+import static android.service.notification.NotificationRankerService.REASON_APP_CANCEL;
+import static android.service.notification.NotificationRankerService.REASON_APP_CANCEL_ALL;
+import static android.service.notification.NotificationRankerService.REASON_DELEGATE_CANCEL;
+import static android.service.notification.NotificationRankerService.REASON_DELEGATE_CANCEL_ALL;
+import static android.service.notification.NotificationRankerService.REASON_DELEGATE_CLICK;
+import static android.service.notification.NotificationRankerService.REASON_DELEGATE_ERROR;
+import static android.service.notification.NotificationRankerService.REASON_GROUP_OPTIMIZATION;
+import static android.service.notification.NotificationRankerService.REASON_GROUP_SUMMARY_CANCELED;
+import static android.service.notification.NotificationRankerService.REASON_LISTENER_CANCEL;
+import static android.service.notification.NotificationRankerService.REASON_LISTENER_CANCEL_ALL;
+import static android.service.notification.NotificationRankerService.REASON_PACKAGE_BANNED;
+import static android.service.notification.NotificationRankerService.REASON_PACKAGE_CHANGED;
+import static android.service.notification.NotificationRankerService.REASON_PACKAGE_SUSPENDED;
+import static android.service.notification.NotificationRankerService.REASON_PROFILE_TURNED_OFF;
+import static android.service.notification.NotificationRankerService.REASON_USER_STOPPED;
 import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
 import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF;
 import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON;
@@ -100,7 +100,7 @@
 import android.service.notification.IConditionProvider;
 import android.service.notification.INotificationListener;
 import android.service.notification.IStatusBarNotificationHolder;
-import android.service.notification.NotificationAssistantService;
+import android.service.notification.NotificationRankerService;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.StatusBarNotification;
@@ -224,8 +224,6 @@
     private WorkerHandler mHandler;
     private final HandlerThread mRankingThread = new HandlerThread("ranker",
             Process.THREAD_PRIORITY_BACKGROUND);
-    private final HandlerThread mAssistantThread = new HandlerThread("assistant",
-            Process.THREAD_PRIORITY_BACKGROUND);
 
     private Light mNotificationLight;
     Light mAttentionLight;
@@ -291,14 +289,13 @@
 
     private final UserProfiles mUserProfiles = new UserProfiles();
     private NotificationListeners mListeners;
-    private NotificationAssistant mAssistant;
+    private NotificationRanker mRankerServices;
     private ConditionProviders mConditionProviders;
     private NotificationUsageStats mUsageStats;
 
     private static final int MY_UID = Process.myUid();
     private static final int MY_PID = Process.myPid();
     private RankingHandler mRankingHandler;
-    private Handler mAssistantHandler;
 
     private static class Archive {
         final int mBufferSize;
@@ -756,7 +753,7 @@
                     }
                 }
                 mListeners.onPackagesChanged(queryReplace, pkgList);
-                mAssistant.onPackagesChanged(queryReplace, pkgList);
+                mRankerServices.onPackagesChanged(queryReplace, pkgList);
                 mConditionProviders.onPackagesChanged(queryReplace, pkgList);
                 mRankingHelper.onPackagesChanged(queryReplace, pkgList);
             }
@@ -805,7 +802,7 @@
                 // Refresh managed services
                 mConditionProviders.onUserSwitched(user);
                 mListeners.onUserSwitched(user);
-                mAssistant.onUserSwitched(user);
+                mRankerServices.onUserSwitched(user);
                 mZenModeHelper.onUserSwitched(user);
             } else if (action.equals(Intent.ACTION_USER_ADDED)) {
                 mUserProfiles.updateCache(context);
@@ -816,7 +813,7 @@
                 final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                 mConditionProviders.onUserUnlocked(user);
                 mListeners.onUserUnlocked(user);
-                mAssistant.onUserUnlocked(user);
+                mRankerServices.onUserUnlocked(user);
                 mZenModeHelper.onUserUnlocked(user);
             }
         }
@@ -892,7 +889,6 @@
 
         mHandler = new WorkerHandler();
         mRankingThread.start();
-        mAssistantThread.start();
         String[] extractorNames;
         try {
             extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
@@ -901,7 +897,6 @@
         }
         mUsageStats = new NotificationUsageStats(getContext());
         mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper());
-        mAssistantHandler = new Handler(mAssistantThread.getLooper());
         mRankingHelper = new RankingHelper(getContext(),
                 mRankingHandler,
                 mUsageStats,
@@ -937,7 +932,7 @@
         importOldBlockDb();
 
         mListeners = new NotificationListeners();
-        mAssistant = new NotificationAssistant();
+        mRankerServices = new NotificationRanker();
         mStatusBar = getLocalService(StatusBarManagerInternal.class);
         mStatusBar.setNotificationDelegate(mNotificationDelegate);
 
@@ -1060,7 +1055,7 @@
             // bind to listener services.
             mSettingsObserver.observe();
             mListeners.onBootPhaseAppsCanStart();
-            mAssistant.onBootPhaseAppsCanStart();
+            mRankerServices.onBootPhaseAppsCanStart();
             mConditionProviders.onBootPhaseAppsCanStart();
         }
     }
@@ -1415,17 +1410,30 @@
          */
         @Override
         public void registerListener(final INotificationListener listener,
-                final ComponentName component, final int userid) {
+                final ComponentName component, final int userid, boolean asRanker) {
             enforceSystemOrSystemUI("INotificationManager.registerListener");
-            mListeners.registerService(listener, component, userid);
+            if (asRanker) {
+                mRankerServices.registerService(listener, component, userid);
+            } else {
+                mListeners.registerService(listener, component, userid);
+            }
         }
 
         /**
          * Remove a listener binder directly
          */
         @Override
-        public void unregisterListener(INotificationListener listener, int userid) {
-            mListeners.unregisterService(listener, userid);
+        public void unregisterListener(INotificationListener token, int userid) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                if(mRankerServices.checkServiceTokenLocked(token) != null) {
+                    mRankerServices.unregisterService(token, userid);
+                } else {
+                    mListeners.unregisterService(token, userid);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
         }
 
         /**
@@ -1478,8 +1486,8 @@
             checkCallerIsSystemOrSameApp(component.getPackageName());
             long identity = Binder.clearCallingIdentity();
             try {
-                ManagedServices manager = mAssistant.isComponentEnabledForCurrentProfiles(component)
-                        ? mAssistant
+                ManagedServices manager = mRankerServices.isComponentEnabledForCurrentProfiles(component)
+                        ? mRankerServices
                         : mListeners;
                 manager.setComponentState(component, true);
             } finally {
@@ -1972,7 +1980,7 @@
         }
 
         @Override
-        public void setImportanceFromAssistant(INotificationListener token, String key,
+        public void setImportanceFromRankerService(INotificationListener token, String key,
                 int importance, CharSequence explanation) throws RemoteException {
             if (importance == IMPORTANCE_NONE) {
                 throw new IllegalArgumentException("blocking not allowed: key=" + key);
@@ -1980,7 +1988,7 @@
             final long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mNotificationList) {
-                    mAssistant.checkServiceTokenLocked(token);
+                    mRankerServices.checkServiceTokenLocked(token);
                     NotificationRecord n = mNotificationsByKey.get(key);
                     n.setImportance(importance, explanation);
                     mRankingHandler.requestSort();
@@ -2130,8 +2138,8 @@
                     pw.print(listener.component);
                 }
                 pw.println(')');
-                pw.println("\n  Notification assistant:");
-                mAssistant.dump(pw, filter);
+                pw.println("\n  Notification ranker services:");
+                mRankerServices.dump(pw, filter);
             }
             pw.println("\n  Policy access:");
             pw.print("    mPolicyAccess: "); pw.println(mPolicyAccess);
@@ -2358,9 +2366,9 @@
                     }
                 }
 
-                // tell the assistant about the notification
-                if (mAssistant.isEnabled()) {
-                    mAssistant.onNotificationEnqueued(r);
+                // tell the ranker service about the notification
+                if (mRankerServices.isEnabled()) {
+                    mRankerServices.onNotificationEnqueued(r);
                     // TODO delay the code below here for 100ms or until there is an answer
                 }
 
@@ -3477,21 +3485,21 @@
         }
     }
 
-    public class NotificationAssistant extends ManagedServices {
+    public class NotificationRanker extends ManagedServices {
 
-        public NotificationAssistant() {
+        public NotificationRanker() {
             super(getContext(), mHandler, mNotificationList, mUserProfiles);
         }
 
         @Override
         protected Config getConfig() {
             Config c = new Config();
-            c.caption = "notification assistant";
-            c.serviceInterface = NotificationAssistantService.SERVICE_INTERFACE;
-            c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT;
-            c.bindPermission = Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE;
+            c.caption = "notification ranker service";
+            c.serviceInterface = NotificationRankerService.SERVICE_INTERFACE;
+            c.secureSettingName = null;
+            c.bindPermission = Manifest.permission.BIND_NOTIFICATION_RANKER_SERVICE;
             c.settingsAction = Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS;
-            c.clientLabel = R.string.notification_assistant_binding_label;
+            c.clientLabel = R.string.notification_ranker_binding_label;
             return c;
         }
 
@@ -3519,10 +3527,10 @@
             final StatusBarNotification sbn = r.sbn;
             TrimCache trimCache = new TrimCache(sbn);
 
-            // mServices is the list inside ManagedServices of all the assistants,
+            // mServices is the list inside ManagedServices of all the rankers,
             // There should be only one, but it's a list, so while we enforce
             // singularity elsewhere, we keep it general here, to avoid surprises.
-            for (final ManagedServiceInfo info : NotificationAssistant.this.mServices) {
+            for (final ManagedServiceInfo info : NotificationRanker.this.mServices) {
                 boolean sbnVisible = isVisibleToListener(sbn, info);
                 if (!sbnVisible) {
                     continue;
@@ -3531,7 +3539,7 @@
                 final int importance = r.getImportance();
                 final boolean fromUser = r.isImportanceFromUser();
                 final StatusBarNotification sbnToPost =  trimCache.ForListener(info);
-                mAssistantHandler.post(new Runnable() {
+                mHandler.post(new Runnable() {
                     @Override
                     public void run() {
                         notifyEnqueued(info, sbnToPost, importance, fromUser);
@@ -3542,12 +3550,12 @@
 
         private void notifyEnqueued(final ManagedServiceInfo info,
                 final StatusBarNotification sbn, int importance, boolean fromUser) {
-            final INotificationListener assistant = (INotificationListener) info.service;
+            final INotificationListener ranker = (INotificationListener) info.service;
             StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
             try {
-                assistant.onNotificationEnqueued(sbnHolder, importance, fromUser);
+                ranker.onNotificationEnqueued(sbnHolder, importance, fromUser);
             } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+                Log.e(TAG, "unable to notify ranker (enqueued): " + ranker, ex);
             }
         }
 
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 93dcc72..206a143 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -166,6 +166,10 @@
         mInstaller.execute("rmpackagedir", packageDir);
     }
 
+    public void rmProfiles(String pkgName) throws InstallerException {
+        mInstaller.execute("rmprofiles", pkgName);
+    }
+
     public void createUserConfig(int userid) throws InstallerException {
         mInstaller.execute("mkuserconfig", userid);
     }
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index c9613b4..561682c 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -191,7 +191,6 @@
                         throw new IllegalStateException("Invalid dexopt:" + dexoptNeeded);
                 }
 
-
                 Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
                         + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
                         + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8d4c9e5..e180e050 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4443,6 +4443,13 @@
     }
 
     @Override
+    public List<String> getAllPackages() {
+        synchronized (mPackages) {
+            return new ArrayList<String>(mPackages.keySet());
+        }
+    }
+
+    @Override
     public String[] getPackagesForUid(int uid) {
         uid = UserHandle.getAppId(uid);
         // reader
@@ -15147,6 +15154,16 @@
     }
 
     @Override
+    public void clearApplicationProfileData(String packageName) {
+        enforceSystemOrRoot("Only the system can clear all profile data");
+        try {
+            mInstaller.rmProfiles(packageName);
+        } catch (InstallerException ex) {
+            Log.e(TAG, "Could not clear profile data of package " + packageName);
+        }
+    }
+
+    @Override
     public void clearApplicationUserData(final String packageName,
             final IPackageDataObserver observer, final int userId) {
         mContext.enforceCallingOrSelfPermission(
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index ccbd823..a2af7d9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -233,17 +233,30 @@
         boolean useJitProfiles = false;
         boolean extractOnly = false;
         boolean forceCompilation = false;
+        boolean allPackages = false;
+        boolean clearProfileData = false;
         String compilationMode = "default";
 
         String opt;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
-                case "-m":
-                    compilationMode = getNextArgRequired();
+                case "-a":
+                    allPackages = true;
+                    break;
+                case "-c":
+                    clearProfileData = true;
                     break;
                 case "-f":
                     forceCompilation = true;
                     break;
+                case "-m":
+                    compilationMode = getNextArgRequired();
+                    break;
+                case "--reset":
+                    forceCompilation = true;
+                    clearProfileData = true;
+                    compilationMode = "extract";
+                    break;
                 default:
                     pw.println("Error: Unknown option: " + opt);
                     return 1;
@@ -272,19 +285,49 @@
                 return 1;
         }
 
-        String packageName = getNextArg();
-        if (packageName == null) {
-            pw.println("Error: package name not specified");
-            return 1;
+        List<String> packageNames = null;
+        if (allPackages) {
+            packageNames = mInterface.getAllPackages();
+        } else {
+            String packageName = getNextArg();
+            if (packageName == null) {
+                pw.println("Error: package name not specified");
+                return 1;
+            }
+            packageNames = Collections.singletonList(packageName);
         }
 
-        boolean success = mInterface.performDexOpt(packageName, null /* instructionSet */,
-                useJitProfiles, extractOnly, forceCompilation);
-        if (success) {
+        List<String> failedPackages = new ArrayList<>();
+        for (String packageName : packageNames) {
+            if (clearProfileData) {
+                mInterface.clearApplicationProfileData(packageName);
+            }
+
+            boolean result = mInterface.performDexOpt(packageName, null /* instructionSet */,
+                        useJitProfiles, extractOnly, forceCompilation);
+            if (!result) {
+                failedPackages.add(packageName);
+            }
+        }
+
+        if (failedPackages.isEmpty()) {
             pw.println("Success");
             return 0;
+        } else if (failedPackages.size() == 1) {
+            pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
+            return 1;
         } else {
-            pw.println("Failure: package " + packageName + " could not be compiled");
+            pw.print("Failure: the following packages could not be compiled: ");
+            boolean is_first = true;
+            for (String packageName : failedPackages) {
+                if (is_first) {
+                    is_first = false;
+                } else {
+                    pw.print(", ");
+                }
+                pw.print(packageName);
+            }
+            pw.println();
             return 1;
         }
     }
@@ -1135,12 +1178,16 @@
         pw.println("  help");
         pw.println("    Print this help text.");
         pw.println("");
-        pw.println("  compile [-m MODE] [-f] TARGET-PACKAGE");
-        pw.println("    Trigger compilation of TARGET-PACKAGE.");
+        pw.println("  compile [-m MODE] [-f] (-a | TARGET-PACKAGE)");
+        pw.println("    Trigger compilation of TARGET-PACKAGE or all packages if \"-a\".");
         pw.println("    Options:");
+        pw.println("      -a: compile all packages");
+        pw.println("      -c: clear profile data before compiling");
+        pw.println("      -f: force compilation even if not needed");
         pw.println("      -m: select compilation mode");
         pw.println("          MODE can be one of \"default\", \"all\", \"profile\", and \"extract\"");
-        pw.println("      -f: force compilation even if not needed");
+        pw.println("      --reset: restore the package to post-install state");
+        pw.println("          shorthand for \"-c -f -m extract\"");
         pw.println("  list features");
         pw.println("    Prints all features of the system.");
         pw.println("  list instrumentation [-f] [TARGET-PACKAGE]");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index d1fd56a..c7ae6fc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -168,8 +168,8 @@
         RTL_ATTRS.put("?android:attr/paddingRight", "paddingEnd");
         RTL_ATTRS.put("?android:attr/layout_marginLeft", "layout_marginStart");
         RTL_ATTRS.put("?android:attr/layout_marginRight", "layout_marginEnd");
-        RTL_ATTRS.put("?android:attr/layout_toLeft", "layout_toStartOf");
-        RTL_ATTRS.put("?android:attr/layout_toRight", "layout_toEndOf");
+        RTL_ATTRS.put("?android:attr/layout_toLeftOf", "layout_toStartOf");
+        RTL_ATTRS.put("?android:attr/layout_toRightOf", "layout_toEndOf");
         RTL_ATTRS.put("?android:attr/layout_alignParentLeft", "layout_alignParentStart");
         RTL_ATTRS.put("?android:attr/layout_alignParentRight", "layout_alignParentEnd");
         RTL_ATTRS.put("?android:attr/drawableLeft", "drawableStart");