Merge "Import translations. DO NOT MERGE" into nyc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 375250c..ae6a8bc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -40272,7 +40272,10 @@
     method public boolean equals(android.util.DisplayMetrics);
     method public void setTo(android.util.DisplayMetrics);
     method public void setToDefaults();
+    field public static final int DENSITY_260 = 260; // 0x104
     field public static final int DENSITY_280 = 280; // 0x118
+    field public static final int DENSITY_300 = 300; // 0x12c
+    field public static final int DENSITY_340 = 340; // 0x154
     field public static final int DENSITY_360 = 360; // 0x168
     field public static final int DENSITY_400 = 400; // 0x190
     field public static final int DENSITY_420 = 420; // 0x1a4
diff --git a/api/system-current.txt b/api/system-current.txt
index 49dd103..15e8673 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -39334,14 +39334,16 @@
   }
 
   public class ParcelableCallAnalytics implements android.os.Parcelable {
-    ctor public ParcelableCallAnalytics(long, long, int, boolean, boolean, int, int, boolean, java.lang.String, boolean);
+    ctor public ParcelableCallAnalytics(long, long, int, boolean, boolean, int, int, boolean, java.lang.String, boolean, java.util.List<android.telecom.ParcelableCallAnalytics.AnalyticsEvent>, java.util.List<android.telecom.ParcelableCallAnalytics.EventTiming>);
     ctor public ParcelableCallAnalytics(android.os.Parcel);
+    method public java.util.List<android.telecom.ParcelableCallAnalytics.AnalyticsEvent> analyticsEvents();
     method public int describeContents();
     method public long getCallDurationMillis();
     method public int getCallTechnologies();
     method public int getCallTerminationCode();
     method public int getCallType();
     method public java.lang.String getConnectionService();
+    method public java.util.List<android.telecom.ParcelableCallAnalytics.EventTiming> getEventTimings();
     method public long getStartTimeMillis();
     method public boolean isAdditionalCall();
     method public boolean isCreatedFromExistingConnection();
@@ -39362,6 +39364,73 @@
     field public static final int THIRD_PARTY_PHONE = 16; // 0x10
   }
 
+  public static final class ParcelableCallAnalytics.AnalyticsEvent implements android.os.Parcelable {
+    ctor public ParcelableCallAnalytics.AnalyticsEvent(int, long);
+    method public int describeContents();
+    method public int getEventName();
+    method public long getTimeSinceLastEvent();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int AUDIO_ROUTE_BT = 204; // 0xcc
+    field public static final int AUDIO_ROUTE_EARPIECE = 205; // 0xcd
+    field public static final int AUDIO_ROUTE_HEADSET = 206; // 0xce
+    field public static final int AUDIO_ROUTE_SPEAKER = 207; // 0xcf
+    field public static final int BIND_CS = 5; // 0x5
+    field public static final int BLOCK_CHECK_FINISHED = 105; // 0x69
+    field public static final int BLOCK_CHECK_INITIATED = 104; // 0x68
+    field public static final int CONFERENCE_WITH = 300; // 0x12c
+    field public static final android.os.Parcelable.Creator<android.telecom.ParcelableCallAnalytics.AnalyticsEvent> CREATOR;
+    field public static final int CS_BOUND = 6; // 0x6
+    field public static final int DIRECT_TO_VM_FINISHED = 103; // 0x67
+    field public static final int DIRECT_TO_VM_INITIATED = 102; // 0x66
+    field public static final int FILTERING_COMPLETED = 107; // 0x6b
+    field public static final int FILTERING_INITIATED = 106; // 0x6a
+    field public static final int FILTERING_TIMED_OUT = 108; // 0x6c
+    field public static final int MUTE = 202; // 0xca
+    field public static final int REMOTELY_HELD = 402; // 0x192
+    field public static final int REMOTELY_UNHELD = 403; // 0x193
+    field public static final int REQUEST_ACCEPT = 7; // 0x7
+    field public static final int REQUEST_HOLD = 400; // 0x190
+    field public static final int REQUEST_PULL = 500; // 0x1f4
+    field public static final int REQUEST_REJECT = 8; // 0x8
+    field public static final int REQUEST_UNHOLD = 401; // 0x191
+    field public static final int SCREENING_COMPLETED = 101; // 0x65
+    field public static final int SCREENING_SENT = 100; // 0x64
+    field public static final int SET_ACTIVE = 1; // 0x1
+    field public static final int SET_DIALING = 4; // 0x4
+    field public static final int SET_DISCONNECTED = 2; // 0x2
+    field public static final int SET_HOLD = 404; // 0x194
+    field public static final int SET_PARENT = 302; // 0x12e
+    field public static final int SET_SELECT_PHONE_ACCOUNT = 0; // 0x0
+    field public static final int SILENCE = 201; // 0xc9
+    field public static final int SKIP_RINGING = 200; // 0xc8
+    field public static final int SPLIT_CONFERENCE = 301; // 0x12d
+    field public static final int START_CONNECTION = 3; // 0x3
+    field public static final int SWAP = 405; // 0x195
+    field public static final int UNMUTE = 203; // 0xcb
+  }
+
+  public static final class ParcelableCallAnalytics.EventTiming implements android.os.Parcelable {
+    ctor public ParcelableCallAnalytics.EventTiming(int, long);
+    method public int describeContents();
+    method public int getName();
+    method public long getTime();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ACCEPT_TIMING = 0; // 0x0
+    field public static final int BIND_CS_TIMING = 6; // 0x6
+    field public static final int BLOCK_CHECK_FINISHED_TIMING = 9; // 0x9
+    field public static final android.os.Parcelable.Creator<android.telecom.ParcelableCallAnalytics.EventTiming> CREATOR;
+    field public static final int DIRECT_TO_VM_FINISHED_TIMING = 8; // 0x8
+    field public static final int DISCONNECT_TIMING = 2; // 0x2
+    field public static final int FILTERING_COMPLETED_TIMING = 10; // 0xa
+    field public static final int FILTERING_TIMED_OUT_TIMING = 11; // 0xb
+    field public static final int HOLD_TIMING = 3; // 0x3
+    field public static final int INVALID = 999999; // 0xf423f
+    field public static final int OUTGOING_TIME_TO_DIALING_TIMING = 5; // 0x5
+    field public static final int REJECT_TIMING = 1; // 0x1
+    field public static final int SCREENING_COMPLETED_TIMING = 7; // 0x7
+    field public static final int UNHOLD_TIMING = 4; // 0x4
+  }
+
   public final deprecated class Phone {
     method public final void addListener(android.telecom.Phone.Listener);
     method public final boolean canAddCall();
@@ -39578,6 +39647,41 @@
     field public static final android.os.Parcelable.Creator<android.telecom.StatusHints> CREATOR;
   }
 
+  public final class TelecomAnalytics implements android.os.Parcelable {
+    ctor public TelecomAnalytics(java.util.List<android.telecom.TelecomAnalytics.SessionTiming>, java.util.List<android.telecom.ParcelableCallAnalytics>);
+    method public int describeContents();
+    method public java.util.List<android.telecom.ParcelableCallAnalytics> getCallAnalytics();
+    method public java.util.List<android.telecom.TelecomAnalytics.SessionTiming> getSessionTimings();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telecom.TelecomAnalytics> CREATOR;
+  }
+
+  public static final class TelecomAnalytics.SessionTiming implements android.os.Parcelable {
+    ctor public TelecomAnalytics.SessionTiming(int, long);
+    method public int describeContents();
+    method public java.lang.Integer getKey();
+    method public long getTime();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telecom.TelecomAnalytics.SessionTiming> CREATOR;
+    field public static final int CSW_ADD_CONFERENCE_CALL = 108; // 0x6c
+    field public static final int CSW_HANDLE_CREATE_CONNECTION_COMPLETE = 100; // 0x64
+    field public static final int CSW_REMOVE_CALL = 106; // 0x6a
+    field public static final int CSW_SET_ACTIVE = 101; // 0x65
+    field public static final int CSW_SET_DIALING = 103; // 0x67
+    field public static final int CSW_SET_DISCONNECTED = 104; // 0x68
+    field public static final int CSW_SET_IS_CONFERENCED = 107; // 0x6b
+    field public static final int CSW_SET_ON_HOLD = 105; // 0x69
+    field public static final int CSW_SET_RINGING = 102; // 0x66
+    field public static final int ICA_ANSWER_CALL = 1; // 0x1
+    field public static final int ICA_CONFERENCE = 8; // 0x8
+    field public static final int ICA_DISCONNECT_CALL = 3; // 0x3
+    field public static final int ICA_HOLD_CALL = 4; // 0x4
+    field public static final int ICA_MUTE = 6; // 0x6
+    field public static final int ICA_REJECT_CALL = 2; // 0x2
+    field public static final int ICA_SET_AUDIO_ROUTE = 7; // 0x7
+    field public static final int ICA_UNHOLD_CALL = 5; // 0x5
+  }
+
   public class TelecomManager {
     method public void acceptRingingCall();
     method public void acceptRingingCall(int);
@@ -39587,7 +39691,7 @@
     method public deprecated void clearAccounts();
     method public void clearPhoneAccounts();
     method public android.content.Intent createManageBlockedNumbersIntent();
-    method public java.util.List<android.telecom.ParcelableCallAnalytics> dumpAnalytics();
+    method public android.telecom.TelecomAnalytics dumpAnalytics();
     method public void enablePhoneAccount(android.telecom.PhoneAccountHandle, boolean);
     method public boolean endCall();
     method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle);
@@ -43272,7 +43376,10 @@
     method public boolean equals(android.util.DisplayMetrics);
     method public void setTo(android.util.DisplayMetrics);
     method public void setToDefaults();
+    field public static final int DENSITY_260 = 260; // 0x104
     field public static final int DENSITY_280 = 280; // 0x118
+    field public static final int DENSITY_300 = 300; // 0x12c
+    field public static final int DENSITY_340 = 340; // 0x154
     field public static final int DENSITY_360 = 360; // 0x168
     field public static final int DENSITY_400 = 400; // 0x190
     field public static final int DENSITY_420 = 420; // 0x1a4
diff --git a/api/test-current.txt b/api/test-current.txt
index 227f161..4bb7a79 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -40352,7 +40352,10 @@
     method public boolean equals(android.util.DisplayMetrics);
     method public void setTo(android.util.DisplayMetrics);
     method public void setToDefaults();
+    field public static final int DENSITY_260 = 260; // 0x104
     field public static final int DENSITY_280 = 280; // 0x118
+    field public static final int DENSITY_300 = 300; // 0x12c
+    field public static final int DENSITY_340 = 340; // 0x154
     field public static final int DENSITY_360 = 360; // 0x168
     field public static final int DENSITY_400 = 400; // 0x190
     field public static final int DENSITY_420 = 420; // 0x1a4
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index a4688d1..f56a6ad 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -274,7 +274,7 @@
                 if (libDir.endsWith(".apk")) {
                     // Avoid opening files we know do not have resources,
                     // like code-only .jar files.
-                    if (assets.addAssetPath(libDir) == 0) {
+                    if (assets.addAssetPathAsSharedLibrary(libDir) == 0) {
                         Log.w(TAG, "Asset path '" + libDir +
                                 "' does not exist or contains no resources.");
                     }
@@ -330,6 +330,22 @@
     }
 
     /**
+     * Finds a cached ResourcesImpl object that matches the given ResourcesKey, or
+     * creates a new one and caches it for future use.
+     * @param key The key to match.
+     * @return a ResourcesImpl object matching the key.
+     */
+    private @NonNull ResourcesImpl findOrCreateResourcesImplForKeyLocked(
+            @NonNull ResourcesKey key) {
+        ResourcesImpl impl = findResourcesImplForKeyLocked(key);
+        if (impl == null) {
+            impl = createResourcesImpl(key);
+            mResourceImpls.put(key, new WeakReference<>(impl));
+        }
+        return impl;
+    }
+
+    /**
      * Find the ResourcesKey that this ResourcesImpl object is associated with.
      * @return the ResourcesKey or null if none was found.
      */
@@ -811,4 +827,75 @@
             Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
         }
     }
+
+    /**
+     * Appends the library asset path to any ResourcesImpl object that contains the main
+     * assetPath.
+     * @param assetPath The main asset path for which to add the library asset path.
+     * @param libAsset The library asset path to add.
+     */
+    public void appendLibAssetForMainAssetPath(String assetPath, String libAsset) {
+        synchronized (this) {
+            // Record which ResourcesImpl need updating
+            // (and what ResourcesKey they should update to).
+            final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
+
+            final int implCount = mResourceImpls.size();
+            for (int i = 0; i < implCount; i++) {
+                final ResourcesImpl impl = mResourceImpls.valueAt(i).get();
+                final ResourcesKey key = mResourceImpls.keyAt(i);
+                if (impl != null && key.mResDir.equals(assetPath)) {
+                    if (!ArrayUtils.contains(key.mLibDirs, libAsset)) {
+                        final int newLibAssetCount = 1 +
+                                (key.mLibDirs != null ? key.mLibDirs.length : 0);
+                        final String[] newLibAssets = new String[newLibAssetCount];
+                        if (key.mLibDirs != null) {
+                            System.arraycopy(key.mLibDirs, 0, newLibAssets, 0, key.mLibDirs.length);
+                        }
+                        newLibAssets[newLibAssetCount - 1] = libAsset;
+
+                        updatedResourceKeys.put(impl, new ResourcesKey(
+                                key.mResDir,
+                                key.mSplitResDirs,
+                                key.mOverlayDirs,
+                                newLibAssets,
+                                key.mDisplayId,
+                                key.mOverrideConfiguration,
+                                key.mCompatInfo));
+                    }
+                }
+            }
+
+            // Bail early if there is no work to do.
+            if (updatedResourceKeys.isEmpty()) {
+                return;
+            }
+
+            // Update any references to ResourcesImpl that require reloading.
+            final int resourcesCount = mResourceReferences.size();
+            for (int i = 0; i < resourcesCount; i++) {
+                final Resources r = mResourceReferences.get(i).get();
+                if (r != null) {
+                    final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
+                    if (key != null) {
+                        r.setImpl(findOrCreateResourcesImplForKeyLocked(key));
+                    }
+                }
+            }
+
+            // Update any references to ResourcesImpl that require reloading for each Activity.
+            for (ActivityResources activityResources : mActivityResourceReferences.values()) {
+                final int resCount = activityResources.activityResources.size();
+                for (int i = 0; i < resCount; i++) {
+                    final Resources r = activityResources.activityResources.get(i).get();
+                    if (r != null) {
+                        final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
+                        if (key != null) {
+                            r.setImpl(findOrCreateResourcesImplForKeyLocked(key));
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8b3eac5..ca798f6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3644,6 +3644,12 @@
     public static final String SYSTEM_HEALTH_SERVICE = "systemhealth";
 
     /**
+     * Gatekeeper Service.
+     * @hide
+     */
+    public static final String GATEKEEPER_SERVICE = "android.service.gatekeeper.IGateKeeperService";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 094b89d..896fa43 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -62,6 +62,13 @@
 
     private static final String ANDROID_PACKAGE_NAME = "android";
 
+    private static final int IMPLICIT_RANK_MASK = 0x7fffffff;
+
+    private static final int RANK_CHANGED_BIT = ~IMPLICIT_RANK_MASK;
+
+    /** @hide */
+    public static final int RANK_NOT_SET = Integer.MAX_VALUE;
+
     /** @hide */
     public static final int FLAG_DYNAMIC = 1 << 0;
 
@@ -193,6 +200,15 @@
 
     private int mRank;
 
+    /**
+     * Internally used for auto-rank-adjustment.
+     *
+     * RANK_CHANGED_BIT is used to denote that the rank of a shortcut is changing.
+     * The rest of the bits are used to denote the order in which shortcuts are passed to
+     * APIs, which is used to preserve the argument order when ranks are tie.
+     */
+    private int mImplicitRank;
+
     @Nullable
     private PersistableBundle mExtras;
 
@@ -544,7 +560,8 @@
 
     /**
      * Copy non-null/zero fields from another {@link ShortcutInfo}.  Only "public" information
-     * will be overwritten.  The timestamp will be updated.
+     * will be overwritten.  The timestamp will *not* be updated to be consistent with other
+     * setters (and also the clock is not injectable in this file).
      *
      * - Flags will not change
      * - mBitmapPath will not change
@@ -603,14 +620,12 @@
             mIntent = source.mIntent;
             mIntentPersistableExtras = source.mIntentPersistableExtras;
         }
-        if (source.mRank != 0) {
+        if (source.mRank != RANK_NOT_SET) {
             mRank = source.mRank;
         }
         if (source.mExtras != null) {
             mExtras = source.mExtras;
         }
-
-        updateTimestamp();
     }
 
     /**
@@ -665,7 +680,7 @@
 
         private Intent mIntent;
 
-        private int mRank;
+        private int mRank = RANK_NOT_SET;
 
         private PersistableBundle mExtras;
 
@@ -825,15 +840,18 @@
         @NonNull
         public Builder setIntent(@NonNull Intent intent) {
             mIntent = Preconditions.checkNotNull(intent, "intent");
-            Preconditions.checkNotNull(mIntent.getAction(), "Intent action must be set.");
+            Preconditions.checkNotNull(mIntent.getAction(), "Intent action must be set");
             return this;
         }
 
         /**
-         * TODO javadoc.
+         * "Rank" of a shortcut, which is a non-negative value that's used by the launcher app
+         * to sort shortcuts.
          */
         @NonNull
         public Builder setRank(int rank) {
+            Preconditions.checkArgument((0 <= rank),
+                    "Rank cannot be negative or bigger than MAX_RANK");
             mRank = rank;
             return this;
         }
@@ -1014,12 +1032,57 @@
     }
 
     /**
-     * TODO Javadoc
+     * "Rank" of a shortcut, which is a non-negative, sequential value that's unique for each
+     * {@link #getActivity} for each of the two kinds, dynamic shortcuts and manifest shortcuts.
+     *
+     * <p>Because manifest shortcuts and dynamic shortcuts have overlapping ranks,
+     * when a launcher application shows shortcuts for an activity, it should first show
+     * the manifest shortcuts followed by the dynamic shortcuts.  Within each of those categories,
+     * shortcuts should be sorted by rank in ascending order.
+     *
+     * <p>"Floating" shortcuts (i.e. shortcuts that are neither dynamic nor manifest) will all
+     * have rank 0, because there's no sorting for them.
      */
     public int getRank() {
         return mRank;
     }
 
+    /** @hide */
+    public boolean hasRank() {
+        return mRank != RANK_NOT_SET;
+    }
+
+    /** @hide */
+    public void setRank(int rank) {
+        mRank = rank;
+    }
+
+    /** @hide */
+    public void clearImplicitRankAndRankChangedFlag() {
+        mImplicitRank = 0;
+    }
+
+    /** @hide */
+    public void setImplicitRank(int rank) {
+        // Make sure to keep RANK_CHANGED_BIT.
+        mImplicitRank = (mImplicitRank & RANK_CHANGED_BIT) | (rank & IMPLICIT_RANK_MASK);
+    }
+
+    /** @hide */
+    public int getImplicitRank() {
+        return mImplicitRank & IMPLICIT_RANK_MASK;
+    }
+
+    /** @hide */
+    public void setRankChanged() {
+        mImplicitRank |= RANK_CHANGED_BIT;
+    }
+
+    /** @hide */
+    public boolean isRankChanged() {
+        return (mImplicitRank & RANK_CHANGED_BIT) != 0;
+    }
+
     /**
      * Optional values that application can set.
      */
diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java
index 8176189..43e596f 100644
--- a/core/java/android/hardware/location/ContextHubService.java
+++ b/core/java/android/hardware/location/ContextHubService.java
@@ -21,12 +21,15 @@
 import android.content.pm.PackageManager;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.vr.IVrManager;
+import android.service.vr.IVrStateCallbacks;
 import android.util.Log;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * @hide
@@ -57,8 +60,11 @@
 
     private static final int OS_APP_INSTANCE = -1;
 
+    private static final long APP_ID_ACTIVITY_RECOGNITION = 0x476f6f676c001000L;
+
     private final Context mContext;
-    private final HashMap<Integer, NanoAppInstanceInfo> mNanoAppHash = new HashMap<>();
+    private final ConcurrentHashMap<Integer, NanoAppInstanceInfo> mNanoAppHash =
+            new ConcurrentHashMap<>();
     private final ContextHubInfo[] mContextHubInfo;
     private final RemoteCallbackList<IContextHubCallback> mCallbacksList =
             new RemoteCallbackList<>();
@@ -66,6 +72,18 @@
     private native int nativeSendMessage(int[] header, byte[] data);
     private native ContextHubInfo[] nativeInitialize();
 
+    private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
+        @Override
+        public void onVrStateChanged(boolean enabled) {
+            for (NanoAppInstanceInfo app : mNanoAppHash.values()) {
+                if (app.getAppId() == APP_ID_ACTIVITY_RECOGNITION) {
+                    sendVrStateChangeMessageToApp(app, enabled);
+                    break;
+                }
+            }
+        }
+    };
+
     public ContextHubService(Context context) {
         mContext = context;
         mContextHubInfo = nativeInitialize();
@@ -74,6 +92,18 @@
             Log.d(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
                   + ", name:  " + mContextHubInfo[i].getName());
         }
+
+        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
+            IVrManager vrManager =
+                    IVrManager.Stub.asInterface(ServiceManager.getService("vrmanager"));
+            if (vrManager != null) {
+                try {
+                    vrManager.registerListener(mVrStateCallbacks);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "VR state listener registration failed", e);
+                }
+            }
+        }
     }
 
     @Override
@@ -277,4 +307,19 @@
 
         return 0;
     }
+
+    private void sendVrStateChangeMessageToApp(NanoAppInstanceInfo app, boolean vrModeEnabled) {
+        int[] msgHeader = new int[MSG_HEADER_SIZE];
+        msgHeader[MSG_FIELD_TYPE] = 0;
+        msgHeader[MSG_FIELD_VERSION] = 0;
+        msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB;
+        msgHeader[MSG_FIELD_APP_INSTANCE] = app.getHandle();
+
+        byte[] data = new byte[1];
+        data[0] = (byte) ((vrModeEnabled) ? 1 : 0);
+        int ret = nativeSendMessage(msgHeader, data);
+        if (ret != 0) {
+            Log.e(TAG, "Couldn't send VR state change notification (" + ret + ")!");
+        }
+    }
 }
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 6af0678..80927f3 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -240,6 +240,22 @@
         return new File(getDataDirectory(), "system");
     }
 
+    /**
+     * Returns the base directory for per-user system directory, device encrypted.
+     * {@hide}
+     */
+    public static File getDataSystemDeDirectory() {
+        return buildPath(getDataDirectory(), "system_de");
+    }
+
+    /**
+     * Returns the base directory for per-user system directory, credential encrypted.
+     * {@hide}
+     */
+    public static File getDataSystemCeDirectory() {
+        return buildPath(getDataDirectory(), "system_ce");
+    }
+
     /** {@hide} */
     public static File getDataSystemCeDirectory(int userId) {
         return buildPath(getDataDirectory(), "system_ce", String.valueOf(userId));
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index b3cc438..507379b 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -759,7 +759,7 @@
 
                 if (line.startsWith("time")) {
                     timeTotal = scaled;
-                } else if (line.startsWith("source_version")) {
+                } else if (line.startsWith("source_build")) {
                     sourceVersion = scaled;
                 } else if (line.startsWith("bytes_written")) {
                     bytesWrittenInMiB = (bytesWrittenInMiB == -1) ? scaled :
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9b0ef8e..d742206 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1508,7 +1508,9 @@
     }
 
     /**
-     * Returns information for all users on this device.
+     * Returns information for all users on this device, including ones marked for deletion.
+     * To retrieve only users that are alive, use {@link #getUsers(boolean)}.
+     * <p>
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @return the list of users that exist on the device.
      * @hide
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index d201ade..f4db4d6 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -66,9 +66,23 @@
      * {@link #DENSITY_XHIGH} (320dpi). This is not a density that applications should target,
      * instead relying on the system to scale their {@link #DENSITY_XHIGH} assets for them.
      */
+    public static final int DENSITY_260 = 260;
+
+    /**
+     * Intermediate density for screens that sit between {@link #DENSITY_HIGH} (240dpi) and
+     * {@link #DENSITY_XHIGH} (320dpi). This is not a density that applications should target,
+     * instead relying on the system to scale their {@link #DENSITY_XHIGH} assets for them.
+     */
     public static final int DENSITY_280 = 280;
 
     /**
+     * Intermediate density for screens that sit between {@link #DENSITY_HIGH} (240dpi) and
+     * {@link #DENSITY_XHIGH} (320dpi). This is not a density that applications should target,
+     * instead relying on the system to scale their {@link #DENSITY_XHIGH} assets for them.
+     */
+    public static final int DENSITY_300 = 300;
+
+    /**
      * Standard quantized DPI for extra-high-density screens.
      */
     public static final int DENSITY_XHIGH = 320;
@@ -79,6 +93,14 @@
      * This is not a density that applications should target, instead relying
      * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
      */
+    public static final int DENSITY_340 = 340;
+
+    /**
+     * Intermediate density for screens that sit somewhere between
+     * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
+     * This is not a density that applications should target, instead relying
+     * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
+     */
     public static final int DENSITY_360 = 360;
 
     /**
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 3069e5a..c46acae 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -22,6 +22,7 @@
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.util.AttributeSet;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ImageView;
@@ -63,6 +64,33 @@
             }
         }
     };
+    final AccessibilityDelegate mExpandDelegate = new AccessibilityDelegate() {
+
+        @Override
+        public boolean performAccessibilityAction(View host, int action, Bundle args) {
+            if (super.performAccessibilityAction(host, action, args)) {
+                return true;
+            }
+            if (action == AccessibilityNodeInfo.ACTION_COLLAPSE
+                    || action == AccessibilityNodeInfo.ACTION_EXPAND) {
+                mExpandClickListener.onClick(mExpandButton);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(host, info);
+            // Avoid that the button description is also spoken
+            info.setClassName(getClass().getName());
+            if (mExpanded) {
+                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
+            } else {
+                info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
+            }
+        }
+    };
 
     public NotificationHeaderView(Context context) {
         this(context, null);
@@ -92,6 +120,9 @@
         mAppName = findViewById(com.android.internal.R.id.app_name_text);
         mHeaderText = findViewById(com.android.internal.R.id.header_text);
         mExpandButton = (ImageView) findViewById(com.android.internal.R.id.expand_button);
+        if (mExpandButton != null) {
+            mExpandButton.setAccessibilityDelegate(mExpandDelegate);
+        }
         mIcon = findViewById(com.android.internal.R.id.icon);
         mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
     }
@@ -230,7 +261,7 @@
     public void setOnClickListener(@Nullable OnClickListener l) {
         mExpandClickListener = l;
         setOnTouchListener(mExpandClickListener != null ? mTouchListener : null);
-        setFocusable(l != null);
+        mExpandButton.setOnClickListener(mExpandClickListener);
         updateTouchListener();
     }
 
@@ -380,19 +411,6 @@
         return this;
     }
 
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        if (mExpandClickListener != null) {
-            AccessibilityNodeInfo.AccessibilityAction expand
-                    = new AccessibilityNodeInfo.AccessibilityAction(
-                    AccessibilityNodeInfo.ACTION_CLICK,
-                    getContext().getString(
-                            com.android.internal.R.string.expand_action_accessibility));
-            info.addAction(expand);
-        }
-    }
-
     public ImageView getExpandButton() {
         return mExpandButton;
     }
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index 9e73af2..2cdff79 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -21,7 +21,9 @@
 import android.annotation.SystemApi;
 import android.app.ActivityThread;
 import android.app.Application;
+import android.app.ResourcesManager;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.os.SystemProperties;
@@ -31,6 +33,8 @@
 import android.view.View;
 import android.view.ViewRootImpl;
 
+import com.android.internal.util.ArrayUtils;
+
 /**
  * Delegate used by the WebView provider implementation to access
  * the required framework functionality needed to implement a {@link WebView}.
@@ -177,7 +181,29 @@
      * Adds the WebView asset path to {@link android.content.res.AssetManager}.
      */
     public void addWebViewAssetPath(Context context) {
-        context.getAssets().addAssetPathAsSharedLibrary(
-                WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir);
+        final String newAssetPath = WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir;
+
+        final ApplicationInfo appInfo = context.getApplicationInfo();
+        final String[] libs = appInfo.sharedLibraryFiles;
+        if (!ArrayUtils.contains(libs, newAssetPath)) {
+            // Build the new library asset path list.
+            final int newLibAssetsCount = 1 + (libs != null ? libs.length : 0);
+            final String[] newLibAssets = new String[newLibAssetsCount];
+            if (libs != null) {
+                System.arraycopy(libs, 0, newLibAssets, 0, libs.length);
+            }
+            newLibAssets[newLibAssetsCount - 1] = newAssetPath;
+
+            // Update the ApplicationInfo object with the new list.
+            // We know this will persist and future Resources created via ResourcesManager
+            // will include the shared library because this ApplicationInfo comes from the
+            // underlying LoadedApk in ContextImpl, which does not change during the life of the
+            // application.
+            appInfo.sharedLibraryFiles = newLibAssets;
+
+            // Update existing Resources with the WebView library.
+            ResourcesManager.getInstance().appendLibAssetForMainAssetPath(
+                    appInfo.getBaseResourcePath(), newAssetPath);
+        }
     }
 }
diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java
index 04929a7..d0719ee 100644
--- a/core/java/com/android/internal/app/LocalePickerWithRegion.java
+++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java
@@ -45,6 +45,7 @@
  * default locale.</p>
  */
 public class LocalePickerWithRegion extends ListFragment implements SearchView.OnQueryTextListener {
+    private static final String PARENT_FRAGMENT_NAME = "localeListEditor";
 
     private SuggestedLocaleAdapter mAdapter;
     private LocaleSelectedListener mListener;
@@ -130,11 +131,24 @@
         return true;
     }
 
+    private void returnToParentFrame() {
+        getFragmentManager().popBackStack(PARENT_FRAGMENT_NAME,
+                FragmentManager.POP_BACK_STACK_INCLUSIVE);
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setHasOptionsMenu(true);
 
+        if (mLocaleList == null) {
+            // The fragment was killed and restored by the FragmentManager.
+            // At this point we have no data, no listener. Just return, to prevend a NPE.
+            // Fixes b/28748150. Created b/29400003 for a cleaner solution.
+            returnToParentFrame();
+            return;
+        }
+
         final boolean countryMode = mParentLocale != null;
         final Locale sortingLocale = countryMode ? mParentLocale.getLocale() : Locale.getDefault();
         mAdapter = new SuggestedLocaleAdapter(mLocaleList, countryMode);
@@ -197,8 +211,7 @@
             if (mListener != null) {
                 mListener.onLocaleSelected(locale);
             }
-            getFragmentManager().popBackStack("localeListEditor",
-                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
+            returnToParentFrame();
         } else {
             LocalePickerWithRegion selector = LocalePickerWithRegion.createCountryPicker(
                     getContext(), mListener, locale, mTranslatedOnly /* translate only */);
@@ -208,8 +221,7 @@
                         .replace(getId(), selector).addToBackStack(null)
                         .commit();
             } else {
-                getFragmentManager().popBackStack("localeListEditor",
-                        FragmentManager.POP_BACK_STACK_INCLUSIVE);
+                returnToParentFrame();
             }
         }
     }
diff --git a/core/java/com/android/internal/widget/NotificationExpandButton.java b/core/java/com/android/internal/widget/NotificationExpandButton.java
new file mode 100644
index 0000000..f4f49b1
--- /dev/null
+++ b/core/java/com/android/internal/widget/NotificationExpandButton.java
@@ -0,0 +1,62 @@
+/*
+ * 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.internal.widget;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+import android.widget.RemoteViews;
+
+/**
+ * An expand button in a notification
+ */
+@RemoteViews.RemoteView
+public class NotificationExpandButton extends ImageView {
+    public NotificationExpandButton(Context context) {
+        super(context);
+    }
+
+    public NotificationExpandButton(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NotificationExpandButton(Context context, @Nullable AttributeSet attrs,
+            int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public NotificationExpandButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
+        super.getBoundsOnScreen(outRect, clipToParent);
+        extendRectToMinTouchSize(outRect);
+    }
+
+    private void extendRectToMinTouchSize(Rect rect) {
+        int touchTargetSize = (int) (getResources().getDisplayMetrics().density * 48);
+        rect.left = rect.centerX() - touchTargetSize / 2;
+        rect.right = rect.left + touchTargetSize;
+        rect.top = rect.centerY() - touchTargetSize / 2;
+        rect.bottom = rect.top + touchTargetSize;
+    }
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 89036dd..3783dc8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -469,13 +469,6 @@
     <protected-broadcast android:name="android.net.wifi.PASSPOINT_ICON_RECEIVED" />
     <protected-broadcast android:name="com.android.server.notification.CountdownConditionProvider" />
 
-    <protected-broadcast android:name="com.android.ims.IMS_SERVICE_UP" />
-    <protected-broadcast android:name="com.android.ims.IMS_INCOMING_CALL" />
-    <protected-broadcast android:name="com.android.ims.internal.uce.UCE_SERVICE_UP" />
-    <protected-broadcast android:name="com.android.ims.internal.uce.UCE_SERVICE_DOWN" />
-    <protected-broadcast android:name="com.android.intent.action.IMS_FEATURE_CHANGED" />
-    <protected-broadcast android:name="com.android.intent.action.IMS_CONFIG_CHANGED" />
-
     <protected-broadcast android:name="com.android.internal.location.ALARM_WAKEUP" />
     <protected-broadcast android:name="com.android.internal.location.ALARM_TIMEOUT" />
     <protected-broadcast android:name="android.intent.action.GLOBAL_BUTTON" />
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 38ea92a..38f671c2 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -89,7 +89,7 @@
         android:layout="@layout/notification_template_part_chronometer"
         android:visibility="gone"
         />
-    <ImageView
+    <com.android.internal.widget.NotificationExpandButton
         android:id="@+id/expand_button"
         android:background="@null"
         android:layout_width="wrap_content"
diff --git a/core/res/res/values-af-watch/styles_material.xml b/core/res/res/values-af-watch/styles_material.xml
new file mode 100644
index 0000000..80a5fa6
--- /dev/null
+++ b/core/res/res/values-af-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidate"</font></string>
+</resources>
diff --git a/core/res/res/values-am-watch/styles_material.xml b/core/res/res/values-am-watch/styles_material.xml
new file mode 100644
index 0000000..5ec383a8
--- /dev/null
+++ b/core/res/res/values-am-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"እጩዎች"</font></string>
+</resources>
diff --git a/core/res/res/values-ar-watch/styles_material.xml b/core/res/res/values-ar-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-ar-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-az-rAZ-watch/styles_material.xml b/core/res/res/values-az-rAZ-watch/styles_material.xml
new file mode 100644
index 0000000..b621266
--- /dev/null
+++ b/core/res/res/values-az-rAZ-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"namizədlər"</font></string>
+</resources>
diff --git a/core/res/res/values-bg-watch/styles_material.xml b/core/res/res/values-bg-watch/styles_material.xml
new file mode 100644
index 0000000..89c3366
--- /dev/null
+++ b/core/res/res/values-bg-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"кандидати"</font></string>
+</resources>
diff --git a/core/res/res/values-bn-rBD-watch/styles_material.xml b/core/res/res/values-bn-rBD-watch/styles_material.xml
new file mode 100644
index 0000000..cd59902
--- /dev/null
+++ b/core/res/res/values-bn-rBD-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"প্রার্থীরা"</font></string>
+</resources>
diff --git a/core/res/res/values-ca-watch/styles_material.xml b/core/res/res/values-ca-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-ca-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-cs-watch/styles_material.xml b/core/res/res/values-cs-watch/styles_material.xml
new file mode 100644
index 0000000..5b604e8
--- /dev/null
+++ b/core/res/res/values-cs-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidáti"</font></string>
+</resources>
diff --git a/core/res/res/values-da-watch/styles_material.xml b/core/res/res/values-da-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-da-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-de-watch/styles_material.xml b/core/res/res/values-de-watch/styles_material.xml
new file mode 100644
index 0000000..891a647
--- /dev/null
+++ b/core/res/res/values-de-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"Kandidaten"</font></string>
+</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index dc30013..79a2dba 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -245,7 +245,7 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"auf deine Kontakte zugreifen"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Standort"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"auf den Standort deines Geräts zugreifen"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"auf den Standort deines Geräts zuzugreifen"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"auf deinen Kalender zugreifen"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
diff --git a/core/res/res/values-el-watch/styles_material.xml b/core/res/res/values-el-watch/styles_material.xml
new file mode 100644
index 0000000..a02b85e
--- /dev/null
+++ b/core/res/res/values-el-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"υποψήφιοι"</font></string>
+</resources>
diff --git a/core/res/res/values-en-rAU-watch/styles_material.xml b/core/res/res/values-en-rAU-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-en-rAU-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-en-rGB-watch/styles_material.xml b/core/res/res/values-en-rGB-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-en-rGB-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-en-rIN-watch/styles_material.xml b/core/res/res/values-en-rIN-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-en-rIN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-es-rUS-watch/styles_material.xml b/core/res/res/values-es-rUS-watch/styles_material.xml
new file mode 100644
index 0000000..898d2fd
--- /dev/null
+++ b/core/res/res/values-es-rUS-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
+</resources>
diff --git a/core/res/res/values-es-watch/styles_material.xml b/core/res/res/values-es-watch/styles_material.xml
new file mode 100644
index 0000000..898d2fd
--- /dev/null
+++ b/core/res/res/values-es-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
+</resources>
diff --git a/core/res/res/values-et-rEE-watch/styles_material.xml b/core/res/res/values-et-rEE-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-et-rEE-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-fa-watch/styles_material.xml b/core/res/res/values-fa-watch/styles_material.xml
new file mode 100644
index 0000000..23b9a7e
--- /dev/null
+++ b/core/res/res/values-fa-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"کاندیدها"</font></string>
+</resources>
diff --git a/core/res/res/values-fi-watch/styles_material.xml b/core/res/res/values-fi-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-fi-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-fr-rCA-watch/styles_material.xml b/core/res/res/values-fr-rCA-watch/styles_material.xml
new file mode 100644
index 0000000..f692d5c
--- /dev/null
+++ b/core/res/res/values-fr-rCA-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidats"</font></string>
+</resources>
diff --git a/core/res/res/values-fr-watch/styles_material.xml b/core/res/res/values-fr-watch/styles_material.xml
new file mode 100644
index 0000000..f692d5c
--- /dev/null
+++ b/core/res/res/values-fr-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidats"</font></string>
+</resources>
diff --git a/core/res/res/values-gl-rES-watch/styles_material.xml b/core/res/res/values-gl-rES-watch/styles_material.xml
new file mode 100644
index 0000000..898d2fd
--- /dev/null
+++ b/core/res/res/values-gl-rES-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
+</resources>
diff --git a/core/res/res/values-gu-rIN-watch/styles_material.xml b/core/res/res/values-gu-rIN-watch/styles_material.xml
new file mode 100644
index 0000000..21c6871
--- /dev/null
+++ b/core/res/res/values-gu-rIN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ઉમેદવારો"</font></string>
+</resources>
diff --git a/core/res/res/values-hr-watch/styles_material.xml b/core/res/res/values-hr-watch/styles_material.xml
new file mode 100644
index 0000000..88e5751
--- /dev/null
+++ b/core/res/res/values-hr-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidati"</font></string>
+</resources>
diff --git a/core/res/res/values-hu-watch/styles_material.xml b/core/res/res/values-hu-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-hu-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-in-watch/styles_material.xml b/core/res/res/values-in-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-in-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-is-rIS-watch/styles_material.xml b/core/res/res/values-is-rIS-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-is-rIS-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-it-watch/styles_material.xml b/core/res/res/values-it-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-it-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-iw-watch/styles_material.xml b/core/res/res/values-iw-watch/styles_material.xml
new file mode 100644
index 0000000..f44b272
--- /dev/null
+++ b/core/res/res/values-iw-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"מועמדים"</font></string>
+</resources>
diff --git a/core/res/res/values-ja-watch/styles_material.xml b/core/res/res/values-ja-watch/styles_material.xml
new file mode 100644
index 0000000..7712090
--- /dev/null
+++ b/core/res/res/values-ja-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"候補"</font></string>
+</resources>
diff --git a/core/res/res/values-km-rKH-watch/styles_material.xml b/core/res/res/values-km-rKH-watch/styles_material.xml
new file mode 100644
index 0000000..e54cb00
--- /dev/null
+++ b/core/res/res/values-km-rKH-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"បេក្ខជន"</font></string>
+</resources>
diff --git a/core/res/res/values-kn-rIN-watch/styles_material.xml b/core/res/res/values-kn-rIN-watch/styles_material.xml
new file mode 100644
index 0000000..1ec23a4
--- /dev/null
+++ b/core/res/res/values-kn-rIN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ಅಭ್ಯರ್ಥಿಗಳು"</font></string>
+</resources>
diff --git a/core/res/res/values-ko-watch/styles_material.xml b/core/res/res/values-ko-watch/styles_material.xml
new file mode 100644
index 0000000..0755eac
--- /dev/null
+++ b/core/res/res/values-ko-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"후보"</font></string>
+</resources>
diff --git a/core/res/res/values-lo-rLA-watch/styles_material.xml b/core/res/res/values-lo-rLA-watch/styles_material.xml
new file mode 100644
index 0000000..1f845b9
--- /dev/null
+++ b/core/res/res/values-lo-rLA-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ແຄນດິເດດ"</font></string>
+</resources>
diff --git a/core/res/res/values-lt-watch/styles_material.xml b/core/res/res/values-lt-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-lt-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-lv-watch/styles_material.xml b/core/res/res/values-lv-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-lv-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-mk-rMK-watch/styles_material.xml b/core/res/res/values-mk-rMK-watch/styles_material.xml
new file mode 100644
index 0000000..89c3366
--- /dev/null
+++ b/core/res/res/values-mk-rMK-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"кандидати"</font></string>
+</resources>
diff --git a/core/res/res/values-ml-rIN-watch/styles_material.xml b/core/res/res/values-ml-rIN-watch/styles_material.xml
new file mode 100644
index 0000000..9d38c0d
--- /dev/null
+++ b/core/res/res/values-ml-rIN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"കാൻഡിഡേറ്റുകൾ"</font></string>
+</resources>
diff --git a/core/res/res/values-mn-rMN-watch/styles_material.xml b/core/res/res/values-mn-rMN-watch/styles_material.xml
new file mode 100644
index 0000000..f65ea48
--- /dev/null
+++ b/core/res/res/values-mn-rMN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"нэр дэвшигч"</font></string>
+</resources>
diff --git a/core/res/res/values-mr-rIN-watch/styles_material.xml b/core/res/res/values-mr-rIN-watch/styles_material.xml
new file mode 100644
index 0000000..3c2513e
--- /dev/null
+++ b/core/res/res/values-mr-rIN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"उमेद्वार"</font></string>
+</resources>
diff --git a/core/res/res/values-ms-rMY-watch/styles_material.xml b/core/res/res/values-ms-rMY-watch/styles_material.xml
new file mode 100644
index 0000000..3f5e687
--- /dev/null
+++ b/core/res/res/values-ms-rMY-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"calon"</font></string>
+</resources>
diff --git a/core/res/res/values-my-rMM-watch/styles_material.xml b/core/res/res/values-my-rMM-watch/styles_material.xml
new file mode 100644
index 0000000..616e13e
--- /dev/null
+++ b/core/res/res/values-my-rMM-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ကိုယ်စားလှယ်များ"</font></string>
+</resources>
diff --git a/core/res/res/values-nb-watch/styles_material.xml b/core/res/res/values-nb-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-nb-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-ne-rNP-watch/styles_material.xml b/core/res/res/values-ne-rNP-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-ne-rNP-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-nl-watch/styles_material.xml b/core/res/res/values-nl-watch/styles_material.xml
new file mode 100644
index 0000000..b821347
--- /dev/null
+++ b/core/res/res/values-nl-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidaten"</font></string>
+</resources>
diff --git a/core/res/res/values-pa-rIN-watch/styles_material.xml b/core/res/res/values-pa-rIN-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-pa-rIN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-pl-watch/styles_material.xml b/core/res/res/values-pl-watch/styles_material.xml
new file mode 100644
index 0000000..384d91c
--- /dev/null
+++ b/core/res/res/values-pl-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"elementy"</font></string>
+</resources>
diff --git a/core/res/res/values-pt-rBR-watch/styles_material.xml b/core/res/res/values-pt-rBR-watch/styles_material.xml
new file mode 100644
index 0000000..898d2fd
--- /dev/null
+++ b/core/res/res/values-pt-rBR-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
+</resources>
diff --git a/core/res/res/values-pt-rPT-watch/styles_material.xml b/core/res/res/values-pt-rPT-watch/styles_material.xml
new file mode 100644
index 0000000..898d2fd
--- /dev/null
+++ b/core/res/res/values-pt-rPT-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
+</resources>
diff --git a/core/res/res/values-pt-watch/styles_material.xml b/core/res/res/values-pt-watch/styles_material.xml
new file mode 100644
index 0000000..898d2fd
--- /dev/null
+++ b/core/res/res/values-pt-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
+</resources>
diff --git a/core/res/res/values-si-rLK-watch/styles_material.xml b/core/res/res/values-si-rLK-watch/styles_material.xml
new file mode 100644
index 0000000..37b4afe
--- /dev/null
+++ b/core/res/res/values-si-rLK-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"අපේක්ෂකයන්"</font></string>
+</resources>
diff --git a/core/res/res/values-sk-watch/styles_material.xml b/core/res/res/values-sk-watch/styles_material.xml
new file mode 100644
index 0000000..5b604e8
--- /dev/null
+++ b/core/res/res/values-sk-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidáti"</font></string>
+</resources>
diff --git a/core/res/res/values-sl-watch/styles_material.xml b/core/res/res/values-sl-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-sl-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-sq-rAL-watch/styles_material.xml b/core/res/res/values-sq-rAL-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-sq-rAL-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-sv-watch/styles_material.xml b/core/res/res/values-sv-watch/styles_material.xml
new file mode 100644
index 0000000..f2ab18a
--- /dev/null
+++ b/core/res/res/values-sv-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidater"</font></string>
+</resources>
diff --git a/core/res/res/values-sw-watch/styles_material.xml b/core/res/res/values-sw-watch/styles_material.xml
new file mode 100644
index 0000000..2e3f715
--- /dev/null
+++ b/core/res/res/values-sw-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"vipengee"</font></string>
+</resources>
diff --git a/core/res/res/values-te-rIN-watch/styles_material.xml b/core/res/res/values-te-rIN-watch/styles_material.xml
new file mode 100644
index 0000000..877cd58
--- /dev/null
+++ b/core/res/res/values-te-rIN-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"క్యాండిడేట్‌లు"</font></string>
+</resources>
diff --git a/core/res/res/values-th-watch/styles_material.xml b/core/res/res/values-th-watch/styles_material.xml
new file mode 100644
index 0000000..3227ced
--- /dev/null
+++ b/core/res/res/values-th-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ผู้สมัคร"</font></string>
+</resources>
diff --git a/core/res/res/values-tl-watch/styles_material.xml b/core/res/res/values-tl-watch/styles_material.xml
new file mode 100644
index 0000000..70e7a7a
--- /dev/null
+++ b/core/res/res/values-tl-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"mga kandidato"</font></string>
+</resources>
diff --git a/core/res/res/values-tr-watch/styles_material.xml b/core/res/res/values-tr-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-tr-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-uk-watch/styles_material.xml b/core/res/res/values-uk-watch/styles_material.xml
new file mode 100644
index 0000000..698d5b0
--- /dev/null
+++ b/core/res/res/values-uk-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"варіанти"</font></string>
+</resources>
diff --git a/core/res/res/values-uz-rUZ-watch/styles_material.xml b/core/res/res/values-uz-rUZ-watch/styles_material.xml
new file mode 100644
index 0000000..3cb38d6
--- /dev/null
+++ b/core/res/res/values-uz-rUZ-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"nomzodlar"</font></string>
+</resources>
diff --git a/core/res/res/values-vi-watch/styles_material.xml b/core/res/res/values-vi-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-vi-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-zh-rHK-watch/styles_material.xml b/core/res/res/values-zh-rHK-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-zh-rHK-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-zh-rTW-watch/styles_material.xml b/core/res/res/values-zh-rTW-watch/styles_material.xml
new file mode 100644
index 0000000..36a459d
--- /dev/null
+++ b/core/res/res/values-zh-rTW-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
+</resources>
diff --git a/core/res/res/values-zu-watch/styles_material.xml b/core/res/res/values-zu-watch/styles_material.xml
new file mode 100644
index 0000000..8b69fef
--- /dev/null
+++ b/core/res/res/values-zu-watch/styles_material.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<!-- 
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"amakhandidethi"</font></string>
+</resources>
diff --git a/docs/html/preview/behavior-changes.jd b/docs/html/preview/behavior-changes.jd
index b38f1b8..3a37295 100644
--- a/docs/html/preview/behavior-changes.jd
+++ b/docs/html/preview/behavior-changes.jd
@@ -737,7 +737,17 @@
 
   <li>The Work Mode setting controls access to work apps. When work mode is off the
   system launcher indicates work apps are unavailable by greying them out. Enabling
-  work mode again restores normal behavior.
+  work mode again restores normal behavior.</li>
+
+  <li>When installing a PKCS #12 file containing a client certificate chain and
+  the corresponding private key from Settings UI, the CA certificate in the
+  chain is no longer installed to the trusted credentials storage. This does
+  not affect the result of {@link android.security.KeyChain#getCertificateChain
+  KeyChain.getCertificateChain()} when apps attempt to retrieve the client
+  certificate chain later. If required, the CA certificate should be installed
+  to the trusted credentials storage via Settings UI separately, with a
+  DER-encoded format under a .crt or .cer file extension.
+  </li>
 </ul>
 
 <p>
diff --git a/docs/html/preview/support.jd b/docs/html/preview/support.jd
index ba30fe34..5328fd8 100644
--- a/docs/html/preview/support.jd
+++ b/docs/html/preview/support.jd
@@ -257,6 +257,26 @@
   server when in a Work profile. This issue will be resolved in the next
   Developer Preview.
   </li>
+
+  <li>After reboot with work mode off, solving work challenge does not switch
+  on work mode.
+  </li>
+
+  <li>Users receiving a video call in Hangouts have to unlock work challenge
+    first.
+  </li>
+
+  <li>Accessing Settings &gt; Security &gt; Device Security crash observed when
+  separating primary and work challenge.
+  </li>
+
+  <li>If {@link android.os.UserManager#DISALLOW_CONFIG_VPN} is set before
+  calling {@link android.app.admin.DevicePolicyManager#setAlwaysOnVpnPackage
+  DevicePolicyManager.setAlwaysOnVpnPackage()}, then setting always on VPN does
+  not work. That is, after rebooting the device with the {@link
+  android.os.UserManager#DISALLOW_CONFIG_VPN} restriction set, VPN is not
+  autostarted.
+  </li>
 </ul>
 
 <!-- TBA, if any
diff --git a/docs/html/training/wearables/watch-faces/service.jd b/docs/html/training/wearables/watch-faces/service.jd
index 20eb0c77..b54f51a 100755
--- a/docs/html/training/wearables/watch-faces/service.jd
+++ b/docs/html/training/wearables/watch-faces/service.jd
@@ -93,24 +93,20 @@
 
 <h3 id="Permissions">Declare Permissions</h3>
 
-<p>Watch faces require the <code>PROVIDE_BACKGROUND</code> and <code>WAKE_LOCK</code> permissions.
-Add the following permissions to the manifest files of both the wearable app and the mobile
-app under the <code>manifest</code> element:</p>
+<p>A watch face requires the <code>WAKE_LOCK</code> permission.
+Add the following permission to the manifest files of both the wearable app
+and the mobile app under the <code>manifest</code> element:</p>
 
 <pre>
 &lt;manifest ...>
     &lt;uses-permission
-        android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
-    &lt;uses-permission
         android:name="android.permission.WAKE_LOCK" />
     ...
 &lt;/manifest>
 </pre>
 
-<p class="caution"><strong>Caution:</strong> The handheld app must include all the permissions
-declared in the wearable app.</p>
-
-
+<p class="caution"><strong>Caution:</strong> The handheld app must include all
+of the permissions declared in the wearable app.</p>
 
 <h2 id="CallbackMethods">Implement the Service and Callback Methods</h2>
 
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index c1df28c..7a2cbd0 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -16,6 +16,7 @@
 
 package android.security;
 
+import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -32,7 +33,7 @@
 
     public static IGateKeeperService getService() {
         IGateKeeperService service = IGateKeeperService.Stub.asInterface(
-                ServiceManager.getService("android.service.gatekeeper.IGateKeeperService"));
+                ServiceManager.getService(Context.GATEKEEPER_SERVICE));
         if (service == null) {
             throw new IllegalStateException("Gatekeeper service not available");
         }
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index d447a38..ceeb12b 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -6174,7 +6174,7 @@
     if (id >= 256) {
         LOG_ALWAYS_FATAL("Package id out of range");
         return NO_ERROR;
-    } else if (id == 0 || appAsLib || isSystemAsset) {
+    } else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) {
         // This is a library or a system asset, so assign an ID
         id = mNextPackageId++;
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index 08364d2..6658c14 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -326,6 +326,13 @@
         }
 
         @Override
+        protected void onPreExecute() {
+            if (sConfigTracker == null || sTileCache == null) {
+                getDashboardCategories();
+            }
+        }
+
+        @Override
         protected void onPostExecute(List<DashboardCategory> dashboardCategories) {
             for (int i = 0; i < dashboardCategories.size(); i++) {
                 DashboardCategory category = dashboardCategories.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
index 913da18..3921a20 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
@@ -30,6 +30,7 @@
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
+import com.android.systemui.recents.misc.ForegroundThread;
 
 /**
  * An implementation of the system user's Recents interface to be called remotely by secondary
@@ -78,12 +79,16 @@
 
     @Override
     public void updateRecentsVisibility(boolean visible) {
-        mImpl.onVisibilityChanged(mContext, visible);
+        ForegroundThread.getHandler().post(() -> {
+            mImpl.onVisibilityChanged(mContext, visible);
+        });
     }
 
     @Override
     public void startScreenPinning(int taskId) {
-        mImpl.onStartScreenPinning(mContext, taskId);
+        ForegroundThread.getHandler().post(() -> {
+            mImpl.onStartScreenPinning(mContext, taskId);
+        });
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 992b13f..b961055 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -72,7 +72,12 @@
     }
 
     public void showPrompt(int taskId, boolean allowCancel) {
-        clearPrompt();
+        try {
+            clearPrompt();
+        } catch (IllegalArgumentException e) {
+            // If the call to show the prompt fails due to the request window not already being
+            // attached, then just ignore the error since we will be re-adding it below.
+        }
 
         this.taskId = taskId;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 28a6851..e1d4c8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -27,6 +27,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.os.Bundle;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
@@ -37,11 +38,11 @@
 import android.view.View;
 import android.view.ViewStub;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Chronometer;
 import android.widget.ImageView;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.MetricsProto;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.R;
@@ -50,6 +51,7 @@
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.StackScrollState;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 import com.android.systemui.statusbar.stack.StackViewState;
@@ -140,15 +142,17 @@
         @Override
         public void onClick(View v) {
             if (!mShowingPublic && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
+                mGroupExpansionChanging = true;
                 final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
                 boolean nowExpanded = mGroupManager.toggleGroupExpansion(mStatusBarNotification);
                 mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
-                mGroupExpansionChanging = true;
-                updateBackgroundForGroupState();
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
                         nowExpanded);
                 logExpansionEvent(true /* userAction */, wasExpanded);
             } else {
+                if (v.isAccessibilityFocused()) {
+                    mPrivateLayout.setFocusOnVisibilityChange();
+                }
                 boolean nowExpanded;
                 if (isPinned()) {
                     nowExpanded = !mExpandedWhenPinned;
@@ -181,6 +185,9 @@
                 }
     };
     private OnClickListener mOnClickListener;
+    private View mChildAfterViewWhenDismissed;
+    private View mGroupParentWhenDismissed;
+    private boolean mRefocusOnDismiss;
 
     public boolean isGroupExpansionChanging() {
         if (isChildInGroup()) {
@@ -717,8 +724,19 @@
         }
     }
 
-    public void setDismissed(boolean dismissed) {
+    public void setDismissed(boolean dismissed, boolean fromAccessibility) {
         mDismissed = dismissed;
+        mGroupParentWhenDismissed = mNotificationParent;
+        mRefocusOnDismiss = fromAccessibility;
+        mChildAfterViewWhenDismissed = null;
+        if (isChildInGroup()) {
+            List<ExpandableNotificationRow> notificationChildren =
+                    mNotificationParent.getNotificationChildren();
+            int i = notificationChildren.indexOf(this);
+            if (i != -1 && i < notificationChildren.size() - 1) {
+                mChildAfterViewWhenDismissed = notificationChildren.get(i + 1);
+            }
+        }
     }
 
     public boolean isDismissed() {
@@ -750,6 +768,14 @@
         return mChildrenContainer;
     }
 
+    public View getChildAfterViewWhenDismissed() {
+        return mChildAfterViewWhenDismissed;
+    }
+
+    public View getGroupParentWhenDismissed() {
+        return mGroupParentWhenDismissed;
+    }
+
     public interface ExpansionLogger {
         public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
@@ -1326,8 +1352,11 @@
 
     private void updateClearability() {
         // public versions cannot be dismissed
-        mVetoButton.setVisibility(isClearable() && (!mShowingPublic
-                || !mSensitiveHiddenInGeneral) ? View.VISIBLE : View.GONE);
+        mVetoButton.setVisibility(canViewBeDismissed() ? View.VISIBLE : View.GONE);
+    }
+
+    private boolean canViewBeDismissed() {
+        return isClearable() && (!mShowingPublic || !mSensitiveHiddenInGeneral);
     }
 
     public void makeActionsVisibile() {
@@ -1343,6 +1372,7 @@
         if (mChildrenContainer != null) {
             mChildrenContainer.setChildrenExpanded(expanded);
         }
+        updateBackgroundForGroupState();
         updateClickAndFocus();
     }
 
@@ -1568,6 +1598,32 @@
         }
     }
 
+    @Override
+    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfoInternal(info);
+        if (canViewBeDismissed()) {
+            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+        if (super.performAccessibilityActionInternal(action, arguments)) {
+            return true;
+        }
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_DISMISS:
+                NotificationStackScrollLayout.performDismiss(this, mGroupManager,
+                        true /* fromAccessibility */);
+                return true;
+        }
+        return false;
+    }
+
+    public boolean shouldRefocusOnDismiss() {
+        return mRefocusOnDismiss || isAccessibilityFocused();
+    }
+
     public interface OnExpandClickListener {
         void onExpandClicked(NotificationData.Entry clickedEntry, boolean nowExpanded);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index a11263a..30ac9ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -29,6 +29,7 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
 
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.R;
@@ -117,6 +118,7 @@
     private PendingIntent mPreviousHeadsUpRemoteInputIntent;
 
     private int mContentHeightAtAnimationStart = UNDEFINED;
+    private boolean mFocusOnVisibilityChange;
 
 
     public NotificationContentView(Context context, AttributeSet attrs) {
@@ -395,6 +397,19 @@
         }
     }
 
+    private void focusExpandButtonIfNecessary() {
+        if (mFocusOnVisibilityChange) {
+            NotificationHeaderView header = getVisibleNotificationHeader();
+            if (header != null) {
+                ImageView expandButton = header.getExpandButton();
+                if (expandButton != null) {
+                    expandButton.requestAccessibilityFocus();
+                }
+            }
+            mFocusOnVisibilityChange = false;
+        }
+    }
+
     public void setContentHeight(int contentHeight) {
         mContentHeight = Math.max(Math.min(contentHeight, getHeight()), getMinHeight());
         selectLayout(mAnimate /* animate */, false /* force */);
@@ -584,7 +599,8 @@
             updateContentTransformation();
         } else {
             int visibleType = calculateVisibleType();
-            if (visibleType != mVisibleType || force) {
+            boolean changedType = visibleType != mVisibleType;
+            if (changedType || force) {
                 View visibleView = getViewForVisibleType(visibleType);
                 if (visibleView != null) {
                     visibleView.setVisibility(VISIBLE);
@@ -604,6 +620,9 @@
                     updateViewVisibilities(visibleType);
                 }
                 mVisibleType = visibleType;
+                if (changedType) {
+                    focusExpandButtonIfNecessary();
+                }
                 updateBackgroundColor(animate);
             }
         }
@@ -1133,4 +1152,8 @@
             mContentHeightAtAnimationStart = UNDEFINED;
         }
     }
+
+    public void setFocusOnVisibilityChange() {
+        mFocusOnVisibilityChange = true;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 7c391fb..43f847c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -769,7 +769,7 @@
                 mHeadsUpManager.addSwipedOutNotification(row.getStatusBarNotification().getKey());
             }
         }
-        performDismiss(v);
+        performDismiss(v, mGroupManager, false /* fromAccessibility */);
 
         mFalsingManager.onNotificationDismissed();
         if (mFalsingManager.shouldEnforceBouncer()) {
@@ -778,17 +778,18 @@
         }
     }
 
-    private void performDismiss(View v) {
+    public static void performDismiss(View v, NotificationGroupManager groupManager,
+            boolean fromAccessibility) {
         if (v instanceof ExpandableNotificationRow) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) v;
-            if (mGroupManager.isOnlyChildInSuppressedGroup(row.getStatusBarNotification())) {
+            if (groupManager.isOnlyChildInGroup(row.getStatusBarNotification())) {
                 ExpandableNotificationRow groupSummary =
-                        mGroupManager.getLogicalGroupSummary(row.getStatusBarNotification());
+                        groupManager.getLogicalGroupSummary(row.getStatusBarNotification());
                 if (groupSummary.isClearable()) {
-                    performDismiss(groupSummary);
+                    performDismiss(groupSummary, groupManager, fromAccessibility);
                 }
             }
-            row.setDismissed(true);
+            row.setDismissed(true, fromAccessibility);
         }
         final View veto = v.findViewById(R.id.veto);
         if (veto != null && veto.getVisibility() != View.GONE) {
@@ -2265,6 +2266,27 @@
 
         // Make sure the clipRect we might have set is removed
         expandableView.setClipTopAmount(0);
+
+        focusNextViewIfFocused(child);
+    }
+
+    private void focusNextViewIfFocused(View view) {
+        if (view instanceof ExpandableNotificationRow) {
+            ExpandableNotificationRow row = (ExpandableNotificationRow) view;
+            if (row.shouldRefocusOnDismiss()) {
+                View nextView = row.getChildAfterViewWhenDismissed();
+                if (nextView == null) {
+                    View groupParentWhenDismissed = row.getGroupParentWhenDismissed();
+                    nextView = getFirstChildBelowTranlsationY(groupParentWhenDismissed != null
+                            ? groupParentWhenDismissed.getTranslationY()
+                            : view.getTranslationY());
+                }
+                if (nextView != null) {
+                    nextView.requestAccessibilityFocus();
+                }
+            }
+        }
+
     }
 
     private boolean isChildInGroup(View child) {
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 2a506d82..5527a41 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2262,8 +2262,68 @@
     // CATEGORY: SETTINGS
     SETTINGS_GESTURES = 459;
 
-    // ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
+    // ------ Begin Deletion Helper ------
+    // ACTION: Settings > Storage > Free Up Space > Photos & Videos > Toggle
+    //   SUBTYPE: false is off, true is on
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_SELECTION_PHOTOS = 460;
 
+    // ACTION: Settings > Storage > Free Up Space > Apps > Toggle
+    //   SUBTYPE: false is off, true is on
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_SELECTION_ALL_APPS = 461;
+
+    // ACTION: Settings > Storage > Free Up Space > Apps > Click an unchecked app
+    // CATEGORY: SETTINGS
+    //   PACKAGE: Unchecked app
+    ACTION_DELETION_SELECTION_APP_ON = 462;
+
+    // ACTION: Settings > Storage > Free Up Space > Apps > Click a checked app
+    // CATEGORY: SETTINGS
+    //   PACKAGE: Checked app
+    ACTION_DELETION_SELECTION_APP_OFF = 463;
+
+    // ACTION: Settings > Storage > Free Up Space > Apps > Click category
+    //   SUBTYPE: false is expanded, true is collapsed
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_APPS_COLLAPSED = 464;
+
+    // ACTION: Settings > Storage > Free Up Space > Downloads > Check On
+    //   SUBTYPE: false is off, true is on
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_SELECTION_DOWNLOADS = 465;
+
+    // ACTION: Settings > Storage > Free Up Space > Downloads > Click category
+    //   SUBTYPE: false is expanded, true is collapsed
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_DOWNLOADS_COLLAPSED = 466;
+
+    // ACTION: Settings > Storage > Free Up Space > Free up ... GB
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_HELPER_CLEAR = 467;
+
+    // ACTION: Settings > Storage > Free Up Space > Cancel
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_HELPER_CANCEL = 468;
+
+    // ACTION: Settings > Storage > Free Up Space > Free up ... GB > Remove
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_HELPER_REMOVE_CONFIRM = 469;
+
+    // ACTION: Settings > Storage > Free Up Space > Free up ... GB > Cancel
+    // CATEGORY: SETTINGS
+    ACTION_DELETION_HELPER_REMOVE_CANCEL = 470;
+
+    // Deletion helper encountered an error during package deletion.
+    ACTION_DELETION_HELPER_APPS_DELETION_FAIL = 471;
+
+    // Deletion helper encountered an error during downloads folder deletion.
+    ACTION_DELETION_HELPER_DOWNLOADS_DELETION_FAIL = 472;
+
+    // Deletion helper encountered an error during photo and video deletion.
+    ACTION_DELETION_HELPER_PHOTOS_VIDEOS_DELETION_FAIL = 473;
+
+    // ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index eeb20bf..1e715f9 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -1588,7 +1588,7 @@
         }
 
         final IBinder service =
-            ServiceManager.getService("android.service.gatekeeper.IGateKeeperService");
+            ServiceManager.getService(Context.GATEKEEPER_SERVICE);
         if (service != null) {
             service.linkToDeath(new GateKeeperDiedRecipient(), 0);
             mGateKeeperService = IGateKeeperService.Stub.asInterface(service);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 4084542..0cf5172 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3425,7 +3425,7 @@
     /** {@hide} */
     @NonNull
     public AccountAndUser[] getAllAccounts() {
-        final List<UserInfo> users = getUserManager().getUsers();
+        final List<UserInfo> users = getUserManager().getUsers(true);
         final int[] userIds = new int[users.size()];
         for (int i = 0; i < userIds.length; i++) {
             userIds[i] = users.get(i).id;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 63f122b..2c7ef7e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2292,11 +2292,8 @@
                 final ActivityRecord r = (ActivityRecord) msg.obj;
                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
                 if (needsVrMode) {
-                    VrManagerInternal vrService =
-                            LocalServices.getService(VrManagerInternal.class);
-                    boolean enable = msg.arg1 == 1;
-                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
-                            r.info.getComponentName());
+                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
+                            r.info.getComponentName(), false);
                 }
             } break;
             }
@@ -3084,6 +3081,17 @@
                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
     }
 
+    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
+            ComponentName callingPackage, boolean immediate) {
+        VrManagerInternal vrService =
+                LocalServices.getService(VrManagerInternal.class);
+        if (immediate) {
+            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
+        } else {
+            vrService.setVrMode(enabled, packageName, userId, callingPackage);
+        }
+    }
+
     final void showAskCompatModeDialogLocked(ActivityRecord r) {
         Message msg = Message.obtain();
         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
@@ -21420,11 +21428,25 @@
         public SleepToken acquireSleepToken(String tag) {
             Preconditions.checkNotNull(tag);
 
+            ComponentName requestedVrService = null;
+            ComponentName callingVrActivity = null;
+            int userId = -1;
+            synchronized (ActivityManagerService.this) {
+                if (mFocusedActivity != null) {
+                    requestedVrService = mFocusedActivity.requestedVrComponent;
+                    callingVrActivity = mFocusedActivity.info.getComponentName();
+                    userId = mFocusedActivity.userId;
+                }
+            }
+
+            if (requestedVrService != null) {
+                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
+            }
+
             synchronized (ActivityManagerService.this) {
                 SleepTokenImpl token = new SleepTokenImpl(tag);
                 mSleepTokens.add(token);
                 updateSleepIfNeededLocked();
-                applyVrModeIfNeededLocked(mFocusedActivity, false);
                 return token;
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2562707..e321049 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -19359,10 +19359,18 @@
             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
                 UserManagerService.enforceSerialNumber(
                         Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
+                if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
+                    UserManagerService.enforceSerialNumber(
+                            Environment.getDataSystemDeDirectory(userId), userSerial);
+                }
             }
             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
                 UserManagerService.enforceSerialNumber(
                         Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
+                if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
+                    UserManagerService.enforceSerialNumber(
+                            Environment.getDataSystemCeDirectory(userId), userSerial);
+                }
             }
 
             synchronized (mInstallLock) {
@@ -19431,6 +19439,10 @@
                 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
         Collections.addAll(files, FileUtils
                 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
+        Collections.addAll(files, FileUtils
+                .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
+        Collections.addAll(files, FileUtils
+                .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
         for (File file : files) {
             if (!file.isDirectory()) continue;
 
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 934545a..ace14ac 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -19,10 +19,8 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ShortcutInfo;
 import android.content.res.Resources;
 import android.os.PersistableBundle;
@@ -51,8 +49,6 @@
 import java.util.Set;
 import java.util.function.Predicate;
 
-import sun.misc.Resource;
-
 /**
  * Package information used by {@link ShortcutService}.
  * User information used by {@link ShortcutService}.
@@ -63,6 +59,7 @@
  */
 class ShortcutPackage extends ShortcutPackageItem {
     private static final String TAG = ShortcutService.TAG;
+    private static final String TAG_VERIFY = ShortcutService.TAG + ".verify";
 
     static final String TAG_ROOT = "package";
     private static final String TAG_INTENT_EXTRAS = "intent-extras";
@@ -303,12 +300,17 @@
      * Remove all dynamic shortcuts.
      */
     public void deleteAllDynamicShortcuts() {
+        final long now = mShortcutUser.mService.injectCurrentTimeMillis();
+
         boolean changed = false;
         for (int i = mShortcuts.size() - 1; i >= 0; i--) {
             final ShortcutInfo si = mShortcuts.valueAt(i);
             if (si.isDynamic()) {
                 changed = true;
+
+                si.setTimestamp(now);
                 si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
+                si.setRank(0); // It may still be pinned, so clear the rank.
             }
         }
         if (changed) {
@@ -356,10 +358,14 @@
             ensureNotImmutable(oldShortcut);
         }
         if (oldShortcut.isPinned()) {
+
+            oldShortcut.setRank(0);
             oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
             if (disable) {
                 oldShortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
             }
+            oldShortcut.setTimestamp(mShortcutUser.mService.injectCurrentTimeMillis());
+
             return oldShortcut;
         } else {
             deleteShortcutInner(shortcutId);
@@ -829,7 +835,7 @@
         if (!a.isManifestShortcut() && b.isManifestShortcut()) {
             return 1;
         }
-        return a.getRank() - b.getRank();
+        return Integer.compare(a.getRank(), b.getRank());
     };
 
     /**
@@ -837,8 +843,6 @@
      * contain "floating" shortcuts because they don't belong on any activities.
      */
     private ArrayMap<ComponentName, ArrayList<ShortcutInfo>> sortShortcutsToActivities() {
-        final int maxShortcuts = mShortcutUser.mService.getMaxActivityShortcuts();
-
         final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> activitiesToShortcuts
                 = new ArrayMap<>();
         for (int i = mShortcuts.size() - 1; i >= 0; i--) {
@@ -851,7 +855,7 @@
 
             ArrayList<ShortcutInfo> list = activitiesToShortcuts.get(activity);
             if (list == null) {
-                list = new ArrayList<>(maxShortcuts * 2);
+                list = new ArrayList<>();
                 activitiesToShortcuts.put(activity, list);
             }
             list.add(si);
@@ -976,6 +980,96 @@
         }
     }
 
+    /** Clears the implicit ranks for all shortcuts. */
+    public void clearAllImplicitRanks() {
+        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+            final ShortcutInfo si = mShortcuts.valueAt(i);
+            si.clearImplicitRankAndRankChangedFlag();
+        }
+    }
+
+    /**
+     * Used to sort shortcuts for rank auto-adjusting.
+     */
+    final Comparator<ShortcutInfo> mShortcutRankComparator = (ShortcutInfo a, ShortcutInfo b) -> {
+        // First, sort by rank.
+        int ret = Integer.compare(a.getRank(), b.getRank());
+        if (ret != 0) {
+            return ret;
+        }
+        // When ranks are tie, then prioritize the ones that have just been assigned new ranks.
+        // e.g. when there are 3 shortcuts, "s1" "s2" and "s3" with rank 0, 1, 2 respectively,
+        // adding a shortcut "s4" with rank 1 will "insert" it between "s1" and "s2", because
+        // "s2" and "s4" have the same rank 1 but s4 has isRankChanged() set.
+        // Similarly, updating s3's rank to 1 will insert it between s1 and s2.
+        if (a.isRankChanged() != b.isRankChanged()) {
+            return a.isRankChanged() ? -1 : 1;
+        }
+        // If they're still tie, sort by implicit rank -- i.e. preserve the order in which
+        // they're passed to the API.
+        ret = Integer.compare(a.getImplicitRank(), b.getImplicitRank());
+        if (ret != 0) {
+            return ret;
+        }
+        // If they're stil tie, just sort by their IDs.
+        // This may happen with updateShortcuts() -- see
+        // the testUpdateShortcuts_noManifestShortcuts() test.
+        return a.getId().compareTo(b.getId());
+    };
+
+    /**
+     * Re-calculate the ranks for all shortcuts.
+     */
+    public void adjustRanks() {
+        final ShortcutService s = mShortcutUser.mService;
+        final long now = s.injectCurrentTimeMillis();
+
+        // First, clear ranks for floating shortcuts.
+        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+            final ShortcutInfo si = mShortcuts.valueAt(i);
+            if (si.isFloating()) {
+                if (si.getRank() != 0) {
+                    si.setTimestamp(now);
+                    si.setRank(0);
+                }
+            }
+        }
+
+        // Then adjust ranks.  Ranks are unique for each activity, so we first need to sort
+        // shortcuts to each activity.
+        // Then sort the shortcuts within each activity with mShortcutRankComparator, and
+        // assign ranks from 0.
+        final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> all =
+                sortShortcutsToActivities();
+        for (int outer = all.size() - 1; outer >= 0; outer--) { // For each activity.
+            final ArrayList<ShortcutInfo> list = all.valueAt(outer);
+
+            // Sort by ranks and other signals.
+            Collections.sort(list, mShortcutRankComparator);
+
+            int rank = 0;
+
+            final int size = list.size();
+            for (int i = 0; i < size; i++) {
+                final ShortcutInfo si = list.get(i);
+                if (si.isManifestShortcut()) {
+                    // Don't adjust ranks for manifest shortcuts.
+                    continue;
+                }
+                // At this point, it must be dynamic.
+                if (!si.isDynamic()) {
+                    s.wtf("Non-dynamic shortcut found.");
+                    continue;
+                }
+                final int thisRank = rank++;
+                if (si.getRank() != thisRank) {
+                    si.setTimestamp(now);
+                    si.setRank(thisRank);
+                }
+            }
+        }
+    }
+
     public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
         pw.println();
 
@@ -1087,7 +1181,6 @@
         ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE_RES_NAME,
                 si.getDisabledMessageResName());
         ShortcutService.writeAttr(out, ATTR_INTENT, si.getIntentNoExtras());
-        ShortcutService.writeAttr(out, ATTR_RANK, si.getRank());
         ShortcutService.writeAttr(out, ATTR_TIMESTAMP,
                 si.getLastChangedTimestamp());
         if (forBackup) {
@@ -1097,6 +1190,10 @@
                             ~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
                             | ShortcutInfo.FLAG_DYNAMIC));
         } else {
+            // When writing for backup, ranks shouldn't be saved, since shortcuts won't be restored
+            // as dynamic.
+            ShortcutService.writeAttr(out, ATTR_RANK, si.getRank());
+
             ShortcutService.writeAttr(out, ATTR_FLAGS, si.getFlags());
             ShortcutService.writeAttr(out, ATTR_ICON_RES_ID, si.getIconResourceId());
             ShortcutService.writeAttr(out, ATTR_ICON_RES_NAME, si.getIconResName());
@@ -1272,35 +1369,74 @@
                 sortShortcutsToActivities();
 
         // Make sure each activity won't have more than max shortcuts.
-        for (int i = all.size() - 1; i >= 0; i--) {
-            if (all.valueAt(i).size() > mShortcutUser.mService.getMaxActivityShortcuts()) {
+        for (int outer = all.size() - 1; outer >= 0; outer--) {
+            final ArrayList<ShortcutInfo> list = all.valueAt(outer);
+            if (list.size() > mShortcutUser.mService.getMaxActivityShortcuts()) {
                 failed = true;
-                Log.e(TAG, "Package " + getPackageName() + ": activity " + all.keyAt(i)
-                        + " has " + all.valueAt(i).size() + " shortcuts.");
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": activity " + all.keyAt(outer)
+                        + " has " + all.valueAt(outer).size() + " shortcuts.");
             }
+
+            // Sort by rank.
+            Collections.sort(list, (a, b) -> Integer.compare(a.getRank(), b.getRank()));
+
+            // Split into two arrays for each kind.
+            final ArrayList<ShortcutInfo> dynamicList = new ArrayList<>(list);
+            dynamicList.removeIf((si) -> !si.isDynamic());
+
+            final ArrayList<ShortcutInfo> manifestList = new ArrayList<>(list);
+            dynamicList.removeIf((si) -> !si.isManifestShortcut());
+
+            verifyRanksSequential(dynamicList);
+            verifyRanksSequential(manifestList);
         }
 
+        // Verify each shortcut's status.
         for (int i = mShortcuts.size() - 1; i >= 0; i--) {
             final ShortcutInfo si = mShortcuts.valueAt(i);
             if (!(si.isManifestShortcut() || si.isDynamic() || si.isPinned())) {
                 failed = true;
-                Log.e(TAG, "Package " + getPackageName() + ": shortcut " + si.getId()
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " is not manifest, dynamic or pinned.");
             }
+            if (si.isManifestShortcut() && si.isDynamic()) {
+                failed = true;
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+                        + " is both dynamic and manifest at the same time.");
+            }
             if (si.getActivity() == null) {
                 failed = true;
-                Log.e(TAG, "Package " + getPackageName() + ": shortcut " + si.getId()
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " has null activity.");
             }
             if ((si.isDynamic() || si.isManifestShortcut()) && !si.isEnabled()) {
                 failed = true;
-                Log.e(TAG, "Package " + getPackageName() + ": shortcut " + si.getId()
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " is not floating, but is disabled.");
             }
+            if (si.isFloating() && si.getRank() != 0) {
+                failed = true;
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+                        + " is floating, but has rank=" + si.getRank());
+            }
         }
 
         if (failed) {
             throw new IllegalStateException("See logcat for errors");
         }
     }
+
+    private boolean verifyRanksSequential(List<ShortcutInfo> list) {
+        boolean failed = false;
+
+        for (int i = 0; i < list.size(); i++) {
+            final ShortcutInfo si = list.get(i);
+            if (si.getRank() != i) {
+                failed = true;
+                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+                        + " rank=" + si.getRank() + " but expected to be "+ i);
+            }
+        }
+        return failed;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java
index 470d4af..ec19927 100644
--- a/services/core/java/com/android/server/pm/ShortcutParser.java
+++ b/services/core/java/com/android/server/pm/ShortcutParser.java
@@ -103,7 +103,7 @@
                 }
                 if (depth == 2 && TAG_SHORTCUT.equals(tag)) {
                     final ShortcutInfo si = parseShortcutAttributes(
-                            service, attrs, packageName, activity, userId, rank++);
+                            service, attrs, packageName, activity, userId, rank);
                     if (ShortcutService.DEBUG) {
                         Slog.d(TAG, "Shortcut=" + si);
                     }
@@ -128,6 +128,7 @@
                         }
                         result.add(si);
                         numShortcuts++;
+                        rank++;
                     }
                     continue;
                 }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 5769402..1619168 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -114,7 +114,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
@@ -223,7 +222,7 @@
         String KEY_MAX_ICON_DIMENSION_DP_LOWRAM = "max_icon_dimension_dp_lowram";
 
         /**
-         * Key name for the max dynamic shortcuts per app. (int)
+         * Key name for the max dynamic shortcuts per activity. (int)
          */
         String KEY_MAX_SHORTCUTS = "max_shortcuts";
 
@@ -1479,6 +1478,12 @@
         return (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
     }
 
+    private void assignImplicitRanks(List<ShortcutInfo> shortcuts) {
+        for (int i = shortcuts.size() - 1; i >= 0; i--) {
+            shortcuts.get(i).setImplicitRank(i);
+        }
+    }
+
     // === APIs ===
 
     @Override
@@ -1501,10 +1506,9 @@
                 return false;
             }
 
-            // Validate the shortcuts.
-            for (int i = 0; i < size; i++) {
-                fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false);
-            }
+            // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+            ps.clearAllImplicitRanks();
+            assignImplicitRanks(newShortcuts);
 
             // First, remove all un-pinned; dynamic shortcuts
             ps.deleteAllDynamicShortcuts();
@@ -1514,6 +1518,9 @@
                 final ShortcutInfo newShortcut = newShortcuts.get(i);
                 ps.addOrUpdateDynamicShortcut(newShortcut);
             }
+
+            // Lastly, adjust the ranks.
+            ps.adjustRanks();
         }
         packageShortcutsChanged(packageName, userId);
 
@@ -1542,41 +1549,58 @@
                 return false;
             }
 
+            // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+            ps.clearAllImplicitRanks();
+            assignImplicitRanks(newShortcuts);
+
             for (int i = 0; i < size; i++) {
                 final ShortcutInfo source = newShortcuts.get(i);
                 fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
 
                 final ShortcutInfo target = ps.findShortcutById(source.getId());
-                if (target != null) {
-                    if (target.isEnabled() != source.isEnabled()) {
-                        Slog.w(TAG,
-                                "ShortcutInfo.enabled cannot be changed with updateShortcuts()");
-                    }
+                if (target == null) {
+                    continue;
+                }
 
-                    final boolean replacingIcon = (source.getIcon() != null);
-                    if (replacingIcon) {
-                        removeIcon(userId, target);
-                    }
+                if (target.isEnabled() != source.isEnabled()) {
+                    Slog.w(TAG,
+                            "ShortcutInfo.enabled cannot be changed with updateShortcuts()");
+                }
 
-                    if (source.getActivity() != null &&
-                            !source.getActivity().equals(target.getActivity())) {
-                        // TODO When activity is changing, check the dynamic count.
-                    }
+                // When updating the rank, we need to insert between existing ranks, so set
+                // this setRankChanged, and also copy the implicit rank fo adjustRanks().
+                if (source.hasRank()) {
+                    target.setRankChanged();
+                    target.setImplicitRank(source.getImplicitRank());
+                }
 
-                    // Note copyNonNullFieldsFrom() does the "updatable with?" check too.
-                    target.copyNonNullFieldsFrom(source);
+                final boolean replacingIcon = (source.getIcon() != null);
+                if (replacingIcon) {
+                    removeIcon(userId, target);
+                }
 
-                    if (replacingIcon) {
-                        saveIconAndFixUpShortcut(userId, target);
-                    }
+                if (source.getActivity() != null &&
+                        !source.getActivity().equals(target.getActivity())) {
+                    // TODO When activity is changing, check the dynamic count.
+                }
 
-                    // When we're updating any resource related fields, re-extract the res names and
-                    // the values.
-                    if (replacingIcon || source.hasStringResources()) {
-                        fixUpShortcutResourceNamesAndValues(target);
-                    }
+                // Note copyNonNullFieldsFrom() does the "updatable with?" check too.
+                target.copyNonNullFieldsFrom(source);
+                target.setTimestamp(injectCurrentTimeMillis());
+
+                if (replacingIcon) {
+                    saveIconAndFixUpShortcut(userId, target);
+                }
+
+                // When we're updating any resource related fields, re-extract the res names and
+                // the values.
+                if (replacingIcon || source.hasStringResources()) {
+                    fixUpShortcutResourceNamesAndValues(target);
                 }
             }
+
+            // Lastly, adjust the ranks.
+            ps.adjustRanks();
         }
         packageShortcutsChanged(packageName, userId);
 
@@ -1600,6 +1624,10 @@
 
             ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_ADD);
 
+            // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+            ps.clearAllImplicitRanks();
+            assignImplicitRanks(newShortcuts);
+
             // Throttling.
             if (!ps.tryApiCall()) {
                 return false;
@@ -1610,9 +1638,16 @@
                 // Validate the shortcut.
                 fixUpIncomingShortcutInfo(newShortcut, /* forUpdate= */ false);
 
+                // When ranks are changing, we need to insert between ranks, so set the
+                // "rank changed" flag.
+                newShortcut.setRankChanged();
+
                 // Add it.
                 ps.addOrUpdateDynamicShortcut(newShortcut);
             }
+
+            // Lastly, adjust the ranks.
+            ps.adjustRanks();
         }
         packageShortcutsChanged(packageName, userId);
 
@@ -1637,6 +1672,9 @@
                         disabledMessage, disabledMessageResId,
                         /* overrideImmutable=*/ false);
             }
+
+            // We may have removed dynamic shortcuts which may have left a gap, so adjust the ranks.
+            ps.adjustRanks();
         }
         packageShortcutsChanged(packageName, userId);
 
@@ -1677,6 +1715,9 @@
                 ps.deleteDynamicWithId(
                         Preconditions.checkStringNotEmpty((String) shortcutIds.get(i)));
             }
+
+            // We may have removed dynamic shortcuts which may have left a gap, so adjust the ranks.
+            ps.adjustRanks();
         }
         packageShortcutsChanged(packageName, userId);
 
@@ -2328,6 +2369,7 @@
         } finally {
             logDurationStat(Stats.CHECK_PACKAGE_CHANGES, start);
         }
+        verifyStates();
     }
 
     private void handlePackageAdded(String packageName, @UserIdInt int userId) {
@@ -2339,6 +2381,7 @@
             user.attemptToRestoreIfNeededAndSave(this, packageName, userId);
             user.handlePackageAddedOrUpdated(packageName);
         }
+        verifyStates();
     }
 
     private void handlePackageUpdateFinished(String packageName, @UserIdInt int userId) {
@@ -2354,6 +2397,7 @@
                 user.handlePackageAddedOrUpdated(packageName);
             }
         }
+        verifyStates();
     }
 
     private void handlePackageRemoved(String packageName, @UserIdInt int packageUserId) {
@@ -2362,6 +2406,8 @@
                     packageUserId));
         }
         cleanUpPackageForAllLoadedUsers(packageName, packageUserId);
+
+        verifyStates();
     }
 
     private void handlePackageDataCleared(String packageName, int packageUserId) {
@@ -2370,6 +2416,8 @@
                     packageUserId));
         }
         cleanUpPackageForAllLoadedUsers(packageName, packageUserId);
+
+        verifyStates();
     }
 
     // === PackageManager interaction ===
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index c2c569e..0bf0cac 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -67,6 +67,8 @@
 import android.os.UserManagerInternal;
 import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.os.storage.StorageManager;
+import android.security.GateKeeper;
+import android.service.gatekeeper.IGateKeeperService;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -90,6 +92,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
 import com.android.server.am.UserState;
 
 import libcore.io.IoUtils;
@@ -122,6 +125,7 @@
  * </ul>
  */
 public class UserManagerService extends IUserManager.Stub {
+
     private static final String LOG_TAG = "UserManagerService";
     static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
     private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE
@@ -370,6 +374,31 @@
         }
     }
 
+    public static class LifeCycle extends SystemService {
+
+        private UserManagerService mUms;
+
+        /**
+         * @param context
+         */
+        public LifeCycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            mUms = UserManagerService.getInstance();
+            publishBinderService(Context.USER_SERVICE, mUms);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+                mUms.cleanupPartialUsers();
+            }
+        }
+    }
+
     @VisibleForTesting
     UserManagerService(File dataDir) {
         this(null, null, new Object(), dataDir);
@@ -411,25 +440,6 @@
     }
 
     void systemReady() {
-        // Prune out any partially created, partially removed and ephemeral users.
-        ArrayList<UserInfo> partials = new ArrayList<>();
-        synchronized (mUsersLock) {
-            final int userSize = mUsers.size();
-            for (int i = 0; i < userSize; i++) {
-                UserInfo ui = mUsers.valueAt(i).info;
-                if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) {
-                    partials.add(ui);
-                }
-            }
-        }
-        final int partialsSize = partials.size();
-        for (int i = 0; i < partialsSize; i++) {
-            UserInfo ui = partials.get(i);
-            Slog.w(LOG_TAG, "Removing partially created user " + ui.id
-                    + " (name=" + ui.name + ")");
-            removeUserState(ui.id);
-        }
-
         mAppOpsService = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
 
@@ -452,6 +462,27 @@
                 null, mHandler);
     }
 
+    void cleanupPartialUsers() {
+        // Prune out any partially created, partially removed and ephemeral users.
+        ArrayList<UserInfo> partials = new ArrayList<>();
+        synchronized (mUsersLock) {
+            final int userSize = mUsers.size();
+            for (int i = 0; i < userSize; i++) {
+                UserInfo ui = mUsers.valueAt(i).info;
+                if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) {
+                    partials.add(ui);
+                }
+            }
+        }
+        final int partialsSize = partials.size();
+        for (int i = 0; i < partialsSize; i++) {
+            UserInfo ui = partials.get(i);
+            Slog.w(LOG_TAG, "Removing partially created user " + ui.id
+                    + " (name=" + ui.name + ")");
+            removeUserState(ui.id);
+        }
+    }
+
     @Override
     public String getUserAccount(int userId) {
         checkManageUserAndAcrossUsersFullPermission("get user account");
@@ -2479,8 +2510,23 @@
                 "Destroying key for user " + userHandle + " failed, continuing anyway", e);
         }
 
+        // Cleanup gatekeeper secure user id
+        try {
+            final IGateKeeperService gk = GateKeeper.getService();
+            if (gk != null) {
+                gk.clearSecureUserId(userHandle);
+            }
+        } catch (Exception ex) {
+            Slog.w(LOG_TAG, "unable to clear GK secure user id");
+        }
+
         // Cleanup package manager settings
         mPm.cleanUpUser(this, userHandle);
+
+        // Clean up all data before removing metadata
+        mPm.destroyUserData(userHandle,
+                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+
         // Remove this user from the list
         synchronized (mUsersLock) {
             mUsers.remove(userHandle);
@@ -2503,12 +2549,6 @@
         AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
         userFile.delete();
         updateUserIds();
-
-        // Now that we've purged all the metadata above, destroy the actual data
-        // on disk; if we battery pull in here we'll finish cleaning up when
-        // reconciling after reboot.
-        mPm.destroyUserData(userHandle,
-                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
     }
 
     private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 1bbb9f5..ad87a88 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -43,6 +43,9 @@
 
     /**
      * Set the current VR mode state.
+     * <p/>
+     * This may delay the mode change slightly during application transitions to avoid frequently
+     * tearing down VrListenerServices unless necessary.
      *
      * @param enabled {@code true} to enable VR mode.
      * @param packageName The package name of the requested VrListenerService to bind.
@@ -52,6 +55,18 @@
     public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName,
             int userId, @NonNull ComponentName calling);
 
+    /**
+     * Set the current VR mode state immediately.
+     *
+     * @param enabled {@code true} to enable VR mode.
+     * @param packageName The package name of the requested VrListenerService to bind.
+     * @param userId the user requesting the VrListenerService component.
+     * @param calling the component currently using VR mode, or null to leave unchanged.
+     */
+    public abstract void setVrModeImmediate(boolean enabled, @NonNull ComponentName packageName,
+            int userId, @NonNull ComponentName calling);
+
+
    /**
     * Return NO_ERROR if the given package is installed on the device and enabled as a
     * VrListenerService for the given current user, or a negative error code indicating a failure.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index b4c4bd8..5fefd4c 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -218,7 +218,6 @@
                     String packageName = mNotificationAccessPackageToUserId.keyAt(i);
                     revokeNotificationListenerAccess(packageName, grantUserId);
                     revokeNotificationPolicyAccess(packageName);
-                    revokeCoarseLocationPermissionIfNeeded(packageName, grantUserId);
                     mNotificationAccessPackageToUserId.removeAt(i);
                 }
             }
@@ -227,7 +226,6 @@
                 if (!packageNames.contains(pkg)) {
                     revokeNotificationListenerAccess(pkg, currentUserId);
                     revokeNotificationPolicyAccess(pkg);
-                    revokeCoarseLocationPermissionIfNeeded(pkg, currentUserId);
                     mNotificationAccessPackageToUserId.remove(pkg);
                 }
             }
@@ -235,7 +233,6 @@
                 if (!allowed.contains(pkg)) {
                     grantNotificationPolicyAccess(pkg);
                     grantNotificationListenerAccess(pkg, currentUserId);
-                    grantCoarseLocationPermissionIfNeeded(pkg, currentUserId);
                     mNotificationAccessPackageToUserId.put(pkg, currentUserId);
                 }
             }
@@ -373,7 +370,13 @@
         @Override
         public void setVrMode(boolean enabled, ComponentName packageName, int userId,
                 ComponentName callingPackage) {
-            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
+            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, false);
+        }
+
+        @Override
+        public void setVrModeImmediate(boolean enabled, ComponentName packageName, int userId,
+                ComponentName callingPackage) {
+            VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage, true);
         }
 
         @Override
@@ -754,22 +757,6 @@
                 flatSettings, userId);
     }
 
-    private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
-        // Don't clobber the user if permission set in current state explicitly
-        if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
-            mContext.getPackageManager().grantRuntimePermission(pkg,
-                    Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
-        }
-    }
-
-    private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
-        // Don't clobber the user if permission set in current state explicitly
-        if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
-            mContext.getPackageManager().revokeRuntimePermission(pkg,
-                    Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
-        }
-    }
-
     private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
         final int flags = mContext.getPackageManager().getPermissionFlags(
                 permission, pkg, new UserHandle(userId));
@@ -916,11 +903,11 @@
      */
 
     private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
-            int userId, @NonNull ComponentName callingPackage) {
+            int userId, @NonNull ComponentName callingPackage, boolean immediate) {
 
         synchronized (mLock) {
 
-            if (!enabled && mCurrentVrService != null) {
+            if (!enabled && mCurrentVrService != null && !immediate) {
                 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
                 // and service bind/unbind in case we are immediately switching to another VR app.
                 if (mPendingState == null) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 1ae1a77..b53933e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -120,7 +120,7 @@
             // First, try to read from the legacy file.
             final File legacy = getLegacyConfigFileWithTestOverride();
 
-            final List<UserInfo> users = mUserManager.getUsers();
+            final List<UserInfo> users = mUserManager.getUsers(true);
 
             if (readLegacyOwnerFileLocked(legacy)) {
                 if (DEBUG) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b21f5fb..8f8ba1d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -475,7 +475,7 @@
         }
 
         traceBeginAndSlog("StartUserManagerService");
-        ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
+        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
         Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
         // Initialize attribute cache used to cache resources from packages.
diff --git a/services/tests/servicestests/res/xml/shortcut_5_reverse.xml b/services/tests/servicestests/res/xml/shortcut_5_reverse.xml
new file mode 100644
index 0000000..3d6eb22
--- /dev/null
+++ b/services/tests/servicestests/res/xml/shortcut_5_reverse.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+    <shortcut
+        android:shortcutId="ms5"
+        android:enabled="true"
+        android:shortcutIcon="@drawable/icon1"
+        android:shortcutShortLabel="@string/shortcut_title1"
+        android:shortcutLongLabel="@string/shortcut_text1"
+        android:shortcutDisabledMessage="@string/shortcut_disabled_message1"
+        android:shortcutCategories="android.shortcut.conversation:android.shortcut.media"
+        android:shortcutIntentAction="action1"
+        android:shortcutIntentData="http://a.b.c/1"
+    />
+    <shortcut
+        android:shortcutId="ms4"
+        android:enabled="true"
+        android:shortcutIcon="@drawable/icon2"
+        android:shortcutShortLabel="@string/shortcut_title2"
+        android:shortcutLongLabel="@string/shortcut_text2"
+        android:shortcutDisabledMessage="@string/shortcut_disabled_message2"
+        android:shortcutCategories="android.shortcut.conversation"
+        android:shortcutIntentAction="action2"
+    />
+    <shortcut
+        android:shortcutId="ms3"
+        android:shortcutShortLabel="@string/shortcut_title1"
+        android:shortcutIntentAction="android.intent.action.VIEW"
+    />
+    <shortcut
+        android:shortcutId="ms2"
+        android:shortcutShortLabel="@string/shortcut_title1"
+        android:shortcutIntentAction="android.intent.action.VIEW"
+    />
+    <shortcut
+        android:shortcutId="ms1"
+        android:shortcutShortLabel="@string/shortcut_title1"
+        android:shortcutIntentAction="android.intent.action.VIEW"
+    />
+</shortcuts>
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 2f11967..69152d4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -742,6 +742,9 @@
         if (mService != null) {
             // Flush all the unsaved data from the previous instance.
             mService.saveDirtyInfo();
+
+            // Make sure everything is consistent.
+            mService.verifyStates();
         }
         LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index fe2d1ec..fc1ebbe 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -45,6 +45,7 @@
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertEmpty;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertShortcutIds;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.filterByActivity;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.findShortcut;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
@@ -71,7 +72,6 @@
 import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.ShortcutInfo;
-import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.BitmapFactory;
@@ -79,7 +79,6 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.Process;
 import android.os.UserHandle;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
@@ -969,23 +968,34 @@
         // Set up shortcuts.
 
         setCaller(CALLING_PACKAGE_1);
-        final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 5000);
-        final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 1000);
+        final ShortcutInfo s1_1 = makeShortcut("s1");
+        final ShortcutInfo s1_2 = makeShortcut("s2");
 
         assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
 
+        // Because setDynamicShortcuts will update the timestamps when ranks are changing,
+        // we explicitly set timestamps here.
+        getCallerShortcut("s1").setTimestamp(5000);
+        getCallerShortcut("s2").setTimestamp(1000);
+
         setCaller(CALLING_PACKAGE_2);
-        final ShortcutInfo s2_2 = makeShortcutWithTimestamp("s2", 1500);
-        final ShortcutInfo s2_3 = makeShortcutWithTimestampWithActivity("s3", 3000,
+        final ShortcutInfo s2_2 = makeShortcut("s2");
+        final ShortcutInfo s2_3 = makeShortcutWithActivity("s3",
                 makeComponent(ShortcutActivity2.class));
-        final ShortcutInfo s2_4 = makeShortcutWithTimestampWithActivity("s4", 500,
+        final ShortcutInfo s2_4 = makeShortcutWithActivity("s4",
                 makeComponent(ShortcutActivity.class));
         assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
 
+        getCallerShortcut("s2").setTimestamp(1500);
+        getCallerShortcut("s3").setTimestamp(3000);
+        getCallerShortcut("s4").setTimestamp(500);
+
         setCaller(CALLING_PACKAGE_3);
-        final ShortcutInfo s3_2 = makeShortcutWithTimestamp("s3", START_TIME + 5000);
+        final ShortcutInfo s3_2 = makeShortcut("s3");
         assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
 
+        getCallerShortcut("s3").setTimestamp(START_TIME + 5000);
+
         setCaller(LAUNCHER_1);
 
         // Get dynamic
@@ -4606,7 +4616,6 @@
         assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_0));
     }
 
-
     public void testManifestShortcut_publishOnBroadcast() {
         // First, no packages are installed.
         uninstallPackage(USER_0, CALLING_PACKAGE_1);
@@ -4677,6 +4686,10 @@
             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
                     mManager.getManifestShortcuts()))),
                     "ms1", "ms2", "ms3", "ms4", "ms5");
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
+                    .haveRanksInOrder("ms1", "ms2", "ms3", "ms4", "ms5");
             assertEmpty(mManager.getPinnedShortcuts());
         });
 
@@ -4710,6 +4723,10 @@
             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
                     mManager.getManifestShortcuts()))),
                     "ms1", "ms2");
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
+                    .haveRanksInOrder("ms1", "ms2");
             assertShortcutIds(assertAllImmutable(assertAllPinned(
                     mManager.getPinnedShortcuts())),
                     "ms2", "ms3");
@@ -4733,6 +4750,10 @@
             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
                     mManager.getManifestShortcuts()))),
                     "ms1", "ms2");
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
+                    .haveRanksInOrder("ms1", "ms2");
             assertEmpty(mManager.getPinnedShortcuts());
         });
 
@@ -4741,6 +4762,10 @@
             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
                     mManager.getManifestShortcuts()))),
                     "ms1", "ms2");
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
+                    .haveRanksInOrder("ms1", "ms2");
             assertShortcutIds(assertAllImmutable(assertAllPinned(
                     mManager.getPinnedShortcuts())),
                     "ms2", "ms3");
@@ -4749,10 +4774,43 @@
             assertAllDisabled(list(getCallerShortcut("ms3")));
         });
 
+        // Multiple activities.
+        // Add shortcuts on activity 2 for package 2.
+        addManifestShortcutResource(
+                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
+                R.xml.shortcut_5_alt);
+        addManifestShortcutResource(
+                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()),
+                R.xml.shortcut_5_reverse);
+
+        updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
+
+        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+            assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
+                    mManager.getManifestShortcuts()))),
+                    "ms1", "ms2", "ms3", "ms4", "ms5",
+                    "ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
+
+            // Make sure they have the correct ranks, regardless of their ID's alphabetical order.
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()))
+                    .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()))
+                    .haveRanksInOrder("ms5", "ms4", "ms3", "ms2", "ms1");
+        });
+
         // Package 2 now has no manifest shortcuts.
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
                 R.xml.shortcut_0);
+        addManifestShortcutResource(
+                new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()),
+                R.xml.shortcut_0);
         updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
         mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
@@ -5128,7 +5186,7 @@
         // ShortcutActivity2 has two shortcuts, ms1 and ms2.
         addManifestShortcutResource(
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
-                R.xml.shortcut_2);
+                R.xml.shortcut_5);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
         mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
@@ -5136,13 +5194,14 @@
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
                     mManager.getManifestShortcuts()))),
-                    "ms1", "ms2");
+                    "ms1", "ms2", "ms3", "ms4", "ms5");
 
             // ms1 should belong to ShortcutActivity.
             ShortcutInfo si = getCallerShortcut("ms1");
             assertEquals(R.string.shortcut_title1, si.getTitleResId());
             assertEquals(new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                     si.getActivity());
+            assertEquals(0, si.getRank());
 
             // ms2 should belong to ShortcutActivity*2*.
             si = getCallerShortcut("ms2");
@@ -5150,8 +5209,18 @@
             assertEquals(new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
                     si.getActivity());
 
+            // Also check the ranks
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()))
+                    .haveRanksInOrder("ms1");
+            assertWith(getCallerShortcuts()).selectManifest()
+                    .selectByActivity(
+                            new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()))
+                    .haveRanksInOrder("ms2", "ms3", "ms4", "ms5");
+
             // Make sure there's no other dangling shortcuts.
-            assertShortcutIds(getCallerShortcuts(), "ms1", "ms2");
+            assertShortcutIds(getCallerShortcuts(), "ms1", "ms2", "ms3", "ms4", "ms5");
         });
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index ea44462..8e32d6a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -533,6 +533,7 @@
         si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
                 .setActivity(new ComponentName("x", "y")).build());
         assertEquals("text", si.getText());
+        assertEquals(123, si.getRank());
         assertEquals(new ComponentName("x", "y"), si.getActivity());
 
         si = sorig.clone(/* flags=*/ 0);
@@ -627,16 +628,6 @@
                 .setExtras(pb2).build());
         assertEquals("text", si.getText());
         assertEquals(99, si.getExtras().getInt("x"));
-
-        // Make sure the timestamp gets updated too.
-
-        final long timestamp = si.getLastChangedTimestamp();
-        Thread.sleep(2);
-
-        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
-                .setTitle("xyz").build());
-
-        assertTrue(si.getLastChangedTimestamp() > timestamp);
     }
 
     public void testShortcutInfoCopyNonNullFieldsFrom_resId() throws InterruptedException {
@@ -764,16 +755,6 @@
                 .setExtras(pb2).build());
         assertEquals(11, si.getTextResId());
         assertEquals(99, si.getExtras().getInt("x"));
-
-        // Make sure the timestamp gets updated too.
-
-        final long timestamp = si.getLastChangedTimestamp();
-        Thread.sleep(2);
-
-        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
-                .setTitle("xyz").build());
-
-        assertTrue(si.getLastChangedTimestamp() > timestamp);
     }
 
     public void testShortcutInfoSaveAndLoad() throws InterruptedException {
@@ -797,7 +778,15 @@
                 .setExtras(pb)
                 .build();
 
-        mManager.addDynamicShortcuts(list(sorig));
+        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+                .setId("id2")
+                .setTitle("x")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(456)
+                .build();
+
+        mManager.addDynamicShortcuts(list(sorig, sorig2));
 
         Thread.sleep(2);
         final long now = System.currentTimeMillis();
@@ -822,7 +811,7 @@
         assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
         assertEquals("action", si.getIntent().getAction());
         assertEquals("val", si.getIntent().getStringExtra("key"));
-        assertEquals(123, si.getRank());
+        assertEquals(0, si.getRank());
         assertEquals(1, si.getExtras().getInt("k"));
 
         assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE
@@ -830,6 +819,11 @@
         assertNotNull(si.getBitmapPath()); // Something should be set.
         assertEquals(0, si.getIconResourceId());
         assertTrue(si.getLastChangedTimestamp() < now);
+
+        // Make sure ranks are saved too.  Because of the auto-adjusting, we need two shortcuts
+        // to test it.
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
+        assertEquals(1, si.getRank());
     }
 
     public void testShortcutInfoSaveAndLoad_resId() throws InterruptedException {
@@ -852,7 +846,15 @@
                 .setExtras(pb)
                 .build();
 
-        mManager.addDynamicShortcuts(list(sorig));
+        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+                .setId("id2")
+                .setTitle("x")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(456)
+                .build();
+
+        mManager.addDynamicShortcuts(list(sorig, sorig2));
 
         Thread.sleep(2);
         final long now = System.currentTimeMillis();
@@ -880,7 +882,7 @@
         assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
         assertEquals("action", si.getIntent().getAction());
         assertEquals("val", si.getIntent().getStringExtra("key"));
-        assertEquals(123, si.getRank());
+        assertEquals(0, si.getRank());
         assertEquals(1, si.getExtras().getInt("k"));
 
         assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_RES
@@ -888,6 +890,11 @@
         assertNull(si.getBitmapPath());
         assertEquals(R.drawable.black_32x32, si.getIconResourceId());
         assertTrue(si.getLastChangedTimestamp() < now);
+
+        // Make sure ranks are saved too.  Because of the auto-adjusting, we need two shortcuts
+        // to test it.
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
+        assertEquals(1, si.getRank());
     }
 
     public void testShortcutInfoSaveAndLoad_forBackup() {
@@ -911,11 +918,19 @@
                 .setExtras(pb)
                 .build();
 
-        mManager.addDynamicShortcuts(list(sorig));
+        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+                .setId("id2")
+                .setTitle("x")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(456)
+                .build();
+
+        mManager.addDynamicShortcuts(list(sorig, sorig2));
 
         // Dynamic shortcuts won't be backed up, so we need to pin it.
         setCaller(LAUNCHER_1, USER_0);
-        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
+        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
 
         // Do backup & restore.
         backupAndRestore();
@@ -935,12 +950,16 @@
         assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
         assertEquals("action", si.getIntent().getAction());
         assertEquals("val", si.getIntent().getStringExtra("key"));
-        assertEquals(123, si.getRank());
+        assertEquals(0, si.getRank());
         assertEquals(1, si.getExtras().getInt("k"));
 
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
         assertNull(si.getBitmapPath()); // No icon.
         assertEquals(0, si.getIconResourceId());
+
+        // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
+        assertEquals(0, si.getRank());
     }
 
     public void testShortcutInfoSaveAndLoad_forBackup_resId() {
@@ -963,11 +982,19 @@
                 .setExtras(pb)
                 .build();
 
-        mManager.addDynamicShortcuts(list(sorig));
+        ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+                .setId("id2")
+                .setTitle("x")
+                .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+                .setRank(456)
+                .build();
+
+        mManager.addDynamicShortcuts(list(sorig, sorig2));
 
         // Dynamic shortcuts won't be backed up, so we need to pin it.
         setCaller(LAUNCHER_1, USER_0);
-        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
+        mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
 
         // Do backup & restore.
         backupAndRestore();
@@ -990,13 +1017,17 @@
         assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
         assertEquals("action", si.getIntent().getAction());
         assertEquals("val", si.getIntent().getStringExtra("key"));
-        assertEquals(123, si.getRank());
+        assertEquals(0, si.getRank());
         assertEquals(1, si.getExtras().getInt("k"));
 
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
         assertNull(si.getBitmapPath()); // No icon.
         assertEquals(0, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
+
+        // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
+        si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
+        assertEquals(0, si.getRank());
     }
 
     public void testThrottling() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
new file mode 100644
index 0000000..eb4db7a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
@@ -0,0 +1,505 @@
+/*
+ * 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.server.pm;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+
+import android.content.ComponentName;
+import android.content.pm.ShortcutInfo;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.frameworks.servicestests.R;
+import com.android.server.pm.ShortcutService.ConfigConstants;
+
+/**
+ * Tests related to shortcut rank auto-adjustment.
+ */
+@SmallTest
+public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
+
+    private static final String CALLING_PACKAGE = CALLING_PACKAGE_1;
+
+    private static final ComponentName A1 = new ComponentName(CALLING_PACKAGE,
+            ShortcutActivity.class.getName());
+
+    private static final ComponentName A2 = new ComponentName(CALLING_PACKAGE,
+            ShortcutActivity2.class.getName());
+
+    private static final ComponentName A3 = new ComponentName(CALLING_PACKAGE,
+            ShortcutActivity3.class.getName());
+
+    private ShortcutInfo shortcut(String id, ComponentName activity, int rank) {
+        return makeShortcutWithActivityAndRank(id, activity, rank);
+    }
+
+    private ShortcutInfo shortcut(String id, ComponentName activity) {
+        return makeShortcutWithActivityAndRank(id, activity, ShortcutInfo.RANK_NOT_SET);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // We don't need throttling during this test class, and also relax the max cap.
+        mService.updateConfigurationLocked(
+                ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
+                + ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
+        );
+
+        setCaller(CALLING_PACKAGE, USER_0);
+    }
+
+    private void publishManifestShortcuts(ComponentName activity, int resId) {
+        addManifestShortcutResource(activity, resId);
+        updatePackageVersion(CALLING_PACKAGE, 1);
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageAddIntent(CALLING_PACKAGE, USER_0));
+    }
+
+    public void testSetDynamicShortcuts_noManifestShortcuts() {
+        mManager.setDynamicShortcuts(list(
+                shortcut("s1", A1)
+        ));
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s1");
+
+        assertTrue(mManager.setDynamicShortcuts(list(
+                shortcut("s5", A1),
+                shortcut("s4", A1),
+                shortcut("s3", A1)
+        )));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s4", "s3");
+
+        // RANK_NOT_SET is always the last.
+        assertTrue(mManager.setDynamicShortcuts(list(
+                shortcut("s5", A1),
+                shortcut("s4", A1, 5),
+                shortcut("s3", A1, 3),
+                shortcut("s2", A1)
+        )));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s3", "s4", "s5", "s2");
+
+        // Same rank, preserve the argument order.
+        assertTrue(mManager.setDynamicShortcuts(list(
+                shortcut("s5", A1, 5),
+                shortcut("s4", A1, 0),
+                shortcut("s3", A1, 5)
+        )));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s4", "s5", "s3");
+
+        // Multiple activities.
+        assertTrue(mManager.setDynamicShortcuts(list(
+                shortcut("s5", A1),
+                shortcut("s4", A2),
+                shortcut("s3", A3)
+        )));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5");
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("s4");
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
+                .haveRanksInOrder("s3");
+
+        assertTrue(mManager.setDynamicShortcuts(list(
+                shortcut("s5", A1, 5),
+                shortcut("s4", A1),
+                shortcut("s3", A1, 5),
+                shortcut("x5", A2, 5),
+                shortcut("x4", A2),
+                shortcut("x3", A2, 1)
+        )));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s4");
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x5", "x4");
+
+        // Clear.  Make sure it wouldn't lead to invalid internals state.
+        // (ShortcutService.verifyStates() will do so internally.)
+        assertTrue(mManager.setDynamicShortcuts(list()));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1).isEmpty();
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2).isEmpty();
+    }
+
+    private void runTestWithManifestShortcuts(Runnable r) {
+        publishManifestShortcuts(A1, R.xml.shortcut_5_alt);
+        publishManifestShortcuts(A2, R.xml.shortcut_1);
+
+        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
+                .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
+
+        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
+                .haveRanksInOrder("ms1");
+
+        // Existence of manifest shortcuts shouldn't affect dynamic shortcut ranks,
+        // so running another test here should pass.
+        r.run();
+
+        // And dynamic shortcut tests shouldn't affect manifest shortcuts, so repeat the
+        // same check.
+        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A1)
+                .haveRanksInOrder("ms1_alt", "ms2_alt", "ms3_alt", "ms4_alt", "ms5_alt");
+
+        assertWith(getCallerShortcuts()).selectManifest().selectByActivity(A2)
+                .haveRanksInOrder("ms1");
+    }
+
+    public void testSetDynamicShortcuts_withManifestShortcuts() {
+        runTestWithManifestShortcuts(() -> testSetDynamicShortcuts_noManifestShortcuts());
+    }
+
+    public void testAddDynamicShortcuts_noManifestShortcuts() {
+        mManager.addDynamicShortcuts(list(
+                shortcut("s1", A1)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s1");
+
+        //------------------------------------------------------
+        long lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.addDynamicShortcuts(list(
+                shortcut("s5", A1, 0),
+                shortcut("s4", A1),
+                shortcut("s2", A1, 3),
+                shortcut("x1", A2),
+                shortcut("x3", A2, 2),
+                shortcut("x2", A2, 2),
+                shortcut("s3", A1, 0)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s1", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s5", "s3", "s1", "s2", "s4", "x3", "x2", "x1");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.addDynamicShortcuts(list(
+                shortcut("s1", A1, 1)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s1", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s1", "s3");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.addDynamicShortcuts(list(
+                shortcut("s1", A1, 1),
+
+                // This is add, not update, so the following means s5 will have NO_RANK,
+                // which puts it at the end.
+                shortcut("s5", A1),
+                shortcut("s3", A1, 0),
+
+                // s10 also has NO_RANK, so it'll be put at the end, even after "s5" as we preserve
+                // the argument order.
+                shortcut("s10", A1),
+
+                // Note we're changing the activity for x2.
+                shortcut("x2", A1, 0),
+                shortcut("x10", A2)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s3", "x2", "s1", "s2", "s4", "s5", "s10");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x1", "x10");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s3", "x2", "s1", "s5", "s10", "x1", "x10");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        // Change the activities again.
+        mManager.addDynamicShortcuts(list(
+                shortcut("s1", A2),
+                shortcut("s2", A2, 999)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s3", "x2", "s4", "s5", "s10");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x1", "x10", "s2", "s1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s1", "s2", "s4", "s5", "s10");
+    }
+
+    public void testAddDynamicShortcuts_withManifestShortcuts() {
+        runTestWithManifestShortcuts(() -> testAddDynamicShortcuts_noManifestShortcuts());
+    }
+
+    public void testUpdateShortcuts_noManifestShortcuts() {
+        mManager.addDynamicShortcuts(list(
+                shortcut("s5", A1, 0),
+                shortcut("s4", A1),
+                shortcut("s2", A1, 3),
+                shortcut("x1", A2),
+                shortcut("x3", A2, 2),
+                shortcut("x2", A2, 2),
+                shortcut("s3", A1, 0)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        //------------------------------------------------------
+        long lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.updateShortcuts(list());
+        // Same order.
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .isEmpty();
+
+
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
+        });
+        // Still same order.
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.updateShortcuts(list(
+                shortcut("s4", A1, 1),
+
+                // Rank not changing, should keep the same positions.
+                // c.f. in case of addDynamicShortcuts, this means "put them at the end".
+                shortcut("s3", A1),
+                shortcut("x2", A2)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s4", "s3", "s2");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s4", "s3", "s2", "x2");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.updateShortcuts(list(
+                shortcut("s4", A1, 0),
+
+                // Change the activity without specifying a rank -> keep the same rank.
+                shortcut("s5", A2),
+
+                // Change the activity without specifying a rank -> assign a new rank.
+                shortcut("x2", A1, 2),
+
+                // "xx" doesn't exist, so it'll be ignored.
+                shortcut("xx", A1, 0)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s4", "x2", "s3", "s2");
+
+        // Interesting case: both x3 and s5 originally had rank=0, and in this case s5 has moved
+        // to A2 without changing the rank.  So they're tie for the new rank, as well as
+        // the "rank changed" bit.  Also in this case, "s5" won't have an implicit order, since
+        // its rank isn't changing.  So we sort them by ID, thus s5 comes before x3.
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("s5", "x3", "x1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s4", "x2", "s5", "x3");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.updateShortcuts(list(
+                shortcut("s3", A3)));
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s4", "x2", "s2");
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("s5", "x3", "x1");
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A3)
+                .haveRanksInOrder("s3");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s3", "s2");
+    }
+
+    public void testUpdateShortcuts_withManifestShortcuts() {
+        runTestWithManifestShortcuts(() -> testUpdateShortcuts_noManifestShortcuts());
+    }
+
+    public void testDeleteDynamicShortcuts_noManifestShortcuts() {
+        mManager.addDynamicShortcuts(list(
+                shortcut("s5", A1, 0),
+                shortcut("s4", A1),
+                shortcut("s2", A1, 3),
+                shortcut("x1", A2),
+                shortcut("x3", A2, 2),
+                shortcut("x2", A2, 2),
+                shortcut("s3", A1, 0)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        //------------------------------------------------------
+        long lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.removeDynamicShortcuts(list());
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .isEmpty();
+
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            mLauncherApps.pinShortcuts(
+                    CALLING_PACKAGE, list("s2", "s4", "x1", "x2"), HANDLE_USER_0);
+        });
+        // Still same order.
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.removeDynamicShortcuts(list("s3", "x1", "xxxx"));
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s2", "s4");
+    }
+
+    public void testDeleteDynamicShortcuts_withManifestShortcuts() {
+        runTestWithManifestShortcuts(() -> testDeleteDynamicShortcuts_noManifestShortcuts());
+    }
+
+    public void testDisableShortcuts_noManifestShortcuts() {
+        mManager.addDynamicShortcuts(list(
+                shortcut("s5", A1, 0),
+                shortcut("s4", A1),
+                shortcut("s2", A1, 3),
+                shortcut("x1", A2),
+                shortcut("x3", A2, 2),
+                shortcut("x2", A2, 2),
+                shortcut("s3", A1, 0)
+        ));
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        //------------------------------------------------------
+        long lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.disableShortcuts(list());
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s3", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2", "x1");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .isEmpty();
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.disableShortcuts(list("s3", "x1", "xxxx"));
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s2", "s4");
+
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
+        });
+        // Still same order.
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s2", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x3", "x2");
+
+        //------------------------------------------------------
+        lastApiTime = ++mInjectedCurrentTimeMillis;
+
+        mManager.disableShortcuts(list("s2", "x3"));
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
+                .haveRanksInOrder("s5", "s4");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A2)
+                .haveRanksInOrder("x2");
+
+        assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
+                .haveIds("s4", "x2");
+    }
+
+    public void testDisableShortcuts_withManifestShortcuts() {
+        runTestWithManifestShortcuts(() -> testDisableShortcuts_noManifestShortcuts());
+    }
+
+}
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 04c7a04..7ba4c68 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -58,9 +58,13 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
 import java.util.function.BooleanSupplier;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -72,10 +76,12 @@
 public class ShortcutManagerTestUtils {
     private static final String TAG = "ShortcutManagerUtils";
 
-    private static final boolean ENABLE_DUMPSYS = true; // DO NOT SUBMIT WITH true
+    private static final boolean ENABLE_DUMPSYS = false; // DO NOT SUBMIT WITH true
 
     private static final int STANDARD_TIMEOUT_SEC = 5;
 
+    private static final String[] EMPTY_STRINGS = new String[0];
+
     private ShortcutManagerTestUtils() {
     }
 
@@ -228,7 +234,7 @@
     }
 
     public static <T> Set<T> hashSet(Set<T> in) {
-        return new HashSet<T>(in);
+        return new LinkedHashSet<>(in);
     }
 
     public static <T> Set<T> set(T... values) {
@@ -240,7 +246,7 @@
     }
 
     public static <T, V> Set<T> set(Function<V, T> converter, List<V> values) {
-        final HashSet<T> ret = new HashSet<>();
+        final LinkedHashSet<T> ret = new LinkedHashSet<>();
         for (V v : values) {
             ret.add(converter.apply(v));
         }
@@ -258,15 +264,21 @@
         return list;
     }
 
+    public static List<ShortcutInfo> filter(List<ShortcutInfo> list, Predicate<ShortcutInfo> p) {
+        final ArrayList<ShortcutInfo> ret = new ArrayList<>(list);
+        ret.removeIf(si -> !p.test(si));
+        return ret;
+    }
+
     public static List<ShortcutInfo> filterByActivity(List<ShortcutInfo> list,
             ComponentName activity) {
-        final ArrayList<ShortcutInfo> ret = new ArrayList<>();
-        for (ShortcutInfo si : list) {
-            if (si.getActivity().equals(activity) && (si.isManifestShortcut() || si.isDynamic())) {
-                ret.add(si);
-            }
-        }
-        return ret;
+        return filter(list, si ->
+                (si.getActivity().equals(activity)
+                        && (si.isManifestShortcut() || si.isDynamic())));
+    }
+
+    public static List<ShortcutInfo> changedSince(List<ShortcutInfo> list, long time) {
+        return filter(list, si -> si.getLastChangedTimestamp() >= time);
     }
 
     public static void assertExpectException(Class<? extends Throwable> expectedExceptionType,
@@ -305,8 +317,8 @@
 
     public static List<ShortcutInfo> assertShortcutIds(List<ShortcutInfo> actualShortcuts,
             String... expectedIds) {
-        final HashSet<String> expected = new HashSet<>(list(expectedIds));
-        final HashSet<String> actual = new HashSet<>();
+        final SortedSet<String> expected = new TreeSet<>(list(expectedIds));
+        final SortedSet<String> actual = new TreeSet<>();
         for (ShortcutInfo s : actualShortcuts) {
             actual.add(s.getId());
         }
@@ -316,6 +328,17 @@
         return actualShortcuts;
     }
 
+    public static List<ShortcutInfo> assertShortcutIdsOrdered(List<ShortcutInfo> actualShortcuts,
+            String... expectedIds) {
+        final ArrayList<String> expected = new ArrayList<>(list(expectedIds));
+        final ArrayList<String> actual = new ArrayList<>();
+        for (ShortcutInfo s : actualShortcuts) {
+            actual.add(s.getId());
+        }
+        assertEquals(expected, actual);
+        return actualShortcuts;
+    }
+
     public static List<ShortcutInfo> assertAllHaveIntents(
             List<ShortcutInfo> actualShortcuts) {
         for (ShortcutInfo s : actualShortcuts) {
@@ -482,7 +505,7 @@
     }
 
     public static <T> void assertAllUnique(Collection<T> list) {
-        final Set<Object> set = new HashSet<>();
+        final Set<Object> set = new LinkedHashSet<>();
         for (T item : list) {
             if (set.contains(item)) {
                 fail("Duplicate item found: " + item + " (in the list: " + list + ")");
@@ -594,6 +617,15 @@
         return ret;
     }
 
+    private static final Comparator<ShortcutInfo> sRankComparator =
+            (ShortcutInfo a, ShortcutInfo b) -> Integer.compare(a.getRank(), b.getRank());
+
+    public static List<ShortcutInfo> sortedByRank(List<ShortcutInfo> shortcuts) {
+        final ArrayList<ShortcutInfo> ret = new ArrayList<>(shortcuts);
+        Collections.sort(ret, sRankComparator);
+        return ret;
+    }
+
     public static void waitUntil(String message, BooleanSupplier condition) {
         waitUntil(message, condition, STANDARD_TIMEOUT_SEC);
     }
@@ -612,4 +644,78 @@
         }
         fail("Timed out for: " + message);
     }
+
+    public static ShortcutListAsserter assertWith(List<ShortcutInfo> list) {
+        return new ShortcutListAsserter(list);
+    }
+
+    /**
+     * New style assertion that allows chained calls.
+     */
+    public static class ShortcutListAsserter {
+        private final List<ShortcutInfo> mList;
+
+        ShortcutListAsserter(List<ShortcutInfo> list) {
+            mList = new ArrayList<>(list);
+        }
+
+        public ShortcutListAsserter selectDynamic() {
+            return new ShortcutListAsserter(
+                    filter(mList, ShortcutInfo::isDynamic));
+        }
+
+        public ShortcutListAsserter selectManifest() {
+            return new ShortcutListAsserter(
+                    filter(mList, ShortcutInfo::isManifestShortcut));
+        }
+
+        public ShortcutListAsserter selectPinned() {
+            return new ShortcutListAsserter(
+                    filter(mList, ShortcutInfo::isPinned));
+        }
+
+        public ShortcutListAsserter selectByActivity(ComponentName activity) {
+            return new ShortcutListAsserter(
+                    ShortcutManagerTestUtils.filterByActivity(mList, activity));
+        }
+
+        public ShortcutListAsserter selectByChangedSince(long time) {
+            return new ShortcutListAsserter(
+                    ShortcutManagerTestUtils.changedSince(mList, time));
+        }
+
+        public ShortcutListAsserter toSortByRank() {
+            return new ShortcutListAsserter(
+                    ShortcutManagerTestUtils.sortedByRank(mList));
+        }
+
+        public ShortcutListAsserter haveIds(String... expectedIds) {
+            assertShortcutIds(mList, expectedIds);
+            return this;
+        }
+
+        public ShortcutListAsserter haveIdsOrdered(String... expectedIds) {
+            assertShortcutIdsOrdered(mList, expectedIds);
+            return this;
+        }
+
+        private ShortcutListAsserter haveSequentialRanks() {
+            for (int i = 0; i < mList.size(); i++) {
+                assertEquals("Rank not sequential", i, mList.get(i).getRank());
+            }
+            return this;
+        }
+
+        public ShortcutListAsserter haveRanksInOrder(String... expectedIds) {
+            toSortByRank()
+                    .haveSequentialRanks()
+                    .haveIdsOrdered(expectedIds);
+            return this;
+        }
+
+        public ShortcutListAsserter isEmpty() {
+            assertEquals(0, mList.size());
+            return this;
+        }
+    }
 }
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index be04c90..0eabf15 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -83,6 +83,7 @@
     private StatusHints mStatusHints;
     private Bundle mExtras;
     private Set<String> mPreviousExtraKeys;
+    private final Object mExtrasLock = new Object();
 
     private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
         @Override
@@ -687,32 +688,35 @@
      * to remove extras.
      */
     public final void setExtras(@Nullable Bundle extras) {
-        // Add/replace any new or changed extras values.
-        putExtras(extras);
+        // Keeping putExtras and removeExtras in the same lock so that this operation happens as a
+        // block instead of letting other threads put/remove while this method is running.
+        synchronized (mExtrasLock) {
+            // Add/replace any new or changed extras values.
+            putExtras(extras);
+            // If we have used "setExtras" in the past, compare the key set from the last invocation
+            // to the current one and remove any keys that went away.
+            if (mPreviousExtraKeys != null) {
+                List<String> toRemove = new ArrayList<String>();
+                for (String oldKey : mPreviousExtraKeys) {
+                    if (extras == null || !extras.containsKey(oldKey)) {
+                        toRemove.add(oldKey);
+                    }
+                }
 
-        // If we have used "setExtras" in the past, compare the key set from the last invocation to
-        // the current one and remove any keys that went away.
-        if (mPreviousExtraKeys != null) {
-            List<String> toRemove = new ArrayList<String>();
-            for (String oldKey : mPreviousExtraKeys) {
-                if (extras == null || !extras.containsKey(oldKey)) {
-                    toRemove.add(oldKey);
+                if (!toRemove.isEmpty()) {
+                    removeExtras(toRemove);
                 }
             }
 
-            if (!toRemove.isEmpty()) {
-                removeExtras(toRemove);
+            // Track the keys the last time set called setExtras.  This way, the next time setExtras
+            // is called we can see if the caller has removed any extras values.
+            if (mPreviousExtraKeys == null) {
+                mPreviousExtraKeys = new ArraySet<String>();
             }
-        }
-
-        // Track the keys the last time set called setExtras.  This way, the next time setExtras is
-        // called we can see if the caller has removed any extras values.
-        if (mPreviousExtraKeys == null) {
-            mPreviousExtraKeys = new ArraySet<String>();
-        }
-        mPreviousExtraKeys.clear();
-        if (extras != null) {
-            mPreviousExtraKeys.addAll(extras.keySet());
+            mPreviousExtraKeys.clear();
+            if (extras != null) {
+                mPreviousExtraKeys.addAll(extras.keySet());
+            }
         }
     }
 
@@ -730,13 +734,19 @@
             return;
         }
 
-        if (mExtras == null) {
-            mExtras = new Bundle();
+        // Creating a Bundle clone so we don't have to synchronize on mExtrasLock while calling
+        // onExtrasChanged.
+        Bundle listenersBundle;
+        synchronized (mExtrasLock) {
+            if (mExtras == null) {
+                mExtras = new Bundle();
+            }
+            mExtras.putAll(extras);
+            listenersBundle = new Bundle(mExtras);
         }
-        mExtras.putAll(extras);
 
         for (Listener l : mListeners) {
-            l.onExtrasChanged(this, extras);
+            l.onExtrasChanged(this, new Bundle(listenersBundle));
         }
     }
 
@@ -789,17 +799,17 @@
             return;
         }
 
-        if (mExtras != null) {
-            for (String key : keys) {
-                mExtras.remove(key);
-            }
-            if (mExtras.size() == 0) {
-                mExtras = null;
+        synchronized (mExtrasLock) {
+            if (mExtras != null) {
+                for (String key : keys) {
+                    mExtras.remove(key);
+                }
             }
         }
 
+        List<String> unmodifiableKeys = Collections.unmodifiableList(keys);
         for (Listener l : mListeners) {
-            l.onExtrasRemoved(this, keys);
+            l.onExtrasRemoved(this, unmodifiableKeys);
         }
     }
 
@@ -849,7 +859,13 @@
      * @hide
      */
     final void handleExtrasChanged(Bundle extras) {
-        mExtras = extras;
-        onExtrasChanged(mExtras);
+        Bundle b = null;
+        synchronized (mExtrasLock) {
+            mExtras = extras;
+            if (mExtras != null) {
+                b = new Bundle(mExtras);
+            }
+        }
+        onExtrasChanged(b);
     }
 }
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index c96f7c0..5843fbb 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1243,6 +1243,7 @@
     private Conference mConference;
     private ConnectionService mConnectionService;
     private Bundle mExtras;
+    private final Object mExtrasLock = new Object();
 
     /**
      * Tracks the key set for the extras bundle provided on the last invocation of
@@ -1401,7 +1402,13 @@
      * @return The extras associated with this connection.
      */
     public final Bundle getExtras() {
-        return mExtras;
+        Bundle extras = null;
+        synchronized (mExtrasLock) {
+            if (mExtras != null) {
+                extras = new Bundle(mExtras);
+            }
+        }
+        return extras;
     }
 
     /**
@@ -1936,14 +1943,20 @@
         if (extras == null) {
             return;
         }
-
-        if (mExtras == null) {
-            mExtras = new Bundle();
+        // Creating a duplicate bundle so we don't have to synchronize on mExtrasLock while calling
+        // the listeners.
+        Bundle listenerExtras;
+        synchronized (mExtrasLock) {
+            if (mExtras == null) {
+                mExtras = new Bundle();
+            }
+            mExtras.putAll(extras);
+            listenerExtras = new Bundle(mExtras);
         }
-        mExtras.putAll(extras);
-
         for (Listener l : mListeners) {
-            l.onExtrasChanged(this, extras);
+            // Create a new clone of the extras for each listener so that they don't clobber
+            // each other
+            l.onExtrasChanged(this, new Bundle(listenerExtras));
         }
     }
 
@@ -1992,18 +2005,16 @@
      * @param keys The keys of the extras to remove.
      */
     public final void removeExtras(List<String> keys) {
-        if (mExtras != null) {
-            for (String key : keys) {
-                mExtras.remove(key);
-            }
-
-            if (mExtras.size() == 0) {
-                mExtras = null;
+        synchronized (mExtrasLock) {
+            if (mExtras != null) {
+                for (String key : keys) {
+                    mExtras.remove(key);
+                }
             }
         }
-
+        List<String> unmodifiableKeys = Collections.unmodifiableList(keys);
         for (Listener l : mListeners) {
-            l.onExtrasRemoved(this, keys);
+            l.onExtrasRemoved(this, unmodifiableKeys);
         }
     }
 
@@ -2291,8 +2302,14 @@
      * @hide
      */
     final void handleExtrasChanged(Bundle extras) {
-        mExtras = extras;
-        onExtrasChanged(mExtras);
+        Bundle b = null;
+        synchronized (mExtrasLock) {
+            mExtras = extras;
+            if (mExtras != null) {
+                b = new Bundle(mExtras);
+            }
+        }
+        onExtrasChanged(b);
     }
 
     /**
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index e7c9672..0ee9bab 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -20,11 +20,168 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @hide
  */
 @SystemApi
 public class ParcelableCallAnalytics implements Parcelable {
+    public static final class AnalyticsEvent implements Parcelable {
+        public static final int SET_SELECT_PHONE_ACCOUNT = 0;
+        public static final int SET_ACTIVE = 1;
+        public static final int SET_DISCONNECTED = 2;
+        public static final int START_CONNECTION = 3;
+        public static final int SET_DIALING = 4;
+        public static final int BIND_CS = 5;
+        public static final int CS_BOUND = 6;
+        public static final int REQUEST_ACCEPT = 7;
+        public static final int REQUEST_REJECT = 8;
+
+        public static final int SCREENING_SENT = 100;
+        public static final int SCREENING_COMPLETED = 101;
+        public static final int DIRECT_TO_VM_INITIATED = 102;
+        public static final int DIRECT_TO_VM_FINISHED = 103;
+        public static final int BLOCK_CHECK_INITIATED = 104;
+        public static final int BLOCK_CHECK_FINISHED = 105;
+        public static final int FILTERING_INITIATED = 106;
+        public static final int FILTERING_COMPLETED = 107;
+        public static final int FILTERING_TIMED_OUT = 108;
+
+        public static final int SKIP_RINGING = 200;
+        public static final int SILENCE = 201;
+        public static final int MUTE = 202;
+        public static final int UNMUTE = 203;
+        public static final int AUDIO_ROUTE_BT = 204;
+        public static final int AUDIO_ROUTE_EARPIECE = 205;
+        public static final int AUDIO_ROUTE_HEADSET = 206;
+        public static final int AUDIO_ROUTE_SPEAKER = 207;
+
+        public static final int CONFERENCE_WITH = 300;
+        public static final int SPLIT_CONFERENCE = 301;
+        public static final int SET_PARENT = 302;
+
+        public static final int REQUEST_HOLD = 400;
+        public static final int REQUEST_UNHOLD = 401;
+        public static final int REMOTELY_HELD = 402;
+        public static final int REMOTELY_UNHELD = 403;
+        public static final int SET_HOLD = 404;
+        public static final int SWAP = 405;
+
+        public static final int REQUEST_PULL = 500;
+
+
+        public static final Parcelable.Creator<AnalyticsEvent> CREATOR =
+                new Parcelable.Creator<AnalyticsEvent> () {
+
+                    @Override
+                    public AnalyticsEvent createFromParcel(Parcel in) {
+                        return new AnalyticsEvent(in);
+                    }
+
+                    @Override
+                    public AnalyticsEvent[] newArray(int size) {
+                        return new AnalyticsEvent[size];
+                    }
+                };
+
+        private int mEventName;
+        private long mTimeSinceLastEvent;
+
+        public AnalyticsEvent(int eventName, long timestamp) {
+            mEventName = eventName;
+            mTimeSinceLastEvent = timestamp;
+        }
+
+        AnalyticsEvent(Parcel in) {
+            mEventName = in.readInt();
+            mTimeSinceLastEvent = in.readLong();
+        }
+
+        public int getEventName() {
+            return mEventName;
+        }
+
+        public long getTimeSinceLastEvent() {
+            return mTimeSinceLastEvent;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(mEventName);
+            out.writeLong(mTimeSinceLastEvent);
+        }
+    }
+
+    public static final class EventTiming implements Parcelable {
+        public static final int ACCEPT_TIMING = 0;
+        public static final int REJECT_TIMING = 1;
+        public static final int DISCONNECT_TIMING = 2;
+        public static final int HOLD_TIMING = 3;
+        public static final int UNHOLD_TIMING = 4;
+        public static final int OUTGOING_TIME_TO_DIALING_TIMING = 5;
+        public static final int BIND_CS_TIMING = 6;
+        public static final int SCREENING_COMPLETED_TIMING = 7;
+        public static final int DIRECT_TO_VM_FINISHED_TIMING = 8;
+        public static final int BLOCK_CHECK_FINISHED_TIMING = 9;
+        public static final int FILTERING_COMPLETED_TIMING = 10;
+        public static final int FILTERING_TIMED_OUT_TIMING = 11;
+
+        public static final int INVALID = 999999;
+
+        public static final Parcelable.Creator<EventTiming> CREATOR =
+                new Parcelable.Creator<EventTiming> () {
+
+                    @Override
+                    public EventTiming createFromParcel(Parcel in) {
+                        return new EventTiming(in);
+                    }
+
+                    @Override
+                    public EventTiming[] newArray(int size) {
+                        return new EventTiming[size];
+                    }
+                };
+
+        private int mName;
+        private long mTime;
+
+        public EventTiming(int name, long time) {
+            this.mName = name;
+            this.mTime = time;
+        }
+
+        private EventTiming(Parcel in) {
+            mName = in.readInt();
+            mTime = in.readLong();
+        }
+
+        public int getName() {
+            return mName;
+        }
+
+        public long getTime() {
+            return mTime;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(mName);
+            out.writeLong(mTime);
+        }
+    }
+
     public static final int CALLTYPE_UNKNOWN = 0;
     public static final int CALLTYPE_INCOMING = 1;
     public static final int CALLTYPE_OUTGOING = 2;
@@ -87,10 +244,17 @@
     // Whether the call object was created from an existing connection.
     private final boolean isCreatedFromExistingConnection;
 
+    // A list of events that are associated with this call
+    private final List<AnalyticsEvent> analyticsEvents;
+
+    // A map from event-pair names to their durations.
+    private final List<EventTiming> eventTimings;
+
     public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
             boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
             int callTerminationCode, boolean isEmergencyCall, String connectionService,
-            boolean isCreatedFromExistingConnection) {
+            boolean isCreatedFromExistingConnection, List<AnalyticsEvent> analyticsEvents,
+            List<EventTiming> eventTimings) {
         this.startTimeMillis = startTimeMillis;
         this.callDurationMillis = callDurationMillis;
         this.callType = callType;
@@ -101,6 +265,8 @@
         this.isEmergencyCall = isEmergencyCall;
         this.connectionService = connectionService;
         this.isCreatedFromExistingConnection = isCreatedFromExistingConnection;
+        this.analyticsEvents = analyticsEvents;
+        this.eventTimings = eventTimings;
     }
 
     public ParcelableCallAnalytics(Parcel in) {
@@ -114,6 +280,10 @@
         isEmergencyCall = readByteAsBoolean(in);
         connectionService = in.readString();
         isCreatedFromExistingConnection = readByteAsBoolean(in);
+        analyticsEvents = new ArrayList<>();
+        in.readTypedList(analyticsEvents, AnalyticsEvent.CREATOR);
+        eventTimings = new ArrayList<>();
+        in.readTypedList(eventTimings, EventTiming.CREATOR);
     }
 
     public void writeToParcel(Parcel out, int flags) {
@@ -127,6 +297,8 @@
         writeBooleanAsByte(out, isEmergencyCall);
         out.writeString(connectionService);
         writeBooleanAsByte(out, isCreatedFromExistingConnection);
+        out.writeTypedList(analyticsEvents);
+        out.writeTypedList(eventTimings);
     }
 
     public long getStartTimeMillis() {
@@ -169,6 +341,14 @@
         return isCreatedFromExistingConnection;
     }
 
+    public List<AnalyticsEvent> analyticsEvents() {
+        return analyticsEvents;
+    }
+
+    public List<EventTiming> getEventTimings() {
+        return eventTimings;
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.aidl b/telecomm/java/android/telecom/TelecomAnalytics.aidl
similarity index 94%
rename from telecomm/java/android/telecom/ParcelableCallAnalytics.aidl
rename to telecomm/java/android/telecom/TelecomAnalytics.aidl
index b7e78d1..08ad0a2 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.aidl
+++ b/telecomm/java/android/telecom/TelecomAnalytics.aidl
@@ -19,4 +19,4 @@
 /**
  * {@hide}
  */
-parcelable ParcelableCallAnalytics;
+parcelable TelecomAnalytics;
diff --git a/telecomm/java/android/telecom/TelecomAnalytics.java b/telecomm/java/android/telecom/TelecomAnalytics.java
new file mode 100644
index 0000000..6e0d02c
--- /dev/null
+++ b/telecomm/java/android/telecom/TelecomAnalytics.java
@@ -0,0 +1,148 @@
+/*
+ * 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 android.telecom;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @hide
+ */
+@SystemApi
+public final class TelecomAnalytics implements Parcelable {
+    public static final Parcelable.Creator<TelecomAnalytics> CREATOR =
+            new Parcelable.Creator<TelecomAnalytics> () {
+
+                @Override
+                public TelecomAnalytics createFromParcel(Parcel in) {
+                    return new TelecomAnalytics(in);
+                }
+
+                @Override
+                public TelecomAnalytics[] newArray(int size) {
+                    return new TelecomAnalytics[size];
+                }
+            };
+
+    public static final class SessionTiming extends TimedEvent<Integer> implements Parcelable {
+        public static final Parcelable.Creator<SessionTiming> CREATOR =
+                new Parcelable.Creator<SessionTiming> () {
+
+                    @Override
+                    public SessionTiming createFromParcel(Parcel in) {
+                        return new SessionTiming(in);
+                    }
+
+                    @Override
+                    public SessionTiming[] newArray(int size) {
+                        return new SessionTiming[size];
+                    }
+                };
+
+        public static final int ICA_ANSWER_CALL = 1;
+        public static final int ICA_REJECT_CALL = 2;
+        public static final int ICA_DISCONNECT_CALL = 3;
+        public static final int ICA_HOLD_CALL = 4;
+        public static final int ICA_UNHOLD_CALL = 5;
+        public static final int ICA_MUTE = 6;
+        public static final int ICA_SET_AUDIO_ROUTE = 7;
+        public static final int ICA_CONFERENCE = 8;
+
+        public static final int CSW_HANDLE_CREATE_CONNECTION_COMPLETE = 100;
+        public static final int CSW_SET_ACTIVE = 101;
+        public static final int CSW_SET_RINGING = 102;
+        public static final int CSW_SET_DIALING = 103;
+        public static final int CSW_SET_DISCONNECTED = 104;
+        public static final int CSW_SET_ON_HOLD = 105;
+        public static final int CSW_REMOVE_CALL = 106;
+        public static final int CSW_SET_IS_CONFERENCED = 107;
+        public static final int CSW_ADD_CONFERENCE_CALL = 108;
+
+        private int mId;
+        private long mTime;
+
+        public SessionTiming(int id, long time) {
+            this.mId = id;
+            this.mTime = time;
+        }
+
+        private SessionTiming(Parcel in) {
+            mId = in.readInt();
+            mTime = in.readLong();
+        }
+
+        @Override
+        public Integer getKey() {
+            return mId;
+        }
+
+        @Override
+        public long getTime() {
+            return mTime;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(mId);
+            out.writeLong(mTime);
+        }
+    }
+
+    private List<SessionTiming> mSessionTimings;
+    private List<ParcelableCallAnalytics> mCallAnalytics;
+
+    public TelecomAnalytics(List<SessionTiming> sessionTimings,
+            List<ParcelableCallAnalytics> callAnalytics) {
+        this.mSessionTimings = sessionTimings;
+        this.mCallAnalytics = callAnalytics;
+    }
+
+    private TelecomAnalytics(Parcel in) {
+        mSessionTimings = new ArrayList<>();
+        in.readTypedList(mSessionTimings, SessionTiming.CREATOR);
+        mCallAnalytics = new ArrayList<>();
+        in.readTypedList(mCallAnalytics, ParcelableCallAnalytics.CREATOR);
+    }
+
+    public List<SessionTiming> getSessionTimings() {
+        return mSessionTimings;
+    }
+
+    public List<ParcelableCallAnalytics> getCallAnalytics() {
+        return mCallAnalytics;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeTypedList(mSessionTimings);
+        out.writeTypedList(mCallAnalytics);
+    }
+}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index ff5daaf..f12886a 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1443,9 +1443,9 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.DUMP)
-    public List<ParcelableCallAnalytics> dumpAnalytics() {
+    public TelecomAnalytics dumpAnalytics() {
         ITelecomService service = getTelecomService();
-        List<ParcelableCallAnalytics> result = null;
+        TelecomAnalytics result = null;
         if (service != null) {
             try {
                 result = service.dumpCallAnalytics();
diff --git a/telecomm/java/android/telecom/TimedEvent.java b/telecomm/java/android/telecom/TimedEvent.java
new file mode 100644
index 0000000..e484e79
--- /dev/null
+++ b/telecomm/java/android/telecom/TimedEvent.java
@@ -0,0 +1,51 @@
+/*
+ * 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 android.telecom;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @hide
+ */
+public abstract class TimedEvent<T> {
+    public abstract long getTime();
+    public abstract T getKey();
+
+    public static <T> Map<T, Double> averageTimings(Collection<? extends TimedEvent<T>> events) {
+        HashMap<T, Integer> counts = new HashMap<>();
+        HashMap<T, Double> result = new HashMap<>();
+
+        for (TimedEvent<T> entry : events) {
+            if (counts.containsKey(entry.getKey())) {
+                counts.put(entry.getKey(), counts.get(entry.getKey()) + 1);
+                result.put(entry.getKey(), result.get(entry.getKey()) + entry.getTime());
+            } else {
+                counts.put(entry.getKey(), 1);
+                result.put(entry.getKey(), (double) entry.getTime());
+            }
+        }
+
+        for (Map.Entry<T, Double> entry : result.entrySet()) {
+            result.put(entry.getKey(), entry.getValue() / counts.get(entry.getKey()));
+        }
+
+        return result;
+    }
+}
+
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 871565d..5c412e7 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -18,7 +18,7 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
-import android.telecom.ParcelableCallAnalytics;
+import android.telecom.TelecomAnalytics;
 import android.telecom.PhoneAccountHandle;
 import android.net.Uri;
 import android.os.Bundle;
@@ -148,7 +148,7 @@
     /**
     * @see TelecomServiceImpl#dumpCallAnalytics
     */
-    List<ParcelableCallAnalytics> dumpCallAnalytics();
+    TelecomAnalytics dumpCallAnalytics();
 
     //
     // Internal system apis relating to call management.