Merge "Check for null inputs in the ctor."
diff --git a/api/current.txt b/api/current.txt
index de54869..e2720f2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26087,7 +26087,7 @@
     method public java.lang.String getSubscriptionType();
     method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
     method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
-    method public int getUpdateIdentififer();
+    method public int getUpdateIdentifier();
     method public long getUsageLimitDataLimit();
     method public long getUsageLimitStartTimeInMs();
     method public long getUsageLimitTimeLimitInMinutes();
@@ -26129,7 +26129,7 @@
     method public int describeContents();
     method public java.security.cert.X509Certificate getCaCertificate();
     method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
-    method public boolean getCheckAaaServerStatus();
+    method public boolean getCheckAaaServerCertStatus();
     method public java.security.cert.X509Certificate[] getClientCertificateChain();
     method public java.security.PrivateKey getClientPrivateKey();
     method public long getCreationTimeInMs();
@@ -26210,7 +26210,7 @@
     method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
     method public java.lang.String getIconUrl();
     method public long[] getMatchAllOis();
-    method public long[] getMatchAnysOis();
+    method public long[] getMatchAnyOis();
     method public java.lang.String[] getOtherHomePartners();
     method public long[] getRoamingConsortiumOis();
     method public void setFqdn(java.lang.String);
@@ -26232,7 +26232,7 @@
     method public int describeContents();
     method public java.lang.String[] getExcludedSsidList();
     method public int getMaximumBssLoadValue();
-    method public long getMinHomeDownlinkBandWidht();
+    method public long getMinHomeDownlinkBandwidth();
     method public long getMinHomeUplinkBandwidth();
     method public long getMinRoamingDownlinkBandwidth();
     method public long getMinRoamingUplinkBandwidth();
@@ -36758,6 +36758,7 @@
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method public void onLockscreenShown();
     method public void onLowMemory();
+    method public void onPrepareShow(android.os.Bundle, int);
     method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest);
     method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest);
     method public void onRequestCompleteVoice(android.service.voice.VoiceInteractionSession.CompleteVoiceRequest);
@@ -36771,6 +36772,7 @@
     method public void setDisabledShowContext(int);
     method public void setKeepAwake(boolean);
     method public void setTheme(int);
+    method public void setUiEnabled(boolean);
     method public void show(android.os.Bundle, int);
     method public void startVoiceActivity(android.content.Intent);
     field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10
@@ -44754,7 +44756,7 @@
     method public final void requestUnbufferedDispatch(android.view.MotionEvent);
     method public static int resolveSize(int, int);
     method public static int resolveSizeAndState(int, int, int);
-    method public boolean restoreDefaultFocus(int);
+    method public boolean restoreDefaultFocus();
     method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
diff --git a/api/system-current.txt b/api/system-current.txt
index bdf06db..14120af 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -28797,7 +28797,7 @@
     method public java.lang.String getSubscriptionType();
     method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
     method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
-    method public int getUpdateIdentififer();
+    method public int getUpdateIdentifier();
     method public long getUsageLimitDataLimit();
     method public long getUsageLimitStartTimeInMs();
     method public long getUsageLimitTimeLimitInMinutes();
@@ -28839,7 +28839,7 @@
     method public int describeContents();
     method public java.security.cert.X509Certificate getCaCertificate();
     method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
-    method public boolean getCheckAaaServerStatus();
+    method public boolean getCheckAaaServerCertStatus();
     method public java.security.cert.X509Certificate[] getClientCertificateChain();
     method public java.security.PrivateKey getClientPrivateKey();
     method public long getCreationTimeInMs();
@@ -28920,7 +28920,7 @@
     method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
     method public java.lang.String getIconUrl();
     method public long[] getMatchAllOis();
-    method public long[] getMatchAnysOis();
+    method public long[] getMatchAnyOis();
     method public java.lang.String[] getOtherHomePartners();
     method public long[] getRoamingConsortiumOis();
     method public void setFqdn(java.lang.String);
@@ -28942,7 +28942,7 @@
     method public int describeContents();
     method public java.lang.String[] getExcludedSsidList();
     method public int getMaximumBssLoadValue();
-    method public long getMinHomeDownlinkBandWidht();
+    method public long getMinHomeDownlinkBandwidth();
     method public long getMinHomeUplinkBandwidth();
     method public long getMinRoamingDownlinkBandwidth();
     method public long getMinRoamingUplinkBandwidth();
@@ -39856,6 +39856,7 @@
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method public void onLockscreenShown();
     method public void onLowMemory();
+    method public void onPrepareShow(android.os.Bundle, int);
     method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest);
     method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest);
     method public void onRequestCompleteVoice(android.service.voice.VoiceInteractionSession.CompleteVoiceRequest);
@@ -39869,6 +39870,7 @@
     method public void setDisabledShowContext(int);
     method public void setKeepAwake(boolean);
     method public void setTheme(int);
+    method public void setUiEnabled(boolean);
     method public void show(android.os.Bundle, int);
     method public void startVoiceActivity(android.content.Intent);
     field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10
@@ -48170,7 +48172,7 @@
     method public final void requestUnbufferedDispatch(android.view.MotionEvent);
     method public static int resolveSize(int, int);
     method public static int resolveSizeAndState(int, int, int);
-    method public boolean restoreDefaultFocus(int);
+    method public boolean restoreDefaultFocus();
     method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
diff --git a/api/test-current.txt b/api/test-current.txt
index 0f6502b..4fb669a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -26179,7 +26179,7 @@
     method public java.lang.String getSubscriptionType();
     method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
     method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
-    method public int getUpdateIdentififer();
+    method public int getUpdateIdentifier();
     method public long getUsageLimitDataLimit();
     method public long getUsageLimitStartTimeInMs();
     method public long getUsageLimitTimeLimitInMinutes();
@@ -26221,7 +26221,7 @@
     method public int describeContents();
     method public java.security.cert.X509Certificate getCaCertificate();
     method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
-    method public boolean getCheckAaaServerStatus();
+    method public boolean getCheckAaaServerCertStatus();
     method public java.security.cert.X509Certificate[] getClientCertificateChain();
     method public java.security.PrivateKey getClientPrivateKey();
     method public long getCreationTimeInMs();
@@ -26302,7 +26302,7 @@
     method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
     method public java.lang.String getIconUrl();
     method public long[] getMatchAllOis();
-    method public long[] getMatchAnysOis();
+    method public long[] getMatchAnyOis();
     method public java.lang.String[] getOtherHomePartners();
     method public long[] getRoamingConsortiumOis();
     method public void setFqdn(java.lang.String);
@@ -26324,7 +26324,7 @@
     method public int describeContents();
     method public java.lang.String[] getExcludedSsidList();
     method public int getMaximumBssLoadValue();
-    method public long getMinHomeDownlinkBandWidht();
+    method public long getMinHomeDownlinkBandwidth();
     method public long getMinHomeUplinkBandwidth();
     method public long getMinRoamingDownlinkBandwidth();
     method public long getMinRoamingUplinkBandwidth();
@@ -36893,6 +36893,7 @@
     method public boolean onKeyUp(int, android.view.KeyEvent);
     method public void onLockscreenShown();
     method public void onLowMemory();
+    method public void onPrepareShow(android.os.Bundle, int);
     method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest);
     method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest);
     method public void onRequestCompleteVoice(android.service.voice.VoiceInteractionSession.CompleteVoiceRequest);
@@ -36906,6 +36907,7 @@
     method public void setDisabledShowContext(int);
     method public void setKeepAwake(boolean);
     method public void setTheme(int);
+    method public void setUiEnabled(boolean);
     method public void show(android.os.Bundle, int);
     method public void startVoiceActivity(android.content.Intent);
     field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10
@@ -45061,7 +45063,7 @@
     method public final void requestUnbufferedDispatch(android.view.MotionEvent);
     method public static int resolveSize(int, int);
     method public static int resolveSizeAndState(int, int, int);
-    method public boolean restoreDefaultFocus(int);
+    method public boolean restoreDefaultFocus();
     method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index 63f6c92..8e9b91d 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.IUserManager;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -51,6 +50,7 @@
     private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer";
     private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer";
     private static final String COMMAND_GET_SYSTEM_DIALER = "get-system-dialer";
+    private static final String COMMAND_WAIT_ON_HANDLERS = "wait-on-handlers";
 
     private ComponentName mComponent;
     private String mAccountId;
@@ -69,6 +69,7 @@
                 "usage: telecom set-default-dialer <PACKAGE>\n" +
                 "usage: telecom get-default-dialer\n" +
                 "usage: telecom get-system-dialer\n" +
+                "usage: telecom wait-on-handlers\n" +
                 "\n" +
                 "telecom set-phone-account-enabled: Enables the given phone account, if it has \n" +
                 " already been registered with Telecom.\n" +
@@ -80,7 +81,9 @@
                 "\n" +
                 "telecom get-default-dialer: Displays the current default dialer. \n" +
                 "\n" +
-                "telecom get-system-dialer: Displays the current system dialer. \n"
+                "telecom get-system-dialer: Displays the current system dialer. \n" +
+                "\n" +
+                "telecom wait-on-handlers: Wait until all handlers finish their work. \n"
                 );
     }
 
@@ -125,6 +128,9 @@
             case COMMAND_GET_SYSTEM_DIALER:
                 runGetSystemDialer();
                 break;
+            case COMMAND_WAIT_ON_HANDLERS:
+                runWaitOnHandler();
+                break;
             default:
                 throw new IllegalArgumentException ("unknown command '" + command + "'");
         }
@@ -192,6 +198,10 @@
         System.out.println(mTelecomService.getSystemDialerPackage());
     }
 
+    private void runWaitOnHandler() throws RemoteException {
+
+    }
+
     private PhoneAccountHandle getPhoneAccountHandleFromArgs() throws RemoteException{
         final ComponentName component = parseComponentName(nextArgRequired());
         final String accountId = nextArgRequired();
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 66b2355..c88448a 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -813,8 +813,11 @@
     /**
      * Reverses the execution of the operations within this transaction. The Fragment states will
      * only be modified if optimizations are not allowed.
+     *
+     * @param moveToState {@code true} if added fragments should be moved to their final state
+     *                    in unoptimized transactions
      */
-    void executePopOps() {
+    void executePopOps(boolean moveToState) {
         for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
             final Op op = mOps.get(opNum);
             Fragment f = op.fragment;
@@ -860,7 +863,7 @@
                 mManager.moveFragmentToExpectedState(f);
             }
         }
-        if (!mAllowOptimization) {
+        if (!mAllowOptimization && moveToState) {
             mManager.moveToState(mManager.mCurState, true);
         }
     }
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index b7c0737..d32cf3c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2170,7 +2170,7 @@
                 if (isPop) {
                     record.executeOps();
                 } else {
-                    record.executePopOps();
+                    record.executePopOps(false);
                 }
 
                 // move to the end
@@ -2280,7 +2280,10 @@
             final boolean isPop = isRecordPop.get(i);
             if (isPop) {
                 record.bumpBackStackNesting(-1);
-                record.executePopOps();
+                // Only execute the add operations at the end of
+                // all transactions.
+                boolean moveToState = i == (endIndex - 1);
+                record.executePopOps(moveToState);
             } else {
                 record.bumpBackStackNesting(1);
                 record.executeOps();
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 58cd310..cc6f6e1 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -40,7 +40,7 @@
 {
     void cancelAllNotifications(String pkg, int userId);
 
-    void clearData(String pkg, int uid);
+    void clearData(String pkg, int uid, boolean fromApp);
     void enqueueToast(String pkg, ITransientNotification callback, int duration);
     void cancelToast(String pkg, ITransientNotification callback);
     void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
index 68cac27..8854adc 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -170,6 +170,11 @@
     }
 
     @Override
+    public NotificationChannelGroup clone() {
+        return new NotificationChannelGroup(getId(), getName());
+    }
+
+    @Override
     public int hashCode() {
         int result = getId() != null ? getId().hashCode() : 0;
         result = 31 * result + (getName() != null ? getName().hashCode() : 0);
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl
index 82432c7..9cc256e 100644
--- a/core/java/android/net/INetworkScoreService.aidl
+++ b/core/java/android/net/INetworkScoreService.aidl
@@ -18,6 +18,7 @@
 
 import android.net.INetworkScoreCache;
 import android.net.NetworkKey;
+import android.net.NetworkScorerAppManager;
 import android.net.RecommendationRequest;
 import android.net.RecommendationResult;
 import android.net.ScoredNetwork;
@@ -130,4 +131,6 @@
      */
     oneway void requestRecommendationAsync(in RecommendationRequest request,
                                            in RemoteCallback remoteCallback);
+
+    NetworkScorerAppManager.NetworkScorerAppData getActiveScorer();
 }
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 57cf1a5..2875580 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -186,6 +186,20 @@
     }
 
     /**
+     * Returns metadata about the active scorer or <code>null</code> if there is no active scorer.
+     *
+     * @hide
+     */
+    @Nullable
+    public NetworkScorerAppData getActiveScorer() {
+        try {
+            return mService.getActiveScorer();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Update network scores.
      *
      * <p>This may be called at any time to re-score active networks. Scores will generally be
diff --git a/core/java/android/net/NetworkScorerAppManager.aidl b/core/java/android/net/NetworkScorerAppManager.aidl
new file mode 100644
index 0000000..d968343
--- /dev/null
+++ b/core/java/android/net/NetworkScorerAppManager.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2017, 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.net;
+
+parcelable NetworkScorerAppManager.NetworkScorerAppData;
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 9dcf4f4..f3cbb52 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -24,6 +24,8 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -54,7 +56,7 @@
     /**
      * Holds metadata about a discovered network scorer/recommendation application.
      */
-    public static class NetworkScorerAppData {
+    public static final class NetworkScorerAppData implements Parcelable {
         /** UID of the scorer app. */
         public final int packageUid;
         private final ComponentName mRecommendationService;
@@ -64,6 +66,35 @@
             this.mRecommendationService = recommendationServiceComp;
         }
 
+        protected NetworkScorerAppData(Parcel in) {
+            packageUid = in.readInt();
+            mRecommendationService = ComponentName.readFromParcel(in);
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(packageUid);
+            ComponentName.writeToParcel(mRecommendationService, dest);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Creator<NetworkScorerAppData> CREATOR =
+                new Creator<NetworkScorerAppData>() {
+                    @Override
+                    public NetworkScorerAppData createFromParcel(Parcel in) {
+                        return new NetworkScorerAppData(in);
+                    }
+
+                    @Override
+                    public NetworkScorerAppData[] newArray(int size) {
+                        return new NetworkScorerAppData[size];
+                    }
+                };
+
         public String getRecommendationServicePackageName() {
             return mRecommendationService.getPackageName();
         }
diff --git a/core/java/android/net/ScoredNetwork.java b/core/java/android/net/ScoredNetwork.java
index d396b50..ba0a8b5 100644
--- a/core/java/android/net/ScoredNetwork.java
+++ b/core/java/android/net/ScoredNetwork.java
@@ -106,7 +106,7 @@
      * the Network Recommendation Provider.
      *
      * @see #ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL
-     * @see #ATTRIBUTES_KEY_RANKING_SCORE_OFFSET_KEY
+     * @see #ATTRIBUTES_KEY_RANKING_SCORE_OFFSET
      */
     @Nullable
     public final Bundle attributes;
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 210ddb6..e05bd89 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -2219,11 +2219,13 @@
     }
 
     /**
-     * Have the stack traces of the given native process dumped to the
-     * specified file.  Will be appended to the file.
+     * Append the stack traces of a given native process to a specified file.
+     * @param pid pid to dump.
+     * @param file path of file to append dump to.
+     * @param timeoutSecs time to wait in seconds, or 0 to wait forever.
      * @hide
      */
-    public static native void dumpNativeBacktraceToFile(int pid, String file);
+    public static native void dumpNativeBacktraceToFileTimeout(int pid, String file, int timeoutSecs);
 
     /**
      * Get description of unreachable native memory.
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index e9bbc2d..ca736e3 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -135,6 +135,7 @@
     FrameLayout mContentFrame;
     SoftInputWindow mWindow;
 
+    boolean mUiEnabled = true;
     boolean mInitialized;
     boolean mWindowAdded;
     boolean mWindowVisible;
@@ -1001,35 +1002,40 @@
 
         try {
             mInShowWindow = true;
+            onPrepareShow(args, flags);
             if (!mWindowVisible) {
-                if (!mWindowAdded) {
-                    mWindowAdded = true;
-                    View v = onCreateContentView();
-                    if (v != null) {
-                        setContentView(v);
-                    }
-                }
+                ensureWindowAdded();
             }
             onShow(args, flags);
             if (!mWindowVisible) {
                 mWindowVisible = true;
-                mWindow.show();
+                if (mUiEnabled) {
+                    mWindow.show();
+                }
             }
             if (showCallback != null) {
-                mRootView.invalidate();
-                mRootView.getViewTreeObserver().addOnPreDrawListener(
-                        new ViewTreeObserver.OnPreDrawListener() {
-                            @Override
-                            public boolean onPreDraw() {
-                                mRootView.getViewTreeObserver().removeOnPreDrawListener(this);
-                                try {
-                                    showCallback.onShown();
-                                } catch (RemoteException e) {
-                                    Log.w(TAG, "Error calling onShown", e);
+                if (mUiEnabled) {
+                    mRootView.invalidate();
+                    mRootView.getViewTreeObserver().addOnPreDrawListener(
+                            new ViewTreeObserver.OnPreDrawListener() {
+                                @Override
+                                public boolean onPreDraw() {
+                                    mRootView.getViewTreeObserver().removeOnPreDrawListener(this);
+                                    try {
+                                        showCallback.onShown();
+                                    } catch (RemoteException e) {
+                                        Log.w(TAG, "Error calling onShown", e);
+                                    }
+                                    return true;
                                 }
-                                return true;
-                            }
-                        });
+                            });
+                } else {
+                    try {
+                        showCallback.onShown();
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Error calling onShown", e);
+                    }
+                }
             }
         } finally {
             mWindowWasVisible = true;
@@ -1039,7 +1045,7 @@
 
     void doHide() {
         if (mWindowVisible) {
-            mWindow.hide();
+            ensureWindowHidden();
             mWindowVisible = false;
             onHide();
         }
@@ -1058,19 +1064,56 @@
         }
     }
 
-    void initViews() {
+    void ensureWindowCreated() {
+        if (mInitialized) {
+            return;
+        }
+
+        if (!mUiEnabled) {
+            throw new IllegalStateException("setUiEnabled is false");
+        }
+
         mInitialized = true;
+        mInflater = (LayoutInflater)mContext.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
+                mCallbacks, this, mDispatcherState,
+                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true);
+        mWindow.getWindow().addFlags(
+                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED |
+                        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
+                        WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
 
         mThemeAttrs = mContext.obtainStyledAttributes(android.R.styleable.VoiceInteractionSession);
         mRootView = mInflater.inflate(
                 com.android.internal.R.layout.voice_interaction_session, null);
         mRootView.setSystemUiVisibility(
                 View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
-                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
         mWindow.setContentView(mRootView);
         mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
 
         mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
+
+        mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
+        mWindow.setToken(mToken);
+    }
+
+    void ensureWindowAdded() {
+        if (mUiEnabled && !mWindowAdded) {
+            mWindowAdded = true;
+            ensureWindowCreated();
+            View v = onCreateContentView();
+            if (v != null) {
+                setContentView(v);
+            }
+        }
+    }
+
+    void ensureWindowHidden() {
+        if (mWindow != null) {
+            mWindow.hide();
+        }
     }
 
     /**
@@ -1151,6 +1194,24 @@
     }
 
     /**
+     * Control whether the UI layer for this session is enabled.  It is enabled by default.
+     * If set to false, you will not be able to provide a UI through {@link #onCreateContentView()}.
+     */
+    public void setUiEnabled(boolean enabled) {
+        if (mUiEnabled != enabled) {
+            mUiEnabled = enabled;
+            if (mWindowVisible) {
+                if (enabled) {
+                    ensureWindowAdded();
+                    mWindow.show();
+                } else {
+                    ensureWindowHidden();
+                }
+            }
+        }
+    }
+
+    /**
      * You can call this to customize the theme used by your IME's window.
      * This must be set before {@link #onCreate}, so you
      * will typically call it in your constructor with the resource ID
@@ -1242,6 +1303,7 @@
      * Convenience for inflating views.
      */
     public LayoutInflater getLayoutInflater() {
+        ensureWindowCreated();
         return mInflater;
     }
 
@@ -1249,6 +1311,7 @@
      * Retrieve the window being used to show the session's UI.
      */
     public Dialog getWindow() {
+        ensureWindowCreated();
         return mWindow;
     }
 
@@ -1278,18 +1341,17 @@
     private void doOnCreate() {
         mTheme = mTheme != 0 ? mTheme
                 : com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
-        mInflater = (LayoutInflater)mContext.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-        mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
-                mCallbacks, this, mDispatcherState,
-                WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true);
-        mWindow.getWindow().addFlags(
-                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED |
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
-                WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
-        initViews();
-        mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
-        mWindow.setToken(mToken);
+    }
+
+    /**
+     * Called prior to {@link #onShow} before any UI setup has occurred.  Not generally useful.
+     *
+     * @param args The arguments that were supplied to
+     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
+     * @param showFlags The show flags originally provided to
+     * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
+     */
+    public void onPrepareShow(Bundle args, int showFlags) {
     }
 
     /**
@@ -1327,6 +1389,7 @@
     }
 
     public void setContentView(View view) {
+        ensureWindowCreated();
         mContentFrame.removeAllViews();
         mContentFrame.addView(view, new FrameLayout.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
@@ -1623,7 +1686,8 @@
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         writer.print(prefix); writer.print("mToken="); writer.println(mToken);
         writer.print(prefix); writer.print("mTheme=#"); writer.println(Integer.toHexString(mTheme));
-        writer.print(prefix); writer.print("mInitialized="); writer.println(mInitialized);
+        writer.print(prefix); writer.print("mUiEnabled="); writer.println(mUiEnabled);
+        writer.print(" mInitialized="); writer.println(mInitialized);
         writer.print(prefix); writer.print("mWindowAdded="); writer.print(mWindowAdded);
         writer.print(" mWindowVisible="); writer.println(mWindowVisible);
         writer.print(prefix); writer.print("mWindowWasVisible="); writer.print(mWindowWasVisible);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 039237a..b06c3fd 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6125,9 +6125,7 @@
 
             if (mParent != null) {
                 mParent.requestChildFocus(this, this);
-                if (mParent instanceof ViewGroup) {
-                    ((ViewGroup) mParent).setDefaultFocus(this);
-                }
+                setFocusedInCluster();
             }
 
             if (mAttachInfo != null) {
@@ -9245,6 +9243,19 @@
     }
 
     /**
+     * Sets this View as the one which receives focus the next time cluster navigation jumps
+     * to the cluster containing this View. This does NOT change focus even if the cluster
+     * containing this view is current.
+     *
+     * @hide
+     */
+    public void setFocusedInCluster() {
+        if (mParent instanceof ViewGroup) {
+            ((ViewGroup) mParent).setFocusInCluster(this);
+        }
+    }
+
+    /**
      * Returns whether this View should receive focus when the focus is restored for the view
      * hierarchy containing this view.
      * <p>
@@ -9290,7 +9301,7 @@
             if (isFocusedByDefault) {
                 ((ViewGroup) mParent).setDefaultFocus(this);
             } else {
-                ((ViewGroup) mParent).cleanDefaultFocus(this);
+                ((ViewGroup) mParent).clearDefaultFocus(this);
             }
         }
     }
@@ -9670,15 +9681,27 @@
     }
 
     /**
+     * Public for testing. This will request focus for whichever View was last focused within this
+     * cluster before a focus-jump out of it.
+     *
+     * @hide
+     */
+    public boolean restoreFocusInCluster(@FocusRealDirection int direction) {
+        // Prioritize focusableByDefault over algorithmic focus selection.
+        if (restoreDefaultFocus()) {
+            return true;
+        }
+        return requestFocus(direction);
+    }
+
+    /**
      * Gives focus to the default-focus view in the view hierarchy that has this view as a root.
      * If the default-focus view cannot be found, falls back to calling {@link #requestFocus(int)}.
-     * Nested keyboard navigation clusters are excluded from the hierarchy.
      *
-     * @param direction The direction of the focus
      * @return Whether this view or one of its descendants actually took focus
      */
-    public boolean restoreDefaultFocus(@FocusDirection int direction) {
-        return requestFocus(direction);
+    public boolean restoreDefaultFocus() {
+        return requestFocus(View.FOCUS_DOWN);
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index af095cf..fd3ff82 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -141,6 +141,8 @@
     // The view contained within this ViewGroup (excluding nested keyboard navigation clusters)
     // that is or contains a default-focus view.
     private View mDefaultFocus;
+    // The last child of this ViewGroup which held focus within the current cluster
+    private View mFocusedInCluster;
 
     /**
      * A Transformation used when drawing children, to
@@ -724,7 +726,7 @@
         if (mFocused != null) {
             mFocused.unFocus(this);
             mFocused = null;
-            mDefaultFocus = null;
+            mFocusedInCluster = null;
         }
         super.handleFocusGainInternal(direction, previouslyFocusedRect);
     }
@@ -754,14 +756,9 @@
         }
     }
 
-    /**
-     * Sets the specified child view as the default focus for this view and all its ancestors.
-     * If the view is inside a keyboard navigation cluster, stops at the root of the cluster since
-     * the cluster forms a separate keyboard navigation hierarchy from the default focus point of
-     * view.
-     */
     void setDefaultFocus(View child) {
-        if (child.isKeyboardNavigationCluster()) {
+        // Stop at any higher view which is explicitly focused-by-default
+        if (mDefaultFocus != null && mDefaultFocus.isFocusedByDefault()) {
             return;
         }
 
@@ -773,10 +770,56 @@
     }
 
     /**
-     * Destroys the default focus chain.
+     * Clears the default-focus chain from {@param child} up to the first parent which has another
+     * default-focusable branch below it or until there is no default-focus chain.
+     *
+     * @param child
      */
-    void cleanDefaultFocus(View child) {
-        if (mDefaultFocus != child) {
+    void clearDefaultFocus(View child) {
+        // Stop at any higher view which is explicitly focused-by-default
+        if (mDefaultFocus != child && mDefaultFocus != null
+                && mDefaultFocus.isFocusedByDefault()) {
+            return;
+        }
+
+        mDefaultFocus = null;
+
+        // Search child siblings for default focusables.
+        for (int i = 0; i < mChildrenCount; ++i) {
+            View sibling = mChildren[i];
+            if (sibling.isFocusedByDefault()) {
+                mDefaultFocus = sibling;
+                return;
+            } else if (mDefaultFocus == null && sibling.hasDefaultFocus()) {
+                mDefaultFocus = sibling;
+            }
+        }
+
+        if (mParent instanceof ViewGroup) {
+            ((ViewGroup) mParent).clearDefaultFocus(this);
+        }
+    }
+
+    @Override
+    boolean hasDefaultFocus() {
+        return mDefaultFocus != null || super.hasDefaultFocus();
+    }
+
+    void setFocusInCluster(View child) {
+        // Stop at the root of the cluster
+        if (child.isKeyboardNavigationCluster()) {
+            return;
+        }
+
+        mFocusedInCluster = child;
+
+        if (mParent instanceof ViewGroup) {
+            ((ViewGroup) mParent).setFocusInCluster(this);
+        }
+    }
+
+    void clearFocusInCluster(View child) {
+        if (mFocusedInCluster != child) {
             return;
         }
 
@@ -784,19 +827,14 @@
             return;
         }
 
-        mDefaultFocus = null;
+        mFocusedInCluster = null;
 
         if (mParent instanceof ViewGroup) {
-            ((ViewGroup) mParent).cleanDefaultFocus(this);
+            ((ViewGroup) mParent).clearFocusInCluster(this);
         }
     }
 
     @Override
-    boolean hasDefaultFocus() {
-        return mDefaultFocus != null || super.hasDefaultFocus();
-    }
-
-    @Override
     public void focusableViewAvailable(View v) {
         if (mParent != null
                 // shortcut: don't report a new focusable view if we block our descendants from
@@ -3115,14 +3153,28 @@
     }
 
     @Override
-    public boolean restoreDefaultFocus(@FocusDirection int direction) {
-        if (mDefaultFocus != null && !mDefaultFocus.isKeyboardNavigationCluster()
+    public boolean restoreDefaultFocus() {
+        if (mDefaultFocus != null
                 && getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS
                 && (mDefaultFocus.mViewFlags & VISIBILITY_MASK) == VISIBLE
-                && mDefaultFocus.restoreDefaultFocus(direction)) {
+                && mDefaultFocus.restoreDefaultFocus()) {
             return true;
         }
-        return super.restoreDefaultFocus(direction);
+        return super.restoreDefaultFocus();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean restoreFocusInCluster(@FocusRealDirection int direction) {
+        if (mFocusedInCluster != null && !mFocusedInCluster.isKeyboardNavigationCluster()
+                && getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS
+                && (mFocusedInCluster.mViewFlags & VISIBILITY_MASK) == VISIBLE
+                && mFocusedInCluster.restoreFocusInCluster(direction)) {
+            return true;
+        }
+        return super.restoreFocusInCluster(direction);
     }
 
     /**
@@ -5004,8 +5056,8 @@
             view.unFocus(null);
             clearChildFocus = true;
         }
-        if (view == mDefaultFocus) {
-            mDefaultFocus = null;
+        if (view == mFocusedInCluster) {
+            clearFocusInCluster(view);
         }
 
         view.clearAccessibilityFocus();
@@ -5028,6 +5080,9 @@
 
         removeFromArray(index);
 
+        if (view == mDefaultFocus) {
+            clearDefaultFocus(view);
+        }
         if (clearChildFocus) {
             clearChildFocus(view);
             if (!rootViewRequestFocus()) {
@@ -5103,6 +5158,7 @@
         final View focused = mFocused;
         final boolean detach = mAttachInfo != null;
         boolean clearChildFocus = false;
+        View clearDefaultFocus = null;
 
         final View[] children = mChildren;
 
@@ -5118,7 +5174,10 @@
                 clearChildFocus = true;
             }
             if (view == mDefaultFocus) {
-                mDefaultFocus = null;
+                clearDefaultFocus = view;
+            }
+            if (view == mFocusedInCluster) {
+                clearFocusInCluster(view);
             }
 
             view.clearAccessibilityFocus();
@@ -5144,6 +5203,9 @@
 
         removeFromArray(start, count);
 
+        if (clearDefaultFocus != null) {
+            clearDefaultFocus(clearDefaultFocus);
+        }
         if (clearChildFocus) {
             clearChildFocus(focused);
             if (!rootViewRequestFocus()) {
@@ -5193,7 +5255,6 @@
         boolean clearChildFocus = false;
 
         needGlobalAttributesUpdate(false);
-        mDefaultFocus = null;
 
         for (int i = count - 1; i >= 0; i--) {
             final View view = children[i];
@@ -5229,6 +5290,9 @@
             children[i] = null;
         }
 
+        if (mDefaultFocus != null) {
+            clearDefaultFocus(mDefaultFocus);
+        }
         if (clearChildFocus) {
             clearChildFocus(focused);
             if (!rootViewRequestFocus()) {
@@ -5266,7 +5330,10 @@
             child.clearFocus();
         }
         if (child == mDefaultFocus) {
-            mDefaultFocus = null;
+            clearDefaultFocus(child);
+        }
+        if (child == mFocusedInCluster) {
+            clearFocusInCluster(child);
         }
 
         child.clearAccessibilityFocus();
@@ -6251,6 +6318,12 @@
             Log.d(VIEW_LOG_TAG, output);
             mDefaultFocus.debug(depth + 1);
         }
+        if (mFocusedInCluster != null) {
+            output = debugIndent(depth);
+            output += "mFocusedInCluster";
+            Log.d(VIEW_LOG_TAG, output);
+            mFocusedInCluster.debug(depth + 1);
+        }
         if (mChildrenCount != 0) {
             output = debugIndent(depth);
             output += "{";
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9e8dda8..cb29053 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2162,7 +2162,7 @@
                     + mView.hasFocus());
             if (mView != null) {
                 if (!mView.hasFocus()) {
-                    mView.restoreDefaultFocus(View.FOCUS_FORWARD);
+                    mView.restoreDefaultFocus();
                     if (DEBUG_INPUT_RESIZE) Log.v(mTag, "First: requested focused view="
                             + mView.findFocus());
                 } else {
@@ -4441,7 +4441,14 @@
                     ? focused.keyboardNavigationClusterSearch(null, direction)
                     : keyboardNavigationClusterSearch(null, direction);
 
-            if (cluster != null && cluster.restoreDefaultFocus(View.FOCUS_DOWN)) {
+            // Since requestFocus only takes "real" focus directions (and therefore also
+            // restoreFocusInCluster), convert forward/backward focus into FOCUS_DOWN.
+            int realDirection = direction;
+            if (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
+                realDirection = View.FOCUS_DOWN;
+            }
+
+            if (cluster != null && cluster.restoreFocusInCluster(realDirection)) {
                 return true;
             }
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 8cb2d23..45b5570 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -149,10 +149,10 @@
     private static final int MENU_ITEM_ORDER_ASSIST = 1;
     private static final int MENU_ITEM_ORDER_UNDO = 2;
     private static final int MENU_ITEM_ORDER_REDO = 3;
-    private static final int MENU_ITEM_ORDER_SHARE = 4;
-    private static final int MENU_ITEM_ORDER_CUT = 5;
-    private static final int MENU_ITEM_ORDER_COPY = 6;
-    private static final int MENU_ITEM_ORDER_PASTE = 7;
+    private static final int MENU_ITEM_ORDER_CUT = 4;
+    private static final int MENU_ITEM_ORDER_COPY = 5;
+    private static final int MENU_ITEM_ORDER_PASTE = 6;
+    private static final int MENU_ITEM_ORDER_SHARE = 7;
     private static final int MENU_ITEM_ORDER_PASTE_AS_PLAIN_TEXT = 8;
     private static final int MENU_ITEM_ORDER_SELECT_ALL = 9;
     private static final int MENU_ITEM_ORDER_REPLACE = 10;
@@ -3876,7 +3876,7 @@
                 final Intent intent = textClassificationResult.getIntent();
                 if ((icon != null || !TextUtils.isEmpty(label))
                         && (onClickListener != null || intent != null)) {
-                    menu.add(Menu.NONE, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, label)
+                    menu.add(TextView.ID_ASSIST, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, label)
                             .setIcon(icon)
                             .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
                 }
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 58e694a..854d013 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -32,6 +32,7 @@
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.util.Size;
+import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -1113,6 +1114,7 @@
             mMainPanel.removeAllViews();
             mMainPanel.setPaddingRelative(0, 0, 0, 0);
 
+            int lastGroupId = -1;
             boolean isFirstItem = true;
             while (!remainingMenuItems.isEmpty()) {
                 final MenuItem menuItem = remainingMenuItems.peek();
@@ -1125,11 +1127,11 @@
                             menuItemButton.getPaddingTop(),
                             menuItemButton.getPaddingEnd(),
                             menuItemButton.getPaddingBottom());
-                    isFirstItem = false;
                 }
 
                 // Adding additional end padding for the last button to even out button spacing.
-                if (remainingMenuItems.size() == 1) {
+                boolean isLastItem = remainingMenuItems.size() == 1;
+                if (isLastItem) {
                     menuItemButton.setPaddingRelative(
                             menuItemButton.getPaddingStart(),
                             menuItemButton.getPaddingTop(),
@@ -1138,25 +1140,64 @@
                 }
 
                 menuItemButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
-                int menuItemButtonWidth = Math.min(menuItemButton.getMeasuredWidth(), toolbarWidth);
+                final int menuItemButtonWidth = Math.min(menuItemButton.getMeasuredWidth(), toolbarWidth);
+
+                final boolean isNewGroup = !isFirstItem && lastGroupId != menuItem.getGroupId();
+                final int extraPadding = isNewGroup ? menuItemButton.getPaddingEnd() * 2 : 0;
+
                 // Check if we can fit an item while reserving space for the overflowButton.
                 boolean canFitWithOverflow =
-                        menuItemButtonWidth <= availableWidth - mOverflowButtonSize.getWidth();
+                        menuItemButtonWidth <=
+                                availableWidth - mOverflowButtonSize.getWidth() - extraPadding;
                 boolean canFitNoOverflow =
-                        remainingMenuItems.size() == 1 && menuItemButtonWidth <= availableWidth;
+                        isLastItem && menuItemButtonWidth <= availableWidth - extraPadding;
                 if (canFitWithOverflow || canFitNoOverflow) {
+                    if (isNewGroup) {
+                        final View border = createBorder(mContext);
+                        final int borderWidth = border.getLayoutParams().width;
+
+                        // Add extra padding to the end of the previous button.
+                        // Half of the extra padding (less borderWidth) goes to the previous button.
+                        View previousButton = mMainPanel.getChildAt(mMainPanel.getChildCount() - 1);
+                        final int prevPaddingEnd = previousButton.getPaddingEnd()
+                                + extraPadding / 2 - borderWidth;
+                        previousButton.setPaddingRelative(
+                                previousButton.getPaddingStart(),
+                                previousButton.getPaddingTop(),
+                                prevPaddingEnd,
+                                previousButton.getPaddingBottom());
+                        final ViewGroup.LayoutParams prevParams = previousButton.getLayoutParams();
+                        prevParams.width += extraPadding / 2 - borderWidth;
+                        previousButton.setLayoutParams(prevParams);
+
+                        // Add extra padding to the start of this button.
+                        // Other half of the extra padding goes to this button.
+                        final int paddingStart = menuItemButton.getPaddingStart()
+                                + extraPadding / 2;
+                        menuItemButton.setPaddingRelative(
+                                paddingStart,
+                                menuItemButton.getPaddingTop(),
+                                menuItemButton.getPaddingEnd(),
+                                menuItemButton.getPaddingBottom());
+
+                        // Include a border.
+                        mMainPanel.addView(border);
+                    }
+
                     setButtonTagAndClickListener(menuItemButton, menuItem);
                     mMainPanel.addView(menuItemButton);
-                    ViewGroup.LayoutParams params = menuItemButton.getLayoutParams();
-                    params.width = menuItemButtonWidth;
+                    final ViewGroup.LayoutParams params = menuItemButton.getLayoutParams();
+                    params.width = menuItemButtonWidth + extraPadding / 2;
                     menuItemButton.setLayoutParams(params);
-                    availableWidth -= menuItemButtonWidth;
+                    availableWidth -= menuItemButtonWidth + extraPadding;
                     remainingMenuItems.pop();
                 } else {
                     // Reserve space for overflowButton.
                     mMainPanel.setPaddingRelative(0, 0, mOverflowButtonSize.getWidth(), 0);
                     break;
                 }
+                lastGroupId = menuItem.getGroupId();
+                isFirstItem = false;
             }
             mMainPanelSize = measure(mMainPanel);
             return remainingMenuItems;
@@ -1688,6 +1729,23 @@
         return popupWindow;
     }
 
+    private static View createBorder(Context context) {
+        // TODO: Inflate this instead.
+        View border = new View(context);
+        int _1dp = (int) TypedValue.applyDimension(
+                TypedValue.COMPLEX_UNIT_DIP, 1, context.getResources().getDisplayMetrics());
+        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+                _1dp, ViewGroup.LayoutParams.MATCH_PARENT);
+        params.setMarginsRelative(0, _1dp * 10, 0, _1dp * 10);
+        border.setLayoutParams(params);
+        border.setBackgroundColor(Color.parseColor("#9E9E9E"));
+        border.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+        border.setEnabled(false);
+        border.setFocusable(false);
+        border.setContentDescription(null);
+        return border;
+    }
+
     /**
      * Creates an "appear" animation for the specified view.
      *
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index be3a87b..eaf9e91 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -1006,9 +1006,8 @@
     ALOGD("Native heap dump complete.\n");
 }
 
-
-static void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject clazz,
-    jint pid, jstring fileName)
+static void android_os_Debug_dumpNativeBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
+    jint pid, jstring fileName, jint timeoutSecs)
 {
     if (fileName == NULL) {
         jniThrowNullPointerException(env, "file == null");
@@ -1031,7 +1030,7 @@
     if (lseek(fd, 0, SEEK_END) < 0) {
         fprintf(stderr, "lseek: %s\n", strerror(errno));
     } else {
-        dump_backtrace_to_file(pid, fd);
+        dump_backtrace_to_file_timeout(pid, fd, timeoutSecs);
     }
 
     close(fd);
@@ -1077,8 +1076,8 @@
             (void*)android_os_Debug_getProxyObjectCount },
     { "getBinderDeathObjectCount", "()I",
             (void*)android_os_Debug_getDeathObjectCount },
-    { "dumpNativeBacktraceToFile", "(ILjava/lang/String;)V",
-            (void*)android_os_Debug_dumpNativeBacktraceToFile },
+    { "dumpNativeBacktraceToFileTimeout", "(ILjava/lang/String;I)V",
+            (void*)android_os_Debug_dumpNativeBacktraceToFileTimeout },
     { "getUnreachableMemory", "(IZ)Ljava/lang/String;",
             (void*)android_os_Debug_getUnreachableMemory },
 };
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index 905a85a..399dec8 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "GraphicsEnvironment"
 
-#include <gui/GraphicsEnv.h>
+#include <ui/GraphicsEnv.h>
 #include <nativehelper/ScopedUtfChars.h>
 #include "core_jni_helpers.h"
 
diff --git a/core/jni/android_os_seccomp.cpp b/core/jni/android_os_seccomp.cpp
index 02c0c62..3f021ae 100644
--- a/core/jni/android_os_seccomp.cpp
+++ b/core/jni/android_os_seccomp.cpp
@@ -216,6 +216,9 @@
     AllowSyscall(f, 8);   // __NR_creat
     AllowSyscall(f, 10);  // __NR_unlink
 
+    // b/35059702
+    AllowSyscall(f, 196); // __NR_lstat64
+
     Trap(f);
 
     return install_filter(f);
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index de5fc95..640e74d 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -461,12 +461,12 @@
     <dimen name="floating_toolbar_height">48dp</dimen>
     <dimen name="floating_toolbar_menu_image_button_width">56dp</dimen>
     <dimen name="floating_toolbar_menu_image_button_vertical_padding">12dp</dimen>
-    <dimen name="floating_toolbar_menu_button_side_padding">16dp</dimen>
+    <dimen name="floating_toolbar_menu_button_side_padding">11dp</dimen>
     <dimen name="floating_toolbar_overflow_image_button_width">60dp</dimen>
     <dimen name="floating_toolbar_overflow_side_padding">18dp</dimen>
     <dimen name="floating_toolbar_text_size">14sp</dimen>
     <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen>
-    <dimen name="floating_toolbar_preferred_width">328dp</dimen>
+    <dimen name="floating_toolbar_preferred_width">400dp</dimen>
     <dimen name="floating_toolbar_minimum_overflow_height">96dp</dimen>
     <dimen name="floating_toolbar_maximum_overflow_height">192dp</dimen>
     <dimen name="floating_toolbar_horizontal_margin">16dp</dimen>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index b72bcc7..aa36617 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -58,8 +58,8 @@
     <dimen name="drawer_item_top_bottom_margin">4dp</dimen>
     <dimen name="drawer_spacer_height">32dp</dimen>
 
-    <dimen name="battery_height">48dp</dimen>
-    <dimen name="battery_width">38dp</dimen>
+    <dimen name="battery_height">14.5dp</dimen>
+    <dimen name="battery_width">9.5dp</dimen>
 
     <!-- Margin on the right side of the system icon group on Keyguard. -->
     <fraction name="battery_button_height_fraction">10.5%</fraction>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index ae6ada2a..11e2a71 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -6,8 +6,8 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
 import android.content.pm.Signature;
+import android.content.pm.UserInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
index 32478a7..7f469b5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
@@ -34,6 +34,7 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Shader;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 
 import com.android.settingslib.R;
@@ -273,6 +274,11 @@
         super.invalidateSelf();
     }
 
+    @Override
+    public ConstantState getConstantState() {
+        return new BitmapDrawable(mBitmap).getConstantState();
+    }
+
     /**
      * This 'bakes' the current state of this icon into a bitmap and removes/recycles the source
      * bitmap/drawable. Use this when no more changes will be made and an intrinsic size is set.
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index d25bb2e..fd2e7ca 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -37,14 +37,13 @@
 
     private static final float ASPECT_RATIO = 9.5f / 14.5f;
     public static final String TAG = BatteryMeterDrawableBase.class.getSimpleName();
-    public static final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";
 
     protected final Context mContext;
 
-    protected int mLevel = -1;
-    protected boolean mPluggedIn;
-    protected boolean mPowerSaveEnabled;
-    protected boolean mShowPercent;
+    private int mLevel = -1;
+    private boolean mPluggedIn;
+    private boolean mPowerSaveEnabled;
+    private boolean mShowPercent;
 
     private static final boolean SINGLE_DIGIT_PERCENT = false;
 
@@ -104,7 +103,7 @@
         }
         levels.recycle();
         colors.recycle();
-        updateShowPercent();
+
         mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
         mCriticalLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -143,10 +142,10 @@
 
         mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
         mBoltPaint.setColor(Utils.getDefaultColor(mContext, R.color.batterymeter_bolt_color));
-        mBoltPoints = loadBoltPoints(res);
+        mBoltPoints = loadPoints(res, R.array.batterymeter_bolt_points);
 
         mPlusPaint = new Paint(mBoltPaint);
-        mPlusPoints = loadPlusPoints(res);
+        mPlusPoints = loadPoints(res, R.array.batterymeter_plus_points);
 
         mDarkModeBackgroundColor =
                 Utils.getDefaultColor(mContext, R.color.dark_mode_icon_color_dual_tone_background);
@@ -171,32 +170,34 @@
         return mIntrinsicWidth;
     }
 
-    public void disableShowPercent() {
-        mShowPercent = false;
+    public void setShowPercent(boolean show) {
+        mShowPercent = show;
         postInvalidate();
     }
 
+    public void setPluggedIn(boolean val) {
+        mPluggedIn = val;
+        postInvalidate();
+    }
+
+    public void setBatteryLevel(int val) {
+        mLevel = val;
+        postInvalidate();
+    }
+
+    public void setPowerSave(boolean val) {
+        mPowerSaveEnabled = val;
+        postInvalidate();
+    }
+
+    // an approximation of View.postInvalidate()
     protected void postInvalidate() {
+        unscheduleSelf(this::invalidateSelf);
         scheduleSelf(this::invalidateSelf, 0);
     }
 
-    private static float[] loadBoltPoints(Resources res) {
-        final int[] pts = res.getIntArray(R.array.batterymeter_bolt_points);
-        int maxX = 0, maxY = 0;
-        for (int i = 0; i < pts.length; i += 2) {
-            maxX = Math.max(maxX, pts[i]);
-            maxY = Math.max(maxY, pts[i + 1]);
-        }
-        final float[] ptsF = new float[pts.length];
-        for (int i = 0; i < pts.length; i += 2) {
-            ptsF[i] = (float) pts[i] / maxX;
-            ptsF[i + 1] = (float) pts[i + 1] / maxY;
-        }
-        return ptsF;
-    }
-
-    private static float[] loadPlusPoints(Resources res) {
-        final int[] pts = res.getIntArray(R.array.batterymeter_plus_points);
+    private static float[] loadPoints(Resources res, int pointArrayRes) {
+        final int[] pts = res.getIntArray(pointArrayRes);
         int maxX = 0, maxY = 0;
         for (int i = 0; i < pts.length; i += 2) {
             maxX = Math.max(maxX, pts[i]);
@@ -219,10 +220,6 @@
         mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
     }
 
-    protected void updateShowPercent() {
-        mShowPercent = true;
-    }
-
     private int getColorForLevel(int percent) {
         // If we are in power save mode, always use the normal color.
         if (mPowerSaveEnabled) {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index fab00da..4de2c12 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -48,4 +48,24 @@
         verify(canvas, never()).drawPath(any(), any());
         verify(canvas, never()).drawText(anyString(), anyFloat(), anyFloat(), any());
     }
+
+    @Test
+    public void testDrawingForTypicalValues() {
+        final Canvas canvas = mock(Canvas.class);
+        final int levels[] = { 0, 1, 5, 10, 25, 50, 75, 90, 95, 99, 100 };
+        final boolean bools[] = { false, true };
+        for (int l : levels) {
+            for (boolean plugged : bools) {
+                for (boolean saver : bools) {
+                    for (boolean percent : bools) {
+                        mBatteryDrawable.setBatteryLevel(l);
+                        mBatteryDrawable.setPowerSave(saver);
+                        mBatteryDrawable.setPluggedIn(plugged);
+                        mBatteryDrawable.setShowPercent(percent);
+                        mBatteryDrawable.draw(canvas);
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
index 0032cf0..7729dec 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
@@ -16,39 +16,35 @@
 
 package com.android.settingslib;
 
-import android.util.Log;
-import android.content.Context;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.os.Bundle;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.os.Bundle;
 import android.preference.PreferenceManager;
 
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtilsTest;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import com.android.settingslib.drawer.Tile;
-import com.android.settingslib.drawer.TileUtilsTest;
-
 import java.util.ArrayList;
 import java.util.List;
 
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
-import org.robolectric.RuntimeEnvironment;
-
 @RunWith(SettingLibRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SuggestionParserTest {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawable/UserIconDrawableTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawable/UserIconDrawableTest.java
new file mode 100644
index 0000000..a21390a
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawable/UserIconDrawableTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 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.settingslib.drawable;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import com.android.settingslib.R;
+import com.android.settingslib.SettingLibRobolectricTestRunner;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UserIconDrawableTest {
+
+    private UserIconDrawable mDrawable;
+
+    @Test
+    public void getConstantState_shouldNotBeNull() {
+        final Bitmap b = BitmapFactory.decodeResource(
+                RuntimeEnvironment.application.getResources(),
+                R.drawable.home);
+        mDrawable = new UserIconDrawable(100 /* size */).setIcon(b).bake();
+
+        assertThat(mDrawable.getConstantState()).isNotNull();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
index 2bdb2f33..9068079 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
@@ -27,6 +27,8 @@
 public class BatteryMeterDrawable extends BatteryMeterDrawableBase implements
         BatteryController.BatteryStateChangeCallback {
 
+    public static final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";
+
     private BatteryController mBatteryController;
     private SettingObserver mSettingObserver;
 
@@ -38,16 +40,13 @@
 
     @Override
     public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
-        mLevel = level;
-        mPluggedIn = pluggedIn;
-
-        postInvalidate();
+        setBatteryLevel(level);
+        setPluggedIn(pluggedIn);
     }
 
     @Override
     public void onPowerSaveChanged(boolean isPowerSave) {
-        mPowerSaveEnabled = isPowerSave;
-        invalidateSelf();
+        setPowerSave(isPowerSave);
     }
 
     public void startListening() {
@@ -62,15 +61,14 @@
         mBatteryController.removeCallback(this);
     }
 
-    @Override
     protected void updateShowPercent() {
-        mShowPercent = 0 != Settings.System.getInt(mContext.getContentResolver(),
-                SHOW_PERCENT_SETTING, 0);
+        setShowPercent(0 != Settings.System.getInt(mContext.getContentResolver(),
+                SHOW_PERCENT_SETTING, 0));
     }
 
     public void setBatteryController(BatteryController batteryController) {
         mBatteryController = batteryController;
-        mPowerSaveEnabled = mBatteryController.isPowerSave();
+        setPowerSave(mBatteryController.isPowerSave());
     }
 
     private final class SettingObserver extends ContentObserver {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
index beec137..0259e3e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
@@ -25,11 +25,14 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnLayoutChangeListener;
+import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.widget.FrameLayout;
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 
 public class PipDismissViewController {
 
@@ -65,8 +68,10 @@
     public void createDismissTarget() {
         if (mDismissView == null) {
             // Determine sizes for the gradient
-            Point windowSize = new Point();
-            mWindowManager.getDefaultDisplay().getSize(windowSize);
+            final Rect stableInsets = new Rect();
+            SystemServicesProxy.getInstance(mContext).getStableInsets(stableInsets);
+            final Point windowSize = new Point();
+            mWindowManager.getDefaultDisplay().getRealSize(windowSize);
             mMinHeight = windowSize.y * DISMISS_GRADIENT_MIN_HEIGHT_PERCENT;
             mMaxHeight = windowSize.y * DISMISS_GRADIENT_MAX_HEIGHT_PERCENT;
 
@@ -74,13 +79,16 @@
             LayoutInflater inflater = LayoutInflater.from(mContext);
             mDismissView = inflater.inflate(R.layout.pip_dismiss_view, null);
             mGradientView = mDismissView.findViewById(R.id.gradient_view);
-            FrameLayout.LayoutParams glp = (android.widget.FrameLayout.LayoutParams) mGradientView
-                    .getLayoutParams();
+            FrameLayout.LayoutParams glp =
+                    (FrameLayout.LayoutParams) mGradientView.getLayoutParams();
             glp.height = (int) mMaxHeight;
             mGradientView.setLayoutParams(glp);
             mGradientView.setPivotY(windowSize.y);
             mGradientView.setScaleY(mMaxHeight / mMinHeight); // Set to min height via scaling
             mDismissContainer = mDismissView.findViewById(R.id.pip_dismiss_container);
+            FrameLayout.LayoutParams clp =
+                    (FrameLayout.LayoutParams) mDismissContainer.getLayoutParams();
+            clp.bottomMargin = stableInsets.bottom;
             mDismissContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
                 @Override
                 public void onLayoutChange(View v, int left, int top, int right, int bottom,
@@ -92,15 +100,16 @@
             });
 
             // Add the target to the window
-            WindowManager.LayoutParams lp =  new WindowManager.LayoutParams(
-                    windowSize.x,
-                    (int) mMaxHeight,
-                    WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
-                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                            | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+            LayoutParams lp =  new LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, (int) mMaxHeight,
+                    0, windowSize.y - (int) mMaxHeight,
+                    LayoutParams.TYPE_SYSTEM_DIALOG,
+                    LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                            | LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                            | LayoutParams.FLAG_NOT_TOUCHABLE
+                            | LayoutParams.FLAG_NOT_FOCUSABLE,
                     PixelFormat.TRANSLUCENT);
-            lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+            lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
             mWindowManager.addView(mDismissView, lp);
         }
         mDismissView.animate().cancel();
@@ -132,7 +141,7 @@
                     .withEndAction(new Runnable() {
                         @Override
                         public void run() {
-                            mWindowManager.removeView(mDismissView);
+                            mWindowManager.removeViewImmediate(mDismissView);
                             mDismissView = null;
                         }
                     })
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 3d36868..471c3ae 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -34,6 +34,7 @@
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Slog;
+import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -45,6 +46,8 @@
     static final String TAG = "PowerUI";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final long TEMPERATURE_INTERVAL = 30 * DateUtils.SECOND_IN_MILLIS;
+    private static final long TEMPERATURE_LOGGING_INTERVAL = DateUtils.HOUR_IN_MILLIS;
+    private static final int MAX_RECENT_TEMPS = 125; // TEMPERATURE_LOGGING_INTERVAL plus a buffer
 
     private final Handler mHandler = new Handler();
     private final Receiver mReceiver = new Receiver();
@@ -62,7 +65,10 @@
 
     private long mScreenOffTime = -1;
 
-    private float mThrottlingTemp;
+    private float mThresholdTemp;
+    private float[] mRecentTemps = new float[MAX_RECENT_TEMPS];
+    private int mNumTemps;
+    private long mNextLogTime;
 
     public void start() {
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -229,10 +235,10 @@
             return;
         }
 
-        mThrottlingTemp = Settings.Global.getFloat(resolver, Settings.Global.WARNING_TEMPERATURE,
+        mThresholdTemp = Settings.Global.getFloat(resolver, Settings.Global.WARNING_TEMPERATURE,
                 resources.getInteger(R.integer.config_warningTemperature));
 
-        if (mThrottlingTemp < 0f) {
+        if (mThresholdTemp < 0f) {
             // Get the throttling temperature. No need to check if we're not throttling.
             float[] throttlingTemps = mHardwarePropertiesManager.getDeviceTemperatures(
                     HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
@@ -242,41 +248,86 @@
                     || throttlingTemps[0] == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) {
                 return;
             }
-            mThrottlingTemp = throttlingTemps[0];
+            mThresholdTemp = throttlingTemps[0];
         }
+        setNextLogTime();
 
         // We have passed all of the checks, start checking the temp
         updateTemperatureWarning();
     }
 
     private void updateTemperatureWarning() {
-        StatusBar statusBar = getComponent(StatusBar.class);
-        if (statusBar != null && statusBar.isDeviceInVrMode()) {
-            // ensure the warning isn't showing, since VR shows its own warning
-            mWarnings.dismissTemperatureWarning();
-        } else {
-            float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
-                    HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
-                    HardwarePropertiesManager.TEMPERATURE_CURRENT);
-            boolean shouldShowTempWarning = false;
-            for (float temp : temps) {
-                if (temp >= mThrottlingTemp) {
-                    Slog.i(TAG, "currentTemp=" + temp + ", throttlingTemp=" + mThrottlingTemp);
-                    shouldShowTempWarning = true;
-                    break;
-                }
-            }
-            if (shouldShowTempWarning) {
+        float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
+                HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+                HardwarePropertiesManager.TEMPERATURE_CURRENT);
+        if (temps.length != 0) {
+            float temp = temps[0];
+            mRecentTemps[mNumTemps++] = temp;
+
+            StatusBar statusBar = getComponent(StatusBar.class);
+            if (statusBar != null && !statusBar.isDeviceInVrMode()
+                    && temp >= mThresholdTemp) {
+                logAtTemperatureThreshold(temp);
                 mWarnings.showTemperatureWarning();
             } else {
                 mWarnings.dismissTemperatureWarning();
             }
         }
 
-        // TODO: skip this when in VR mode since we already get a callback
+        logTemperatureStats();
+
         mHandler.postDelayed(this::updateTemperatureWarning, TEMPERATURE_INTERVAL);
     }
 
+    private void logAtTemperatureThreshold(float temp) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("currentTemp=").append(temp)
+                .append(",thresholdTemp=").append(mThresholdTemp)
+                .append(",batteryStatus=").append(mBatteryStatus)
+                .append(",recentTemps=");
+        for (int i = 0; i < mNumTemps; i++) {
+            sb.append(mRecentTemps[i]).append(',');
+        }
+        Slog.i(TAG, sb.toString());
+    }
+
+    /**
+     * Calculates and logs min, max, and average
+     * {@link HardwarePropertiesManager#DEVICE_TEMPERATURE_SKIN} over the past
+     * {@link #TEMPERATURE_LOGGING_INTERVAL}.
+     */
+    private void logTemperatureStats() {
+        if (mNextLogTime > System.currentTimeMillis() && mNumTemps != MAX_RECENT_TEMPS) {
+            return;
+        }
+
+        if (mNumTemps > 0) {
+            float sum = mRecentTemps[0], min = mRecentTemps[0], max = mRecentTemps[0];
+            for (int i = 1; i < mNumTemps; i++) {
+                float temp = mRecentTemps[i];
+                sum += temp;
+                if (temp > max) {
+                    max = temp;
+                }
+                if (temp < min) {
+                    min = temp;
+                }
+            }
+
+            float avg = sum / mNumTemps;
+            Slog.i(TAG, "avg=" + avg + ",min=" + min + ",max=" + max);
+            MetricsLogger.histogram(mContext, "device_skin_temp_avg", (int) avg);
+            MetricsLogger.histogram(mContext, "device_skin_temp_min", (int) min);
+            MetricsLogger.histogram(mContext, "device_skin_temp_max", (int) max);
+        }
+        setNextLogTime();
+        mNumTemps = 0;
+    }
+
+    private void setNextLogTime() {
+        mNextLogTime = System.currentTimeMillis() + TEMPERATURE_LOGGING_INTERVAL;
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print("mLowBatteryAlertCloseLevel=");
         pw.println(mLowBatteryAlertCloseLevel);
@@ -303,8 +354,10 @@
                 Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
         pw.print("bucket: ");
         pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
-        pw.print("mThrottlingTemp=");
-        pw.println(Float.toString(mThrottlingTemp));
+        pw.print("mThresholdTemp=");
+        pw.println(Float.toString(mThresholdTemp));
+        pw.print("mNextLogTime=");
+        pw.println(Long.toString(mNextLogTime));
         mWarnings.dump(pw);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 6f1f977..fff8305 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -197,7 +197,7 @@
             }
             mDrawable.onBatteryLevelChanged(100, false, false);
             mDrawable.onPowerSaveChanged(true);
-            mDrawable.disableShowPercent();
+            mDrawable.setShowPercent(false);
             ((ImageView) mCurrentView.findViewById(android.R.id.icon)).setImageDrawable(mDrawable);
             Checkable checkbox = (Checkable) mCurrentView.findViewById(android.R.id.toggle);
             checkbox.setChecked(mPowerSave);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
index ee0116e..3058c0a 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
@@ -25,7 +25,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 
-import static com.android.settingslib.graph.BatteryMeterDrawableBase.SHOW_PERCENT_SETTING;
+import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
 
 public class BatteryPreference extends DropDownPreference implements TunerService.Tunable {
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index 7acd888..489c05b 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -38,12 +38,10 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
-import com.android.settingslib.graph.BatteryMeterDrawableBase;
+import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
 import com.android.systemui.DemoMode;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.SystemUIApplication;
 import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
@@ -201,7 +199,7 @@
         // A couple special cases.
         Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null);
         Settings.System.putString(mContentResolver,
-                BatteryMeterDrawableBase.SHOW_PERCENT_SETTING, null);
+                SHOW_PERCENT_SETTING, null);
         Intent intent = new Intent(DemoMode.ACTION_DEMO);
         intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT);
         mContext.sendBroadcast(intent);
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index 8c74532..859e1a1 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -552,6 +552,11 @@
                 Slog.wtf(TAG, "showSaveLocked(): no mStructure");
                 return;
             }
+            if (mCurrentResponse == null) {
+                // Happens when the activity / session was finished before the service replied.
+                Slog.d(TAG, "showSaveLocked(): no mCurrentResponse yet");
+                return;
+            }
             final ArraySet<AutoFillId> savableIds = mCurrentResponse.getSavableIds();
             if (VERBOSE) Slog.v(TAG, "showSaveLocked(): savableIds=" + savableIds);
 
@@ -573,7 +578,6 @@
                         Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": "
                                 + state.mAutoFillValue);
                     }
-
                     mUi.showSaveUi();
                     return;
                 }
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 5fe8b1a..0ac51b9 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -53,6 +53,7 @@
 import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -676,6 +677,10 @@
         }
     }
 
+    private boolean isCallerSystemProcess(int callingUid) {
+        return callingUid == Process.SYSTEM_UID;
+    }
+
     /**
      * Obtain the package name of the current active network scorer.
      *
@@ -692,6 +697,27 @@
         return null;
     }
 
+
+    /**
+     * Returns metadata about the active scorer or <code>null</code> if there is no active scorer.
+     */
+    @Override
+    public NetworkScorerAppData getActiveScorer() {
+        // Only the system can access this data.
+        if (isCallerSystemProcess(getCallingUid()) || callerCanRequestScores()) {
+            synchronized (mServiceConnectionLock) {
+                if (mServiceConnection != null) {
+                    return mServiceConnection.mAppData;
+                }
+            }
+        } else {
+            throw new SecurityException(
+                    "Caller is neither the system process nor a score requester.");
+        }
+
+        return null;
+    }
+
     @Override
     public void disableScoring() {
         // Only the active scorer or the system should be allowed to disable scoring.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 93fb911..1726747 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5326,7 +5326,8 @@
                     for (int pid : pids) {
                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
                         final long sime = SystemClock.elapsedRealtime();
-                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
+
+                        Debug.dumpNativeBacktraceToFileTimeout(pid, tracesPath, 10);
                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
                     }
@@ -5563,7 +5564,7 @@
 
                 // Reset notification settings.
                 INotificationManager inm = NotificationManager.getService();
-                inm.clearData(packageName, pkgUidF);
+                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
             } catch (RemoteException e) {
             }
         } finally {
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index a1c5653..b4feef3 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -49,11 +49,18 @@
      * that they lost focus.
      */
     static final boolean ENFORCE_DUCKING = false;
+    /**
+     * set to true so the framework enforces muting media/game itself when the device is ringing
+     * or in a call.
+     */
+    static final boolean ENFORCE_MUTING_FOR_RING_OR_CALL = true;
 
     private final Context mContext;
     private final AppOpsManager mAppOps;
     private PlayerFocusEnforcer mFocusEnforcer; // never null
 
+    private boolean mRingOrCallActive = false;
+
     protected MediaFocusControl(Context cntxt, PlayerFocusEnforcer pfe) {
         mContext = cntxt;
         mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
@@ -78,6 +85,16 @@
         mFocusEnforcer.unduckPlayers(winner);
     }
 
+    @Override
+    public void mutePlayersForCall(int[] usagesToMute) {
+        mFocusEnforcer.mutePlayersForCall(usagesToMute);
+    }
+
+    @Override
+    public void unmutePlayersForCall() {
+        mFocusEnforcer.unmutePlayersForCall();
+    }
+
     //==========================================================================================
     // AudioFocus
     //==========================================================================================
@@ -139,7 +156,9 @@
                 stackIterator.next().dump(pw);
             }
         }
-        pw.println("\n Notify on duck: " + mNotifyFocusOwnerOnDuck +"\n");
+        pw.println("\n");
+        pw.println(" Notify on duck:  " + mNotifyFocusOwnerOnDuck + "\n");
+        pw.println(" In ring or call: " + mRingOrCallActive + "\n");
     }
 
     /**
@@ -401,6 +420,18 @@
     }
 
     /**
+     * Delay after entering ringing or call mode after which the framework will mute streams
+     * that are still playing.
+     */
+    private static final int RING_CALL_MUTING_ENFORCEMENT_DELAY_MS = 100;
+
+    /**
+     * Usages to mute when the device rings or is in a call
+     */
+    private final static int[] USAGES_TO_MUTE_IN_RING_OR_CALL =
+        { AudioAttributes.USAGE_MEDIA, AudioAttributes.USAGE_GAME };
+
+    /**
      * Return the volume ramp time expected before playback with the given AudioAttributes would
      * start after gaining audio focus.
      * @param attr attributes of the sound about to start playing
@@ -452,6 +483,10 @@
         }
 
         synchronized(mAudioFocusLock) {
+            boolean enteringRingOrCall = !mRingOrCallActive
+                    & (AudioSystem.IN_VOICE_COMM_FOCUS_ID.compareTo(clientId) == 0);
+            if (enteringRingOrCall) { mRingOrCallActive = true; }
+
             boolean focusGrantDelayed = false;
             if (!canReassignAudioFocus()) {
                 if ((flags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK) == 0) {
@@ -523,6 +558,9 @@
             notifyExtPolicyFocusGrant_syncAf(nfr.toAudioFocusInfo(),
                     AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
 
+            if (ENFORCE_MUTING_FOR_RING_OR_CALL & enteringRingOrCall) {
+                runAudioCheckerForRingOrCallAsync(true/*enteringRingOrCall*/);
+            }
         }//synchronized(mAudioFocusLock)
 
         return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
@@ -539,7 +577,15 @@
         try {
             // this will take care of notifying the new focus owner if needed
             synchronized(mAudioFocusLock) {
+                boolean exitingRingOrCall = mRingOrCallActive
+                        & (AudioSystem.IN_VOICE_COMM_FOCUS_ID.compareTo(clientId) == 0);
+                if (exitingRingOrCall) { mRingOrCallActive = false; }
+
                 removeFocusStackEntry(clientId, true /*signal*/, true /*notifyFocusFollowers*/);
+
+                if (ENFORCE_MUTING_FOR_RING_OR_CALL & exitingRingOrCall) {
+                    runAudioCheckerForRingOrCallAsync(false/*enteringRingOrCall*/);
+                }
             }
         } catch (java.util.ConcurrentModificationException cme) {
             // Catching this exception here is temporary. It is here just to prevent
@@ -559,4 +605,26 @@
         }
     }
 
+    private void runAudioCheckerForRingOrCallAsync(final boolean enteringRingOrCall) {
+        new Thread() {
+            public void run() {
+                if (enteringRingOrCall) {
+                    try {
+                        Thread.sleep(RING_CALL_MUTING_ENFORCEMENT_DELAY_MS);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+                synchronized (mAudioFocusLock) {
+                    // since the new thread starting running the state could have changed, so
+                    // we need to check again mRingOrCallActive, not enteringRingOrCall
+                    if (mRingOrCallActive) {
+                        mFocusEnforcer.mutePlayersForCall(USAGES_TO_MUTE_IN_RING_OR_CALL);
+                    } else {
+                        mFocusEnforcer.unmutePlayersForCall();
+                    }
+                }
+            }
+        }.start();
+    }
 }
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 4930c53..3f8bbe5 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -147,6 +147,11 @@
             for (int piid : mDuckedPlayers) {
                 pw.println(" " + piid);
             }
+            // players muted due to the device ringing or being in a call
+            pw.println("\n  muted player piids:");
+            for (int piid : mMutedPlayers) {
+                pw.println(" " + piid);
+            }
         }
     }
 
@@ -231,6 +236,7 @@
     //=================================================================
     // PlayerFocusEnforcer implementation
     private final ArrayList<Integer> mDuckedPlayers = new ArrayList<Integer>();
+    private final ArrayList<Integer> mMutedPlayers = new ArrayList<Integer>();
 
     @Override
     public boolean duckPlayers(FocusRequester winner, FocusRequester loser) {
@@ -290,9 +296,9 @@
                         && winner.hasSameUid(apc.getClientUid())) {
                     try {
                         if (DEBUG) { Log.v(TAG, "unducking player" + piid); }
+                        mDuckedPlayers.remove(new Integer(piid));
                         //FIXME just a test before we have VolumeShape
                         apc.getPlayerProxy().setPan(0.0f);
-                        mDuckedPlayers.remove(new Integer(piid));
                     } catch (Exception e) {
                         Log.e(TAG, "Error unducking player " + piid, e);
                     }
@@ -303,6 +309,65 @@
         }
     }
 
+    @Override
+    public void mutePlayersForCall(int[] usagesToMute) {
+        if (DEBUG) {
+            String log = new String("mutePlayersForCall: usages=");
+            for (int usage : usagesToMute) { log += " " + usage; }
+            Log.v(TAG, log);
+        }
+        synchronized (mPlayerLock) {
+            final Set<Integer> piidSet = mPlayers.keySet();
+            final Iterator<Integer> piidIterator = piidSet.iterator();
+            // find which players to mute
+            while (piidIterator.hasNext()) {
+                final Integer piid = piidIterator.next();
+                final AudioPlaybackConfiguration apc = mPlayers.get(piid);
+                final int playerUsage = apc.getAudioAttributes().getUsage();
+                boolean mute = false;
+                for (int usageToMute : usagesToMute) {
+                    if (playerUsage == usageToMute) {
+                        mute = true;
+                        break;
+                    }
+                }
+                if (mute) {
+                    try {
+                        if (DEBUG) { Log.v(TAG, "muting player" + piid); }
+                        apc.getPlayerProxy().setVolume(0.0f);
+                        mMutedPlayers.add(piid);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Error muting player " + piid, e);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void unmutePlayersForCall() {
+        if (DEBUG) {
+            Log.v(TAG, "unmutePlayersForCall()");
+        }
+        synchronized (mPlayerLock) {
+            if (mMutedPlayers.isEmpty()) {
+                return;
+            }
+            for (int piid : mMutedPlayers) {
+                final AudioPlaybackConfiguration apc = mPlayers.get(piid);
+                if (apc != null) {
+                    try {
+                        if (DEBUG) { Log.v(TAG, "unmuting player" + piid); }
+                        apc.getPlayerProxy().setVolume(1.0f);
+                        mMutedPlayers.remove(new Integer(piid));
+                    } catch (Exception e) {
+                        Log.e(TAG, "Error unmuting player " + piid, e);
+                    }
+                }
+            }
+        }
+    }
+
     //=================================================================
     // Track playback activity listeners
 
diff --git a/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java b/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java
index acb4f0d..0733eca 100644
--- a/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java
+++ b/services/core/java/com/android/server/audio/PlayerFocusEnforcer.java
@@ -28,4 +28,8 @@
     public boolean duckPlayers(FocusRequester winner, FocusRequester loser);
 
     public void unduckPlayers(FocusRequester winner);
+
+    public void mutePlayersForCall(int[] usagesToMute);
+
+    public void unmutePlayersForCall();
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 32c98a1..cc3fc00 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1698,7 +1698,7 @@
 
 
         @Override
-        public void clearData(String packageName, int uid) throws RemoteException {
+        public void clearData(String packageName, int uid, boolean fromApp) throws RemoteException {
             checkCallerIsSystem();
 
             // Cancel posted notifications
@@ -1713,8 +1713,10 @@
             mConditionProviders.onPackagesChanged(true, new String[] {packageName});
 
             // Reset notification preferences
-            mRankingHelper.onPackagesChanged(true, UserHandle.getCallingUserId(),
-                    new String[] {packageName}, new int[] {uid});
+            if (!fromApp) {
+                mRankingHelper.onPackagesChanged(true, UserHandle.getCallingUserId(),
+                        new String[]{packageName}, new int[]{uid});
+            }
 
             savePolicyFile();
         }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 4cbeec8..46c449b 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -674,7 +674,7 @@
     public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid, boolean includeDeleted) {
         Preconditions.checkNotNull(pkg);
-        List<NotificationChannelGroup> groups = new ArrayList<>();
+        Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
         Record r = getRecord(pkg, uid);
         if (r == null) {
             return ParceledListSlice.emptyList();
@@ -685,23 +685,21 @@
             final NotificationChannel nc = r.channels.valueAt(i);
             if (includeDeleted || !nc.isDeleted()) {
                 if (nc.getGroup() != null) {
-                    // lazily populate channel list
-                    NotificationChannelGroup ncg = r.groups.get(nc.getGroup());
+                    NotificationChannelGroup ncg = groups.get(nc.getGroup());
+                    if (ncg == null ) {
+                        ncg = r.groups.get(nc.getGroup()).clone();
+                        groups.put(nc.getGroup(), ncg);
+                    }
                     ncg.addChannel(nc);
                 } else {
                     nonGrouped.addChannel(nc);
                 }
             }
         }
-        for (NotificationChannelGroup group : r.groups.values()) {
-            if (group.getChannels().size() > 0) {
-                groups.add(group);
-            }
-        }
         if (nonGrouped.getChannels().size() > 0) {
-            groups.add(nonGrouped);
+            groups.put(null, nonGrouped);
         }
-        return new ParceledListSlice<>(groups);
+        return new ParceledListSlice<>(new ArrayList<>(groups.values()));
     }
 
     @Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9d8372a..5075a41 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1887,7 +1887,10 @@
 
     private void setDeviceOwnerSystemPropertyLocked() {
         // Device owner may still be provisioned, do not set the read-only system property yet.
-        if (mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
+        // Wear devices don't set device_provisioned until the device is paired, so allow
+        // device_owner property to be set without that.
+        if (!mIsWatch
+                && mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
             return;
         }
         // Still at the first stage of CryptKeeper double bounce, mOwners.hasDeviceOwner is
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index e20b571..9ea9ce9 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.notification;
 
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.fail;
 
@@ -56,6 +58,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -168,7 +171,7 @@
 
     private NotificationChannel getDefaultChannel() {
         return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
-                NotificationManager.IMPORTANCE_LOW);
+                IMPORTANCE_LOW);
     }
 
     private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, String... channelIds)
@@ -260,7 +263,7 @@
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         NotificationChannel channel2 =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel2.enableLights(true);
         channel2.setBypassDnd(true);
@@ -294,10 +297,26 @@
                 mHelper.getNotificationChannel(pkg, uid, channel2.getId(), false));
         assertNotNull(mHelper.getNotificationChannel(
                 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false));
-        assertEquals(ncg.getId(),
-                mHelper.getNotificationChannelGroups(pkg, uid, false).getList().get(0).getId());
-        assertEquals(channel2.getGroup(), mHelper.getNotificationChannelGroups(
-                pkg, uid, false).getList().get(0).getChannels().get(0).getGroup());
+
+        List<NotificationChannelGroup> actualGroups =
+                mHelper.getNotificationChannelGroups(pkg, uid, false).getList();
+        boolean foundNcg = false;
+        for (NotificationChannelGroup actual : actualGroups) {
+            if (ncg.getId().equals(actual.getId())) {
+                foundNcg = true;
+                 break;
+            }
+        }
+        assertTrue(foundNcg);
+
+        boolean foundChannel2Group = false;
+        for (NotificationChannelGroup actual : actualGroups) {
+            if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) {
+                foundChannel2Group = true;
+                break;
+            }
+        }
+        assertTrue(foundChannel2Group);
     }
 
     @Test
@@ -332,7 +351,7 @@
 
         final NotificationChannel defaultChannel = mHelper.getNotificationChannel(
                 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false);
-        defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+        defaultChannel.setImportance(IMPORTANCE_LOW);
         mHelper.updateNotificationChannel(pkg, uid, defaultChannel);
 
         ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(),
@@ -344,7 +363,7 @@
         parser.nextTag();
         mHelper.readXml(parser, false);
 
-        assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
+        assertEquals(IMPORTANCE_LOW, mHelper.getNotificationChannel(
                 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance());
     }
 
@@ -376,7 +395,7 @@
         final NotificationChannel updated2 = mHelper.getNotificationChannel(
                 pkg2, uid2, NotificationChannel.DEFAULT_CHANNEL_ID, false);
         // clamped
-        assertEquals(NotificationManager.IMPORTANCE_LOW, updated2.getImportance());
+        assertEquals(IMPORTANCE_LOW, updated2.getImportance());
         assertFalse(updated2.canBypassDnd());
         assertEquals(Notification.VISIBILITY_PRIVATE, updated2.getLockscreenVisibility());
         assertEquals(NotificationChannel.USER_LOCKED_VISIBILITY, updated2.getUserLockedFields());
@@ -388,7 +407,7 @@
 
         try {
             mHelper.createNotificationChannel(pkg, uid,
-                    new NotificationChannel(pkg, "", NotificationManager.IMPORTANCE_LOW), true);
+                    new NotificationChannel(pkg, "", IMPORTANCE_LOW), true);
             fail("Channel creation should fail");
         } catch (IllegalArgumentException e) {
             // pass
@@ -399,7 +418,7 @@
     public void testUpdate_userLockedImportance() throws Exception {
         // all fields locked by user
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
 
         mHelper.createNotificationChannel(pkg, uid, channel, false);
@@ -418,7 +437,7 @@
     public void testUpdate_userLockedVisibility() throws Exception {
         // all fields locked by user
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
         channel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
 
@@ -439,7 +458,7 @@
     public void testUpdate_userLockedVibration() throws Exception {
         // all fields locked by user
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.enableLights(false);
         channel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
 
@@ -461,7 +480,7 @@
     public void testUpdate_userLockedLights() throws Exception {
         // all fields locked by user
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.enableLights(false);
         channel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
 
@@ -482,7 +501,7 @@
     public void testUpdate_userLockedPriority() throws Exception {
         // all fields locked by user
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setBypassDnd(true);
         channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
 
@@ -503,7 +522,7 @@
     public void testUpdate_userLockedRingtone() throws Exception {
         // all fields locked by user
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
 
@@ -523,7 +542,7 @@
     @Test
     public void testUpdate_userLockedBadge() throws Exception {
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setShowBadge(true);
         channel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE);
 
@@ -543,7 +562,7 @@
     public void testUpdate() throws Exception {
         // no fields locked by user
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
@@ -575,7 +594,7 @@
     @Test
     public void testCreateChannel_CannotChangeHiddenFields() throws Exception {
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
@@ -602,7 +621,7 @@
     @Test
     public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception {
         final NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
@@ -629,7 +648,7 @@
     @Test
     public void testGetDeletedChannel() throws Exception {
         NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
@@ -655,7 +674,7 @@
     public void testGetDeletedChannels() throws Exception {
         Map<String, NotificationChannel> channelMap = new HashMap<>();
         NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel.enableLights(true);
         channel.setBypassDnd(true);
@@ -694,7 +713,7 @@
     @Test
     public void testUpdateDeletedChannels() throws Exception {
         NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         mHelper.createNotificationChannel(pkg, uid, channel, true);
 
         mHelper.deleteNotificationChannel(pkg, uid, channel.getId());
@@ -719,7 +738,7 @@
     public void testCreateDeletedChannel() throws Exception {
         long[] vibration = new long[]{100, 67, 145, 156};
         NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setVibrationPattern(vibration);
 
         mHelper.createNotificationChannel(pkg, uid, channel, true);
@@ -740,7 +759,7 @@
     public void testCreateChannel_alreadyExists() throws Exception {
         long[] vibration = new long[]{100, 67, 145, 156};
         NotificationChannel channel =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setVibrationPattern(vibration);
 
         mHelper.createNotificationChannel(pkg, uid, channel, true);
@@ -761,7 +780,7 @@
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         NotificationChannel channel2 =
-                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
 
         mHelper.createNotificationChannel(pkg, uid, channel1, true);
         mHelper.createNotificationChannel(pkg, uid, channel2, false);
@@ -900,4 +919,29 @@
             }
         }
     }
+
+    @Test
+    public void testGetChannelGroups_noSideEffects() throws Exception {
+        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
+        mHelper.createNotificationChannelGroup(pkg, uid, ncg, true);
+
+        NotificationChannel channel1 =
+                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
+        channel1.setGroup(ncg.getId());
+        mHelper.createNotificationChannel(pkg, uid, channel1, true);
+        mHelper.getNotificationChannelGroups(pkg, uid, true).getList();
+
+        channel1.setImportance(IMPORTANCE_LOW);
+        mHelper.updateNotificationChannel(pkg, uid, channel1);
+
+        List<NotificationChannelGroup> actual =
+                mHelper.getNotificationChannelGroups(pkg, uid, true).getList();
+
+        assertEquals(2, actual.size());
+        for (NotificationChannelGroup group : actual) {
+            if (Objects.equals(group.getId(),ncg.getId())) {
+                assertEquals(1, group.getChannels().size());
+            }
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index fa9e9a8..3a88e9c 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -829,6 +829,50 @@
         assertEquals(expectedList, actualList);
     }
 
+    @Test
+    public void testGetActiveScorer_notConnected_canRequestScores() throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+        assertNull(mNetworkScoreService.getActiveScorer());
+    }
+
+    @Test
+    public void testGetActiveScorer_notConnected_canNotRequestScores() throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
+        try {
+            mNetworkScoreService.getActiveScorer();
+            fail("SecurityException expected.");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testGetActiveScorer_connected_canRequestScores()
+            throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+        NetworkScorerAppData expectedAppData =
+                new NetworkScorerAppData(Binder.getCallingUid(), RECOMMENDATION_SERVICE_COMP);
+        bindToScorer(expectedAppData);
+        assertEquals(expectedAppData, mNetworkScoreService.getActiveScorer());
+    }
+
+    @Test
+    public void testGetActiveScorer_connected_canNotRequestScores()
+            throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
+        bindToScorer(false);
+        try {
+            mNetworkScoreService.getActiveScorer();
+            fail("SecurityException expected.");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
     // "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
     private void injectProvider() {
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
@@ -849,9 +893,13 @@
     }
 
     private void bindToScorer(boolean callerIsScorer) {
-        final int callingUid = callerIsScorer ? Binder.getCallingUid() : 0;
+        final int callingUid = callerIsScorer ? Binder.getCallingUid() : Binder.getCallingUid() + 1;
         NetworkScorerAppData appData =
                 new NetworkScorerAppData(callingUid, RECOMMENDATION_SERVICE_COMP);
+        bindToScorer(appData);
+    }
+
+    private void bindToScorer(NetworkScorerAppData appData) {
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData);
         when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
                 isA(UserHandle.class))).thenReturn(true);
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 6ca0bc5..d9465dc 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -259,4 +259,9 @@
      * @see TelecomServiceImpl#isOutgoingCallPermitted
      */
     boolean isOutgoingCallPermitted(in PhoneAccountHandle phoneAccountHandle);
+
+    /**
+     * @see TelecomServiceImpl#waitOnHandler
+     */
+    void waitOnHandlers();
 }
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 5767f11..0401737 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -172,12 +172,10 @@
     @Override
     public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
         mAssistStructure = structure;
-        if (mAssistStructure != null) {
-            if (mAssistVisualizer != null) {
+        if (mAssistVisualizer != null) {
+            if (mAssistStructure != null) {
                 mAssistVisualizer.setAssistStructure(mAssistStructure);
-            }
-        } else {
-            if (mAssistVisualizer != null) {
+            } else {
                 mAssistVisualizer.clearAssistData();
             }
         }
@@ -207,19 +205,24 @@
 
     @Override
     public void onHandleScreenshot(Bitmap screenshot) {
-        if (screenshot != null) {
-            mScreenshot.setImageBitmap(screenshot);
-            mScreenshot.setAdjustViewBounds(true);
-            mScreenshot.setMaxWidth(screenshot.getWidth() / 3);
-            mScreenshot.setMaxHeight(screenshot.getHeight() / 3);
-            mFullScreenshot.setImageBitmap(screenshot);
-        } else {
-            mScreenshot.setImageDrawable(null);
-            mFullScreenshot.setImageDrawable(null);
+        if (mScreenshot != null) {
+            if (screenshot != null) {
+                mScreenshot.setImageBitmap(screenshot);
+                mScreenshot.setAdjustViewBounds(true);
+                mScreenshot.setMaxWidth(screenshot.getWidth() / 3);
+                mScreenshot.setMaxHeight(screenshot.getHeight() / 3);
+                mFullScreenshot.setImageBitmap(screenshot);
+            } else {
+                mScreenshot.setImageDrawable(null);
+                mFullScreenshot.setImageDrawable(null);
+            }
         }
     }
 
     void updateState() {
+        if (mTopContent == null) {
+            return;
+        }
         if (mState == STATE_IDLE) {
             mTopContent.setVisibility(View.VISIBLE);
             mBottomContent.setVisibility(View.GONE);
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 7b73b4b..1f661c4 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -120,7 +120,7 @@
     public void setUpdateIdentifier(int updateIdentifier) {
         mUpdateIdentifier = updateIdentifier;
     }
-    public int getUpdateIdentififer() {
+    public int getUpdateIdentifier() {
         return mUpdateIdentifier;
     }
 
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index 025d4d3..620759d 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -100,7 +100,7 @@
     public void setCheckAaaServerCertStatus(boolean checkAaaServerCertStatus) {
         mCheckAaaServerCertStatus = checkAaaServerCertStatus;
     }
-    public boolean getCheckAaaServerStatus() {
+    public boolean getCheckAaaServerCertStatus() {
         return mCheckAaaServerCertStatus;
     }
 
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 7a46129..8ec40c0 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -131,7 +131,7 @@
     public void setMatchAnyOis(long[] matchAnyOis) {
         mMatchAnyOis = matchAnyOis;
     }
-    public long[] getMatchAnysOis() {
+    public long[] getMatchAnyOis() {
         return mMatchAnyOis;
     }
 
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
index caca0e4b..63238e8 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -77,7 +77,7 @@
     public void setMinHomeDownlinkBandwidth(long minHomeDownlinkBandwidth) {
         mMinHomeDownlinkBandwidth = minHomeDownlinkBandwidth;
     }
-    public long getMinHomeDownlinkBandWidht() {
+    public long getMinHomeDownlinkBandwidth() {
         return mMinHomeDownlinkBandwidth;
     }
     private long mMinHomeUplinkBandwidth = Long.MIN_VALUE;