Merge "Fix battery icon tint in QS during battery saver" into oc-dev
diff --git a/Android.mk b/Android.mk
index 8f99bc0..b5f8cb0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1061,6 +1061,7 @@
 		-showAnnotation android.annotation.SystemApi \
 		-api $(INTERNAL_PLATFORM_SYSTEM_API_FILE) \
 		-removedApi $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE) \
+		-exactApi $(INTERNAL_PLATFORM_SYSTEM_EXACT_API_FILE) \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
@@ -1097,6 +1098,7 @@
                -showAnnotation android.annotation.TestApi \
                -api $(INTERNAL_PLATFORM_TEST_API_FILE) \
                -removedApi $(INTERNAL_PLATFORM_TEST_REMOVED_API_FILE) \
+               -exactApi $(INTERNAL_PLATFORM_TEST_EXACT_API_FILE) \
                -nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
@@ -1250,8 +1252,6 @@
 include $(BUILD_DROIDDOC)
 
 # ==== docs for the web (on the androiddevdocs app engine server) =======================
-# TODO: Fix the System API docs build.
-ifneq ($(filter online-system-api-sdk-docs,$(MAKECMDGOALS)),)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
@@ -1282,11 +1282,10 @@
 		-samplesdir $(samples_dir)
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
-# Don't build by default
+
 LOCAL_UNINSTALLABLE_MODULE := true
 
 include $(BUILD_DROIDDOC)
-endif  # online-system-api-sdk-docs in make command line.
 
 # ==== docs for the web (on the devsite app engine server) =======================
 include $(CLEAR_VARS)
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 26ac6ad..ad272b8 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -131,6 +131,7 @@
 import java.util.HashMap;
 import java.util.List;
 
+import static android.os.Build.VERSION_CODES.O;
 import static java.lang.Character.MIN_VALUE;
 
 /**
@@ -974,6 +975,18 @@
     @CallSuper
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
+
+        if (getApplicationInfo().targetSdkVersion >= O && mActivityInfo.isFixedOrientation()) {
+            final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
+            final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
+            ta.recycle();
+
+            if (isTranslucentOrFloating) {
+                throw new IllegalStateException(
+                        "Only fullscreen opaque activities can request orientation");
+            }
+        }
+
         if (mLastNonConfigurationInstances != null) {
             mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
         }
@@ -7432,7 +7445,7 @@
         final int offsetX = (anchorBounds != null)
                 ? anchorBounds.left - actualAnchorBounds.left : 0;
         int offsetY = (anchorBounds != null)
-                ? anchorBounds.bottom - actualAnchorBounds.bottom : 0;
+                ?  anchorBounds.top - actualAnchorBounds.top : 0;
 
         final boolean wasShowing;
 
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 587ab3b..9a01476 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Configuration.NativeConfig;
+import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Printer;
@@ -440,7 +441,6 @@
      * @hide
      */
     public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000;
-
     /**
      * @hide Bit in {@link #flags}: If set, this component will only be seen
      * by the system user.  Only works with broadcast receivers.  Set from the
@@ -978,12 +978,20 @@
      * Returns true if the activity's orientation is fixed.
      * @hide
      */
-    boolean isFixedOrientation() {
+    public boolean isFixedOrientation() {
         return isFixedOrientationLandscape() || isFixedOrientationPortrait()
                 || screenOrientation == SCREEN_ORIENTATION_LOCKED;
     }
 
     /**
+     * Returns true if the specified orientation is considered fixed.
+     * @hide
+     */
+    static public boolean isFixedOrientation(int orientation) {
+        return isFixedOrientationLandscape(orientation) || isFixedOrientationPortrait(orientation);
+    }
+
+    /**
      * Returns true if the activity's orientation is fixed to landscape.
      * @hide
      */
@@ -1162,6 +1170,25 @@
         dest.writeFloat(maxAspectRatio);
     }
 
+    /**
+     * Determines whether the {@link Activity} is considered translucent or floating.
+     * @hide
+     */
+    public static boolean isTranslucentOrFloating(TypedArray attributes) {
+        final boolean isTranslucent =
+                attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent,
+                        false);
+        final boolean isSwipeToDismiss = !attributes.hasValue(
+                com.android.internal.R.styleable.Window_windowIsTranslucent)
+                && attributes.getBoolean(
+                        com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
+        final boolean isFloating =
+                attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating,
+                        false);
+
+        return isFloating || isTranslucent || isSwipeToDismiss;
+    }
+
     public static final Parcelable.Creator<ActivityInfo> CREATOR
             = new Parcelable.Creator<ActivityInfo>() {
         public ActivityInfo createFromParcel(Parcel source) {
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 3267172..244c7a2 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -340,7 +340,12 @@
     private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
         Display display = mDisplays.get(displayId);
         if (display == null) {
-            display = mGlobal.getCompatibleDisplay(displayId, mContext.getResources());
+            // TODO: We cannot currently provide any override configurations for metrics on displays
+            // other than the display the context is associated with.
+            final Context context = mContext.getDisplay().getDisplayId() == displayId
+                    ? mContext : mContext.getApplicationContext();
+
+            display = mGlobal.getCompatibleDisplay(displayId, context.getResources());
             if (display != null) {
                 mDisplays.put(displayId, display);
             }
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index bf0601d..13ebe5c 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -17,6 +17,8 @@
 package android.widget;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.app.INotificationManager;
 import android.app.ITransientNotification;
@@ -26,6 +28,7 @@
 import android.graphics.PixelFormat;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -62,7 +65,7 @@
  * <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Toast Notifications</a> developer
  * guide.</p>
  * </div>
- */ 
+ */
 public class Toast {
     static final String TAG = "Toast";
     static final boolean localLOGV = false;
@@ -99,8 +102,16 @@
      *                 or {@link android.app.Activity} object.
      */
     public Toast(Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Constructs an empty Toast object.  If looper is null, Looper.myLooper() is used.
+     * @hide
+     */
+    public Toast(@NonNull Context context, @Nullable Looper looper) {
         mContext = context;
-        mTN = new TN(context.getPackageName());
+        mTN = new TN(context.getPackageName(), looper);
         mTN.mY = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.toast_y_offset);
         mTN.mGravity = context.getResources().getInteger(
@@ -170,7 +181,7 @@
     public int getDuration() {
         return mDuration;
     }
-    
+
     /**
      * Set the margins of the view.
      *
@@ -226,7 +237,7 @@
     public int getXOffset() {
         return mTN.mX;
     }
-    
+
     /**
      * Return the Y offset in pixels to apply to the gravity's location.
      */
@@ -241,7 +252,7 @@
     public WindowManager.LayoutParams getWindowParams() {
         return mTN.mParams;
     }
-    
+
     /**
      * Make a standard toast that just contains a text view.
      *
@@ -253,14 +264,24 @@
      *
      */
     public static Toast makeText(Context context, CharSequence text, @Duration int duration) {
-        Toast result = new Toast(context);
+        return makeText(context, null, text, duration);
+    }
+
+    /**
+     * Make a standard toast to display using the specified looper.
+     * If looper is null, Looper.myLooper() is used.
+     * @hide
+     */
+    public static Toast makeText(@NonNull Context context, @Nullable Looper looper,
+            @NonNull CharSequence text, @Duration int duration) {
+        Toast result = new Toast(context, looper);
 
         LayoutInflater inflate = (LayoutInflater)
                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
         TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
         tv.setText(text);
-        
+
         result.mNextView = v;
         result.mDuration = duration;
 
@@ -290,7 +311,7 @@
     public void setText(@StringRes int resId) {
         setText(mContext.getText(resId));
     }
-    
+
     /**
      * Update the text in a Toast that was previously created using one of the makeText() methods.
      * @param s The new text for the Toast.
@@ -327,34 +348,7 @@
         private static final int SHOW = 0;
         private static final int HIDE = 1;
         private static final int CANCEL = 2;
-        final Handler mHandler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case SHOW: {
-                        IBinder token = (IBinder) msg.obj;
-                        handleShow(token);
-                        break;
-                    }
-                    case HIDE: {
-                        handleHide();
-                        // Don't do this in handleHide() because it is also invoked by handleShow()
-                        mNextView = null;
-                        break;
-                    }
-                    case CANCEL: {
-                        handleHide();
-                        // Don't do this in handleHide() because it is also invoked by handleShow()
-                        mNextView = null;
-                        try {
-                            getService().cancelToast(mPackageName, TN.this);
-                        } catch (RemoteException e) {
-                        }
-                        break;
-                    }
-                }
-            }
-        };
+        final Handler mHandler;
 
         int mGravity;
         int mX, mY;
@@ -373,7 +367,7 @@
         static final long SHORT_DURATION_TIMEOUT = 4000;
         static final long LONG_DURATION_TIMEOUT = 7000;
 
-        TN(String packageName) {
+        TN(String packageName, @Nullable Looper looper) {
             // XXX This should be changed to use a Dialog, with a Theme.Toast
             // defined that sets up the layout params appropriately.
             final WindowManager.LayoutParams params = mParams;
@@ -388,6 +382,45 @@
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 
             mPackageName = packageName;
+
+            if (looper == null) {
+                // Use Looper.myLooper() if looper is not specified.
+                looper = Looper.myLooper();
+                if (looper == null) {
+                    throw new RuntimeException(
+                            "Can't toast on a thread that has not called Looper.prepare()");
+                }
+            }
+            mHandler = new Handler(looper, null) {
+                @Override
+                public void handleMessage(Message msg) {
+                    switch (msg.what) {
+                        case SHOW: {
+                            IBinder token = (IBinder) msg.obj;
+                            handleShow(token);
+                            break;
+                        }
+                        case HIDE: {
+                            handleHide();
+                            // Don't do this in handleHide() because it is also invoked by
+                            // handleShow()
+                            mNextView = null;
+                            break;
+                        }
+                        case CANCEL: {
+                            handleHide();
+                            // Don't do this in handleHide() because it is also invoked by
+                            // handleShow()
+                            mNextView = null;
+                            try {
+                                getService().cancelToast(mPackageName, TN.this);
+                            } catch (RemoteException e) {
+                            }
+                            break;
+                        }
+                    }
+                }
+            };
         }
 
         /**
@@ -469,7 +502,7 @@
             event.setPackageName(mView.getContext().getPackageName());
             mView.dispatchPopulateAccessibilityEvent(event);
             accessibilityManager.sendAccessibilityEvent(event);
-        }        
+        }
 
         public void handleHide() {
             if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f418435..18cfc99 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1314,6 +1314,13 @@
     <permission android:name="android.permission.NETWORK_STACK"
         android:protectionLevel="signature" />
 
+    <!-- Allows Settings and SystemUI to call methods in Networking services
+         <p>Not for use by third-party or privileged applications.
+         @hide This should only be used by Settings and SystemUI.
+    -->
+    <permission android:name="android.permission.NETWORK_SETTINGS"
+        android:protectionLevel="signature" />
+
     <!-- ======================================= -->
     <!-- Permissions for short range, peripheral networks -->
     <!-- ======================================= -->
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index 60df492..90b74ac 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -59,7 +59,8 @@
                     android:layout_marginLeft="16dp"
                     android:src="@android:drawable/ic_close"
                     android:alpha="0.54"
-                    android:background="?android:attr/selectableItemBackgroundBorderless">
+                    android:background="?android:attr/selectableItemBackgroundBorderless"
+                    android:contentDescription="@android:string/close_button_text">
                 </ImageView>
 
             </LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index aeb564b..8b9b0e2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2876,4 +2876,7 @@
     <!-- Handle volume keys directly in Window Manager without passing them to the foreground app -->
     <bool name="config_handleVolumeKeysInWindowManager">false</bool>
 
+    <!-- Volume level of in-call notification tone playback,
+         relative to the overall voice call stream volume [0..100] -->
+    <integer name="config_inCallNotificationVolumeRelative">67</integer>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 72011e8..cb1851b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4484,7 +4484,7 @@
         <item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> selected</item>
     </plurals>
 
-    <string name="default_notification_channel_label">Miscellaneous</string>
+    <string name="default_notification_channel_label">Uncategorized</string>
 
     <string name="importance_from_user">You set the importance of these notifications.</string>
     <string name="importance_from_person">This is important because of the people involved.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2aab590..3551bc9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3013,4 +3013,6 @@
   <java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
 
   <java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
+
+  <java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
 </resources>
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index ea804d0..3fe730f 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -599,9 +599,9 @@
         private final Context context;
         private final ServiceConnection serviceConnection;
         private final IKeyChainService service;
-        private KeyChainConnection(Context context,
-                                   ServiceConnection serviceConnection,
-                                   IKeyChainService service) {
+        protected KeyChainConnection(Context context,
+                                     ServiceConnection serviceConnection,
+                                     IKeyChainService service) {
             this.context = context;
             this.serviceConnection = serviceConnection;
             this.service = service;
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index dd66649..9bd93aa 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -35,6 +35,7 @@
 import com.android.internal.app.IAppOpsService;
 
 import java.lang.IllegalArgumentException;
+import java.lang.ref.WeakReference;
 import java.util.Objects;
 
 /**
@@ -45,11 +46,11 @@
  */
 public abstract class PlayerBase {
 
-    private final static String TAG = "PlayerBase";
-    private final static boolean DEBUG = false;
+    private static final String TAG = "PlayerBase";
+    private static final boolean DEBUG = false;
     private static IAudioService sService; //lazy initialization, use getService()
     /** Debug app ops */
-    protected static final boolean DEBUG_APP_OPS = Log.isLoggable(TAG + ".AO", Log.DEBUG);
+    private static final boolean DEBUG_APP_OPS = false;
 
     // parameters of the player that affect AppOps
     protected AudioAttributes mAttributes;
@@ -94,19 +95,9 @@
         IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
         mAppOps = IAppOpsService.Stub.asInterface(b);
         // initialize mHasAppOpsPlayAudio
-        synchronized (mLock) {
-            updateAppOpsPlayAudio_sync();
-        }
+        updateAppOpsPlayAudio();
         // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
-        mAppOpsCallback = new IAppOpsCallback.Stub() {
-            public void opChanged(int op, int uid, String packageName) {
-                synchronized (mLock) {
-                    if (op == AppOpsManager.OP_PLAY_AUDIO) {
-                        updateAppOpsPlayAudio_sync();
-                    }
-                }
-            }
-        };
+        mAppOpsCallback = new IAppOpsCallbackWrapper(this);
         try {
             mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
                     ActivityThread.currentPackageName(), mAppOpsCallback);
@@ -114,10 +105,8 @@
             mHasAppOpsPlayAudio = false;
         }
         try {
-            if (mIPlayer == null) {
-                throw new IllegalStateException("Cannot register a player with a null mIPlayer");
-            }
-            newPiid = getService().trackPlayer(new PlayerIdCard(mImplType, mAttributes, mIPlayer));
+            newPiid = getService().trackPlayer(
+                    new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this)));
         } catch (RemoteException e) {
             Log.e(TAG, "Error talking to audio service, player will not be tracked", e);
         }
@@ -259,6 +248,12 @@
         }
     }
 
+    private void updateAppOpsPlayAudio() {
+        synchronized (mLock) {
+            updateAppOpsPlayAudio_sync();
+        }
+    }
+
     /**
      * To be called whenever a condition that might affect audibility of this player is updated.
      * Must be called synchronized on mLock.
@@ -406,47 +401,95 @@
     abstract void playerStop();
 
     //=====================================================================
+    private static class IAppOpsCallbackWrapper extends IAppOpsCallback.Stub {
+        private final WeakReference<PlayerBase> mWeakPB;
+
+        public IAppOpsCallbackWrapper(PlayerBase pb) {
+            mWeakPB = new WeakReference<PlayerBase>(pb);
+        }
+
+        @Override
+        public void opChanged(int op, int uid, String packageName) {
+            if (op == AppOpsManager.OP_PLAY_AUDIO) {
+                if (DEBUG_APP_OPS) { Log.v(TAG, "opChanged: op=PLAY_AUDIO pack=" + packageName); }
+                final PlayerBase pb = mWeakPB.get();
+                if (pb != null) {
+                    pb.updateAppOpsPlayAudio();
+                }
+            }
+        }
+    }
+
+    //=====================================================================
     /**
-     * Implementation of IPlayer for all subclasses of PlayerBase
+     * Wrapper around an implementation of IPlayer for all subclasses of PlayerBase
+     * that doesn't keep a strong reference on PlayerBase
      */
-    private IPlayer mIPlayer = new IPlayer.Stub() {
+    private static class IPlayerWrapper extends IPlayer.Stub {
+        private final WeakReference<PlayerBase> mWeakPB;
+
+        public IPlayerWrapper(PlayerBase pb) {
+            mWeakPB = new WeakReference<PlayerBase>(pb);
+        }
+
         @Override
         public void start() {
-            playerStart();
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerStart();
+            }
         }
 
         @Override
         public void pause() {
-            playerPause();
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerPause();
+            }
         }
 
         @Override
         public void stop() {
-            playerStop();
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerStop();
+            }
         }
 
         @Override
         public void setVolume(float vol) {
-            baseSetVolume(vol, vol);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetVolume(vol, vol);
+            }
         }
 
         @Override
         public void setPan(float pan) {
-            baseSetPan(pan);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetPan(pan);
+            }
         }
 
         @Override
         public void setStartDelayMs(int delayMs) {
-            baseSetStartDelayMs(delayMs);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetStartDelayMs(delayMs);
+            }
         }
 
         @Override
         public void applyVolumeShaper(
                 @NonNull VolumeShaper.Configuration configuration,
                 @NonNull VolumeShaper.Operation operation) {
-            /* void */ playerApplyVolumeShaper(configuration, operation);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerApplyVolumeShaper(configuration, operation);
+            }
         }
-    };
+    }
 
     //=====================================================================
     /**
@@ -455,8 +498,8 @@
     public static class PlayerIdCard implements Parcelable {
         public final int mPlayerType;
 
-        public final static int AUDIO_ATTRIBUTES_NONE = 0;
-        public final static int AUDIO_ATTRIBUTES_DEFINED = 1;
+        public static final int AUDIO_ATTRIBUTES_NONE = 0;
+        public static final int AUDIO_ATTRIBUTES_DEFINED = 1;
         public final AudioAttributes mAttributes;
         public final IPlayer mIPlayer;
 
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index e774c71..3eb9d52 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -943,7 +943,8 @@
 
         // Sanity-check: are we actually being asked to install an audio file?
         final String mimeType = mContext.getContentResolver().getType(fileUri);
-        if(mimeType == null || !mimeType.startsWith("audio/")) {
+        if(mimeType == null ||
+                !(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) {
             throw new IllegalArgumentException("Ringtone file must have MIME type \"audio/*\"."
                     + " Given file has MIME type \"" + mimeType + "\"");
         }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 490bee4..290ce1f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -528,7 +528,7 @@
         <activity
             android:name=".settings.BrightnessDialog"
             android:label="@string/quick_settings_brightness_dialog_title"
-            android:theme="@android:style/Theme.DeviceDefault.Dialog"
+            android:theme="@android:style/Theme.DeviceDefault.Light.Dialog"
             android:finishOnCloseSystemDialogs="true"
             android:launchMode="singleInstance"
             android:excludeFromRecents="true"
diff --git a/packages/SystemUI/res/drawable/ic_data_unavailable.xml b/packages/SystemUI/res/drawable/ic_data_unavailable.xml
index 27a7697..ffb2af7 100644
--- a/packages/SystemUI/res/drawable/ic_data_unavailable.xml
+++ b/packages/SystemUI/res/drawable/ic_data_unavailable.xml
@@ -12,7 +12,6 @@
     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.
-        M12.0,12.0m-9.5,0.0a9.5,9.5 0.0,1.0 1.0,19.0 0.0a9.5,9.5 0.0,1.0 1.0,-19.0 0.0
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="24.0dp"
@@ -20,13 +19,9 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:pathData="M12.0,2.5c-5.246705,0.0 -9.5,4.253295 -9.5,9.5 0.0,5.246705 4.253295,9.5 9.5,9.5 2.771732,0.0 5.263364,-1.200342 7.0,-3.09375l0.0,-0.21875 0.0,-7.5 0.0,-1.0 1.0,0.0 1.1875,0.0C20.148497,5.5674677 16.442669,2.5 12.0,2.5zm9.1875,7.1875c-14.125,9.541667 -7.0625,4.770833 0.0,0.0z
-        M10.6,5.4C10.4,5.2 10.1,5.2 10.0,5.4L7.6,9.1l2.0,0.0l0.0,3.8L11.0,12.900001L11.0,9.1l2.0,0.0L10.6,5.4z
-        M13.3,18.6c0.2,0.2 0.5,0.2 0.6,0.0l2.4,-3.7l-2.0,0.0l0.0,-3.8l-1.4,0.0l0.0,3.8l-2.0,0.0l2.4,3.7z
-        M21.7,24.0c-0.5,0.0 -0.8,-0.1 -1.1,-0.4c-0.3,-0.3 -0.4,-0.6 -0.4,-1.0c0.0,-0.4 0.1,-0.8 0.4,-1.0c0.3,-0.3 0.7,-0.4 1.1,-0.4s0.8,0.1 1.1,0.4c0.3,0.3 0.4,0.6 0.4,1.0c0.0,0.4 -0.1,0.7 -0.4,1.0
-        C22.6,23.8 22.2,24 21.7,24z
-        M20.4,19.7l0.0,-8.5L23.0,11.2l0.0,8.5L20.4,19.7z
-        "
-        android:fillType="evenOdd"
-        android:fillColor="#231F20"/>
+        android:pathData="M15.8,12.9l3.7,0.0c0.0,-0.3 0.0,-0.6 0.0,-0.9c0.0,-5.2 -4.3,-9.5 -9.5,-9.5S0.6,6.8 0.6,12.0s4.3,9.5 9.5,9.5c2.1,0.0 4.1,-0.7 5.7,-1.9L15.8,12.9zM5.7,9.1l2.4,-3.7c0.2,-0.2 0.5,-0.2 0.6,0.0l2.4,3.7l-2.0,0.0l0.0,3.8L7.8,12.900001L7.8,9.1L5.7,9.1zM11.4,18.6L9.0,14.9l2.0,0.0l0.0,-3.8l1.4,0.0l0.0,3.8l2.0,0.0L12.0,18.6C11.9,18.8 11.6,18.8 11.4,18.6z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M23.4,19.4l-2.1,-2.1 2.1,-2.199999 -1.1,-1.0 -2.099998,2.1 -2.1,-2.1 -1.1,1.099999 2.1,2.099999 -2.1,2.1 1.1,1.1 2.1,-2.200001 2.099998,2.200001z"
+        android:fillColor="#FFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/layout/volume_zen_footer.xml b/packages/SystemUI/res/layout/volume_zen_footer.xml
index 775b157..91dc617 100644
--- a/packages/SystemUI/res/layout/volume_zen_footer.xml
+++ b/packages/SystemUI/res/layout/volume_zen_footer.xml
@@ -29,6 +29,52 @@
         android:layout_marginTop="8dp"
         android:background="@color/qs_tile_divider" />
 
+
+    <RelativeLayout
+        android:id="@+id/zen_introduction"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginEnd="16dp"
+        android:paddingTop="8dp"
+        android:paddingBottom="8dp"
+        android:background="@drawable/zen_introduction_message_background"
+        android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent.Light">
+
+        <ImageView
+            android:id="@+id/zen_introduction_confirm"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:layout_marginEnd="8dp"
+            android:layout_alignParentEnd="true"
+            android:background="@drawable/btn_borderless_rect"
+            android:clickable="true"
+            android:contentDescription="@string/accessibility_desc_close"
+            android:scaleType="center"
+            android:src="@drawable/ic_close"
+            android:tint="@android:color/white" />
+
+        <TextView
+            android:id="@+id/zen_introduction_message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:layout_marginStart="24dp"
+            android:textDirection="locale"
+            android:lineSpacingMultiplier="1.20029"
+            android:layout_toStartOf="@id/zen_introduction_confirm"
+            android:text="@string/zen_alarms_introduction"
+            android:textAppearance="@style/TextAppearance.QS.Introduction" />
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="16dp"
+            android:layout_below="@id/zen_introduction_message"
+            android:layout_alignParentEnd="true" />
+
+    </RelativeLayout>
+
+
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d15fcae..64b5f4b 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -838,7 +838,10 @@
     <string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
 
     <!-- Zen mode: Priority only introduction message on first use -->
-    <string name="zen_priority_introduction">You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify.</string>
+    <string name="zen_priority_introduction">You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify. You'll still hear anything you choose to play including music, videos, and games.</string>
+
+    <!-- Zen mode: Alarms only introduction message on first use -->
+    <string name="zen_alarms_introduction">You won’t be disturbed by sounds and vibrations, except from alarms. You'll still hear anything you choose to play including music, videos, and games.</string>
 
     <!-- Zen mode: Priority only customization button label -->
     <string name="zen_priority_customize_button">Customize</string>
@@ -1211,7 +1214,7 @@
     <string name="zen_mode_and_condition"><xliff:g id="zen_mode" example="Priority interruptions only">%1$s</xliff:g>. <xliff:g id="exit_condition" example="For one hour">%2$s</xliff:g></string>
 
     <!-- Button label for ending zen mode in the volume dialog -->
-    <string name="volume_zen_end_now">End now</string>
+    <string name="volume_zen_end_now">Turn off now</string>
 
     <!-- Content description for accessibility (not shown on the screen): volume dialog expand button. [CHAR LIMIT=NONE] -->
     <string name="accessibility_volume_expand">Expand</string>
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 1e9cbdc..3cc81df 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -58,6 +58,7 @@
         String DND_TILE_COMBINED_ICON = "DndTileCombinedIcon";
         String DND_CONFIRMED_PRIORITY_INTRODUCTION = "DndConfirmedPriorityIntroduction";
         String DND_CONFIRMED_SILENCE_INTRODUCTION = "DndConfirmedSilenceIntroduction";
+        String DND_CONFIRMED_ALARM_INTRODUCTION = "DndConfirmedAlarmIntroduction";
         String DND_FAVORITE_BUCKET_INDEX = "DndCountdownMinuteIndex";
         String DND_NONE_SELECTED = "DndNoneSelected";
         String DND_FAVORITE_ZEN = "DndFavoriteZen";
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 07bd242..88e8b39 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1585,7 +1585,6 @@
             updateInputRestricted();
         }
 
-        mDismissCallbackRegistry.notifyDismissSucceeded();
         handleHide();
         Trace.endSection();
     }
@@ -1798,6 +1797,7 @@
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
+            mDismissCallbackRegistry.notifyDismissSucceeded();
             sendUserPresentBroadcast();
         }
         Trace.endSection();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 0c2c5bc..4feaf5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -62,6 +62,7 @@
     private int mAppUid;
     private List<NotificationChannel> mNotificationChannels;
     private NotificationChannel mSingleNotificationChannel;
+    private boolean mIsSingleDefaultChannel;
     private StatusBarNotification mSbn;
     private int mStartingUserImportance;
 
@@ -113,17 +114,23 @@
         mSbn = sbn;
         mPm = pm;
         mAppSettingsClickListener = onAppSettingsClick;
-        boolean isSingleDefaultChannel = false;
         mStartingUserImportance = startingUserImportance;
+        int numTotalChannels = 1;
+        numTotalChannels = iNotificationManager.getNumNotificationChannelsForPackage(
+                pkg, mAppUid, false /* includeDeleted */);
         if (mNotificationChannels.isEmpty()) {
             throw new IllegalArgumentException("bindNotification requires at least one channel");
         } else  {
             if (mNotificationChannels.size() == 1) {
                 mSingleNotificationChannel = mNotificationChannels.get(0);
-                isSingleDefaultChannel = mSingleNotificationChannel.getId()
-                        .equals(NotificationChannel.DEFAULT_CHANNEL_ID);
+                // Special behavior for the Default channel if no other channels have been defined.
+                mIsSingleDefaultChannel =
+                        (mSingleNotificationChannel.getId()
+                                .equals(NotificationChannel.DEFAULT_CHANNEL_ID) &&
+                        numTotalChannels <= 1);
             } else {
                 mSingleNotificationChannel = null;
+                mIsSingleDefaultChannel = false;
             }
         }
 
@@ -148,19 +155,16 @@
         }
         ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
 
-        int numChannels = 1;
-        numChannels = iNotificationManager.getNumNotificationChannelsForPackage(
-                pkg, mAppUid, false /* includeDeleted */);
-
         String channelsDescText;
         mNumChannelsView = findViewById(R.id.num_channels_desc);
-        if (isSingleDefaultChannel) {
+        if (mIsSingleDefaultChannel) {
             channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
         } else {
             switch (mNotificationChannels.size()) {
                 case 1:
                     channelsDescText = String.format(mContext.getResources().getQuantityString(
-                            R.plurals.notification_num_channels_desc, numChannels), numChannels);
+                            R.plurals.notification_num_channels_desc, numTotalChannels),
+                            numTotalChannels);
                     break;
                 case 2:
                     channelsDescText = mContext.getString(
@@ -185,7 +189,7 @@
             // Multiple channels don't use a channel name for the title.
             channelNameText = mContext.getString(R.string.notification_num_channels,
                     mNotificationChannels.size());
-        } else if (isSingleDefaultChannel) {
+        } else if (mIsSingleDefaultChannel) {
             // If this is the default channel, don't use our channel-specific text.
             channelNameText = mContext.getString(R.string.notification_header_default_channel);
         } else {
@@ -241,7 +245,7 @@
                     (View view) -> {
                         onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
                     });
-            if (numChannels > 1) {
+            if (numTotalChannels > 1) {
                 settingsButton.setText(R.string.notification_all_categories);
             } else {
                 settingsButton.setText(R.string.notification_more_settings);
@@ -327,14 +331,12 @@
     private void updateSecondaryText() {
         final boolean disabled = mSingleNotificationChannel != null &&
                 getSelectedImportance() == IMPORTANCE_NONE;
-        final boolean isDefaultChannel = mSingleNotificationChannel != null &&
-                mSingleNotificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID);
         if (disabled) {
             mChannelDisabledView.setVisibility(View.VISIBLE);
             mNumChannelsView.setVisibility(View.GONE);
         } else {
             mChannelDisabledView.setVisibility(View.GONE);
-            mNumChannelsView.setVisibility(isDefaultChannel ? View.INVISIBLE : View.VISIBLE);
+            mNumChannelsView.setVisibility(mIsSingleDefaultChannel ? View.INVISIBLE : View.VISIBLE);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index fcb7289..efbf76b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -17,7 +17,10 @@
 
 import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -28,16 +31,23 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.os.AsyncTask;
+import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.security.KeyChain;
+import android.security.KeyChain.KeyChainConnection;
+import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.settings.CurrentUserTracker;
 
@@ -59,6 +69,8 @@
 
     private static final String VPN_BRANDED_META_DATA = "com.android.systemui.IS_BRANDED";
 
+    private static final int CA_CERT_LOADING_RETRY_TIME_IN_MS = 30_000;
+
     private final Context mContext;
     private final ConnectivityManager mConnectivityManager;
     private final IConnectivityManager mConnectivityManagerService;
@@ -73,6 +85,10 @@
     private int mCurrentUserId;
     private int mVpnUserId;
 
+    // Key: userId, Value: whether the user has CACerts installed
+    // Needs to be cached here since the query has to be asynchronous
+    private ArrayMap<Integer, Boolean> mHasCACerts = new ArrayMap<Integer, Boolean>();
+
     public SecurityControllerImpl(Context context) {
         super(context);
         mContext = context;
@@ -86,6 +102,11 @@
         mUserManager = (UserManager)
                 context.getSystemService(Context.USER_SERVICE);
 
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
+        context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null,
+                new Handler(Dependency.get(Dependency.BG_LOOPER)));
+
         // TODO: re-register network callback on user change.
         mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
         onUserSwitched(ActivityManager.getCurrentUser());
@@ -218,14 +239,16 @@
 
     @Override
     public boolean hasCACertInCurrentUser() {
-        //TODO: implement
-        return false;
+        Boolean hasCACerts = mHasCACerts.get(mCurrentUserId);
+        return hasCACerts != null && hasCACerts.booleanValue();
     }
 
     @Override
     public boolean hasCACertInWorkProfile() {
-        //TODO: implement
-        return false;
+        int userId = getWorkProfileUserId(mCurrentUserId);
+        if (userId == UserHandle.USER_NULL) return false;
+        Boolean hasCACerts = mHasCACerts.get(userId);
+        return hasCACerts != null && hasCACerts.booleanValue();
     }
 
     @Override
@@ -256,9 +279,16 @@
         } else {
             mVpnUserId = mCurrentUserId;
         }
+        refreshCACerts();
         fireCallbacks();
     }
 
+    private void refreshCACerts() {
+        new CACertLoader().execute(mCurrentUserId);
+        int workProfileId = getWorkProfileUserId(mCurrentUserId);
+        if (workProfileId != UserHandle.USER_NULL) new CACertLoader().execute(workProfileId);
+    }
+
     private String getNameForVpnConfig(VpnConfig cfg, UserHandle user) {
         if (cfg.legacy) {
             return mContext.getString(R.string.legacy_vpn_name);
@@ -348,4 +378,39 @@
             fireCallbacks();
         };
     };
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override public void onReceive(Context context, Intent intent) {
+            if (KeyChain.ACTION_TRUST_STORE_CHANGED.equals(intent.getAction())) {
+                refreshCACerts();
+            }
+        }
+    };
+
+    protected class CACertLoader extends AsyncTask<Integer, Void, Pair<Integer, Boolean> > {
+
+        @Override
+        protected Pair<Integer, Boolean> doInBackground(Integer... userId) {
+            try (KeyChainConnection conn = KeyChain.bindAsUser(mContext,
+                                                               UserHandle.of(userId[0]))) {
+                boolean hasCACerts = !(conn.getService().getUserCaAliases().getList().isEmpty());
+                return new Pair<Integer, Boolean>(userId[0], hasCACerts);
+            } catch (RemoteException | InterruptedException | AssertionError e) {
+                Log.i(TAG, e.getMessage());
+                new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed(
+                        () -> new CACertLoader().execute(userId[0]),
+                        CA_CERT_LOADING_RETRY_TIME_IN_MS);
+                return new Pair<Integer, Boolean>(userId[0], null);
+            }
+        }
+
+        @Override
+        protected void onPostExecute(Pair<Integer, Boolean> result) {
+            if (DEBUG) Log.d(TAG, "onPostExecute " + result);
+            if (result.second != null) {
+                mHasCACerts.put(result.first, result.second);
+                fireCallbacks();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index e7bce708..df2be48 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -19,9 +19,11 @@
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.content.DialogInterface;
+import android.os.Build;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -43,6 +45,11 @@
     public static final String SETTING_SEEN_TUNER_WARNING = "seen_tuner_warning";
 
     private static final String WARNING_TAG = "tuner_warning";
+    private static final String[] DEBUG_ONLY = new String[] {
+            "nav_bar",
+            "lockscreen",
+            "picture_in_picture",
+    };
 
     private static final int MENU_REMOVE = Menu.FIRST + 1;
 
@@ -68,6 +75,12 @@
         if (!alwaysOnAvailable()) {
             getPreferenceScreen().removePreference(findPreference(KEY_DOZE));
         }
+        if (!Build.IS_DEBUGGABLE) {
+            for (int i = 0; i < DEBUG_ONLY.length; i++) {
+                Preference preference = findPreference(DEBUG_ONLY[i]);
+                if (preference != null) getPreferenceScreen().removePreference(preference);
+            }
+        }
 
         if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING,
                 0) == 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index b8b046b..8d8931f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -642,7 +642,6 @@
                 updateVolumeRowSliderTintH(row, isActive);
             }
         }
-
     }
 
     private void trimObsoleteH() {
@@ -695,28 +694,25 @@
         final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF
                 && (mAudioManager.isStreamAffectedByRingerMode(mActiveStream) || mExpanded)
                 && !mZenPanel.isEditing();
-        TransitionManager.beginDelayedTransition(mDialogView, getTransistion());
-        if (wasVisible != visible && !visible) {
-            prepareForCollapse();
+
+        if (wasVisible != visible) {
+            mZenFooter.update();
+            Util.setVisOrGone(mZenFooter, visible);
         }
-        Util.setVisOrGone(mZenFooter, visible);
-        mZenFooter.update();
 
         final boolean fullWasVisible = mZenPanel.getVisibility() == View.VISIBLE;
         final boolean fullVisible = mShowFullZen && !visible;
-        if (fullWasVisible != fullVisible && !fullVisible) {
-            prepareForCollapse();
-        }
-        Util.setVisOrGone(mZenPanel, fullVisible);
-        if (fullVisible) {
-            mZenPanel.setZenState(mState.zenMode);
-            mZenPanel.setDoneListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    prepareForCollapse();
-                    mHandler.sendEmptyMessage(H.UPDATE_FOOTER);
-                }
-            });
+        if (fullWasVisible != fullVisible) {
+            Util.setVisOrGone(mZenPanel, fullVisible);
+            if (fullVisible) {
+                mZenPanel.setZenState(mState.zenMode);
+                mZenPanel.setDoneListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        mHandler.sendEmptyMessage(H.UPDATE_FOOTER);
+                    }
+                });
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 10b6ff5..17d98b1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -20,12 +20,16 @@
 import android.content.Context;
 import android.provider.Settings.Global;
 import android.service.notification.ZenModeConfig;
+import android.transition.AutoTransition;
+import android.transition.TransitionManager;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
@@ -44,6 +48,9 @@
     private TextView mSummaryLine1;
     private TextView mSummaryLine2;
     private TextView mEndNowButton;
+    private View mZenIntroduction;
+    private View mZenIntroductionConfirm;
+    private TextView mZenIntroductionMessage;
     private int mZen = -1;
     private ZenModeConfig mConfig;
     private ZenModeController mController;
@@ -64,6 +71,17 @@
         mSummaryLine1 = findViewById(R.id.volume_zen_summary_line_1);
         mSummaryLine2 = findViewById(R.id.volume_zen_summary_line_2);
         mEndNowButton = findViewById(R.id.volume_zen_end_now);
+        mZenIntroduction = findViewById(R.id.zen_introduction);
+        mZenIntroductionMessage = findViewById(R.id.zen_introduction_message);
+        mConfigurableTexts.add(mZenIntroductionMessage, R.string.zen_alarms_introduction);
+        mZenIntroductionConfirm = findViewById(R.id.zen_introduction_confirm);
+        mZenIntroductionConfirm.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                confirmZenIntroduction();
+            }
+        });
+        Util.setVisOrGone(mZenIntroduction, shouldShowIntroduction());
         mConfigurableTexts.add(mSummaryLine1);
         mConfigurableTexts.add(mSummaryLine2);
         mConfigurableTexts.add(mEndNowButton, R.string.volume_zen_end_now);
@@ -73,6 +91,7 @@
         mEndNowButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
+                setZen(Global.ZEN_MODE_OFF);
                 controller.setZen(Global.ZEN_MODE_OFF, null, TAG);
             }
         });
@@ -81,6 +100,7 @@
         mController = controller;
         mController.addCallback(mZenCallback);
         update();
+        updateIntroduction();
     }
 
     public void cleanup() {
@@ -91,6 +111,7 @@
         if (mZen == zen) return;
         mZen = zen;
         update();
+        updateIntroduction();
     }
 
     private void setConfig(ZenModeConfig config) {
@@ -99,8 +120,9 @@
         update();
     }
 
-    public boolean isZen() {
-        return isZenPriority() || isZenAlarms() || isZenNone();
+    private void confirmZenIntroduction() {
+        Prefs.putBoolean(mContext, Prefs.Key.DND_CONFIRMED_ALARM_INTRODUCTION, true);
+        updateIntroduction();
     }
 
     private boolean isZenPriority() {
@@ -128,6 +150,15 @@
                                 mController.getCurrentUser(), true /*shortVersion*/);
         Util.setText(mSummaryLine2, line2);
     }
+    public boolean shouldShowIntroduction() {
+        final boolean confirmed =  Prefs.getBoolean(mContext,
+                Prefs.Key.DND_CONFIRMED_ALARM_INTRODUCTION, false);
+        return !confirmed && isZenAlarms();
+    }
+
+    public void updateIntroduction() {
+        Util.setVisOrGone(mZenIntroduction, shouldShowIntroduction());
+    }
 
     public void onConfigurationChanged() {
         mConfigurableTexts.update();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index fffcc08..51fcdbb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -284,6 +284,8 @@
                 return Prefs.Key.DND_CONFIRMED_PRIORITY_INTRODUCTION;
             case Global.ZEN_MODE_NO_INTERRUPTIONS:
                 return Prefs.Key.DND_CONFIRMED_SILENCE_INTRODUCTION;
+            case Global.ZEN_MODE_ALARMS:
+                return Prefs.Key.DND_CONFIRMED_ALARM_INTRODUCTION;
             default:
                 return null;
         }
@@ -523,16 +525,22 @@
         final int zen = getSelectedZen(Global.ZEN_MODE_OFF);
         final boolean zenImportant = zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
+        final boolean zenAlarm = zen == Global.ZEN_MODE_ALARMS;
         final boolean introduction = (zenImportant && !mPrefs.mConfirmedPriorityIntroduction
-                        || zenNone && !mPrefs.mConfirmedSilenceIntroduction);
+                || zenNone && !mPrefs.mConfirmedSilenceIntroduction
+                || zenAlarm && !mPrefs.mConfirmedAlarmIntroduction);
 
         mZenButtons.setVisibility(mHidden ? GONE : VISIBLE);
         mZenIntroduction.setVisibility(introduction ? VISIBLE : GONE);
         if (introduction) {
-            mConfigurableTexts.add(mZenIntroductionMessage, zenImportant
+            int message = zenImportant
                     ? R.string.zen_priority_introduction
-                    : mVoiceCapable ? R.string.zen_silence_introduction_voice
-                    : R.string.zen_silence_introduction);
+                    : zenAlarm
+                            ? R.string.zen_alarms_introduction
+                            : mVoiceCapable
+                                    ? R.string.zen_silence_introduction_voice
+                                    : R.string.zen_silence_introduction;
+            mConfigurableTexts.add(mZenIntroductionMessage, message);
             mConfigurableTexts.update();
             mZenIntroductionCustomize.setVisibility(zenImportant ? VISIBLE : GONE);
         }
@@ -963,6 +971,7 @@
         private int mNoneSelected;
         private boolean mConfirmedPriorityIntroduction;
         private boolean mConfirmedSilenceIntroduction;
+        private boolean mConfirmedAlarmIntroduction;
 
         private ZenPrefs() {
             mNoneDangerousThreshold = mContext.getResources()
@@ -972,6 +981,7 @@
             updateNoneSelected();
             updateConfirmedPriorityIntroduction();
             updateConfirmedSilenceIntroduction();
+            updateConfirmedAlarmIntroduction();
         }
 
         public void trackNoneSelected() {
@@ -999,6 +1009,7 @@
             updateNoneSelected();
             updateConfirmedPriorityIntroduction();
             updateConfirmedSilenceIntroduction();
+            updateConfirmedAlarmIntroduction();
         }
 
         private void updateMinuteIndex() {
@@ -1038,6 +1049,15 @@
             if (DEBUG) Log.d(mTag, "Confirmed silence introduction: "
                     + mConfirmedSilenceIntroduction);
         }
+
+        private void updateConfirmedAlarmIntroduction() {
+            final boolean confirmed =  Prefs.getBoolean(mContext,
+                    Prefs.Key.DND_CONFIRMED_ALARM_INTRODUCTION, false);
+            if (confirmed == mConfirmedAlarmIntroduction) return;
+            mConfirmedAlarmIntroduction = confirmed;
+            if (DEBUG) Log.d(mTag, "Confirmed alarm introduction: "
+                    + mConfirmedAlarmIntroduction);
+        }
     }
 
     protected final SegmentedButtons.Callback mZenButtonsCallback = new SegmentedButtons.Callback() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 0531ec5..0118a80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -210,6 +210,30 @@
     }
 
     @Test
+    public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, null);
+        final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+        assertEquals(mContext.getString(R.string.notification_header_default_channel),
+                textView.getText());
+    }
+
+    @Test
+    public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists()
+            throws Exception {
+        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+                eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, null);
+        final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+        assertEquals(mDefaultNotificationChannel.getName(), textView.getText());
+    }
+
+    @Test
     public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -325,6 +349,21 @@
     }
 
     @Test
+    public void testBindNotification_NumChannelsTextDisplaysWhenMoreThanOneChannelExists()
+            throws Exception {
+        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+                eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null,
+                null, null, null);
+        final TextView numChannelsView =
+                (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+        assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
+        assertEquals(getNumChannelsDescString(2), numChannelsView.getText());
+    }
+
+    @Test
     public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
             throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index 87c4c66..ae0509a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -21,31 +21,76 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.doNothing;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.StringParceledListSlice;
 import android.net.ConnectivityManager;
+import android.security.IKeyChainService;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.systemui.statusbar.policy.SecurityController.SecurityControllerCallback;
 import com.android.systemui.SysuiTestCase;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+
+import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class SecurityControllerTest extends SysuiTestCase {
+public class SecurityControllerTest extends SysuiTestCase implements SecurityControllerCallback {
     private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
+    private final IKeyChainService.Stub mKeyChainService = mock(IKeyChainService.Stub.class);
     private SecurityControllerImpl mSecurityController;
+    private CountDownLatch mStateChangedLatch;
+
+    // implementing SecurityControllerCallback
+    @Override
+    public void onStateChanged() {
+        mStateChangedLatch.countDown();
+    }
 
     @Before
     public void setUp() throws Exception {
         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
         mContext.addMockSystemService(Context.CONNECTIVITY_SERVICE, mock(ConnectivityManager.class));
+
+        Intent intent = new Intent(IKeyChainService.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        mContext.addMockService(comp, mKeyChainService);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenReturn(new StringParceledListSlice(new ArrayList<String>()));
+        // Without this line, mKeyChainService gets wrapped in a proxy when Stub.asInterface() is
+        // used on it, and the mocking above does not work.
+        when(mKeyChainService.queryLocalInterface("android.security.IKeyChainService"))
+                .thenReturn(mKeyChainService);
+
         mSecurityController = new SecurityControllerImpl(mContext);
+
+        // Wait for one or two state changes from the CACertLoader(s) in the constructor of
+        // mSecurityController
+        mStateChangedLatch = new CountDownLatch(mSecurityController.hasWorkProfile() ? 2 : 1);
+        mSecurityController.addCallback(this);
+    }
+
+    @After
+    public void tearDown() {
+        mSecurityController.removeCallback(this);
     }
 
     @Test
@@ -62,4 +107,41 @@
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn("organization");
         assertEquals("organization", mSecurityController.getDeviceOwnerOrganizationName());
     }
+
+    @Test
+    @Ignore("Flaky")
+    public void testCaCertLoader() throws Exception {
+        assertTrue(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertFalse(mSecurityController.hasCACertInCurrentUser());
+
+        // With a CA cert
+
+        mStateChangedLatch = new CountDownLatch(1);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenReturn(new StringParceledListSlice(Arrays.asList("One CA Alias")));
+
+        mSecurityController.new CACertLoader()
+                           .execute(0);
+
+        assertTrue(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertTrue(mSecurityController.hasCACertInCurrentUser());
+
+        // Exception
+
+        mStateChangedLatch = new CountDownLatch(1);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenThrow(new AssertionError("Test AssertionError"))
+                .thenReturn(new StringParceledListSlice(new ArrayList<String>()));
+
+        mSecurityController.new CACertLoader()
+                           .execute(0);
+
+        assertFalse(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertTrue(mSecurityController.hasCACertInCurrentUser());
+        // The retry takes 30s
+        //assertTrue(mStateChangedLatch.await(31, TimeUnit.SECONDS));
+        //assertFalse(mSecurityController.hasCACertInCurrentUser());
+    }
 }
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 20a6d14..bff39b3 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -56,6 +56,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.ActivityThread;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -3562,7 +3563,6 @@
     private void showInputMethodMenu(boolean showAuxSubtypes) {
         if (DEBUG) Slog.v(TAG, "Show switching menu. showAuxSubtypes=" + showAuxSubtypes);
 
-        final Context context = mContext;
         final boolean isScreenLocked = isScreenLocked();
 
         final String lastInputMethodId = mSettings.getSelectedInputMethod();
@@ -3610,7 +3610,8 @@
                 }
             }
 
-            final Context settingsContext = new ContextThemeWrapper(context,
+            final Context settingsContext = new ContextThemeWrapper(
+                    ActivityThread.currentActivityThread().getSystemUiContext(),
                     com.android.internal.R.style.Theme_DeviceDefault_Settings);
 
             mDialogBuilder = new AlertDialog.Builder(settingsContext);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index a5cfbcf..5c57be2 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -131,6 +131,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
@@ -892,15 +893,7 @@
 
         Entry ent = AttributeCache.instance().get(packageName,
                 realTheme, com.android.internal.R.styleable.Window, userId);
-        final boolean translucent = ent != null && (ent.array.getBoolean(
-                com.android.internal.R.styleable.Window_windowIsTranslucent, false)
-                || (!ent.array.hasValue(
-                        com.android.internal.R.styleable.Window_windowIsTranslucent)
-                        && ent.array.getBoolean(
-                                com.android.internal.R.styleable.Window_windowSwipeToDismiss,
-                                        false)));
-        fullscreen = ent != null && !ent.array.getBoolean(
-                com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
+        fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
         noDisplay = ent != null && ent.array.getBoolean(
                 com.android.internal.R.styleable.Window_windowNoDisplay, false);
 
@@ -2186,6 +2179,11 @@
     }
 
     void setRequestedOrientation(int requestedOrientation) {
+        if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
+                && appInfo.targetSdkVersion >= O) {
+            throw new IllegalStateException("Only fullscreen activities can request orientation");
+        }
+
         final int displayId = getDisplayId();
         final Configuration displayConfig =
                 mStackSupervisor.getDisplayOverrideConfiguration(displayId);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index e33ae0d..6d4eb5b 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -637,7 +637,6 @@
         if (componentSpecified
                 && intent.getData() != null
                 && Intent.ACTION_VIEW.equals(intent.getAction())
-                && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
                 && mService.getPackageManagerInternalLocked()
                         .isInstantAppInstallerComponent(intent.getComponent())) {
             // intercept intents targeted directly to the ephemeral installer the
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 70766f9..7dcd6cd 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -96,6 +96,7 @@
 import android.media.AudioManager;
 import android.media.AudioManagerInternal;
 import android.media.IRingtonePlayer;
+import android.media.ToneGenerator;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -301,6 +302,10 @@
     private boolean mInCall = false;
     private boolean mNotificationPulseEnabled;
 
+    // for generating notification tones in-call
+    private ToneGenerator mInCallToneGenerator;
+    private final Object mInCallToneGeneratorLock = new Object();
+
     // used as a mutex for access to all active notifications & listeners
     final Object mNotificationLock = new Object();
     final ArrayList<NotificationRecord> mNotificationList =
@@ -854,6 +859,30 @@
                 mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
                         .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
                 updateNotificationPulse();
+                synchronized (mInCallToneGeneratorLock) {
+                    if (mInCall) {
+                        if (mInCallToneGenerator == null) {
+                            int relativeToneVolume = getContext().getResources().getInteger(
+                                    R.integer.config_inCallNotificationVolumeRelative);
+                            if (relativeToneVolume < ToneGenerator.MIN_VOLUME
+                                    || relativeToneVolume > ToneGenerator.MAX_VOLUME) {
+                                relativeToneVolume = ToneGenerator.MAX_VOLUME;
+                            }
+                            try {
+                                mInCallToneGenerator = new ToneGenerator(
+                                        AudioManager.STREAM_VOICE_CALL, relativeToneVolume);
+                            } catch (RuntimeException e) {
+                                Log.e(TAG, "Error creating local tone generator: " + e);
+                                mInCallToneGenerator = null;
+                            }
+                        }
+                    } else {
+                        if (mInCallToneGenerator != null) {
+                            mInCallToneGenerator.release();
+                            mInCallToneGenerator = null;
+                        }
+                     }
+                }
             } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (userHandle >= 0) {
@@ -3240,12 +3269,8 @@
         final boolean warningEnabled = Settings.System.getInt(getContext().getContentResolver(),
                 Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, 0) != 0;
         if (warningEnabled || Build.IS_DEBUGGABLE) {
-            try {
-                Toast toast = Toast.makeText(getContext(), toastText, Toast.LENGTH_LONG);
-                toast.show();
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Unable to toast with text: " + toastText, e);
-            }
+            Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText, Toast.LENGTH_LONG);
+            toast.show();
         }
     }
 
@@ -3723,14 +3748,21 @@
             hasValidVibrate = vibration != null;
 
             if (!shouldMuteNotificationLocked(record)) {
-
                 sendAccessibilityEvent(notification, record.sbn.getPackageName());
+
                 if (hasValidSound) {
                     mSoundNotificationKey = key;
-                    beep = playSound(record, soundUri);
+                    if (mInCall) {
+                        playInCallNotification();
+                        beep = true;
+                    } else {
+                        beep = playSound(record, soundUri);
+                    }
                 }
-                if (hasValidVibrate && !(mAudioManager.getRingerModeInternal()
-                        == AudioManager.RINGER_MODE_SILENT)) {
+
+                final boolean ringerModeSilent =
+                        mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT;
+                if (!mInCall && hasValidVibrate && !ringerModeSilent) {
                     mVibrateNotificationKey = key;
 
                     buzz = playVibration(record, vibration);
@@ -3839,6 +3871,26 @@
         }
     }
 
+    private void playInCallNotification() {
+        new Thread() {
+            @Override
+            public void run() {
+                // If toneGenerator creation fails, just continue the call
+                // without playing the notification sound.
+                try {
+                    synchronized (mInCallToneGeneratorLock) {
+                        if (mInCallToneGenerator != null) {
+                            // limit this tone to 1 second; BEEP2 should in fact be much shorter
+                            mInCallToneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP2, 1000);
+                        }
+                    }
+                } catch (RuntimeException e) {
+                    Log.w(TAG, "Exception from ToneGenerator: " + e);
+                }
+            }
+        }.start();
+    }
+
     void showNextToastLocked() {
         ToastRecord record = mToastQueue.get(0);
         while (record != null) {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 2e4b49a..271045a 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -316,6 +316,7 @@
 
                 if (arg == null) {
                     builder.append('!');
+                    return;
                 }
 
                 String txt = String.valueOf(arg);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0173533..f1e4e12 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1741,13 +1741,14 @@
 
                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
 
-                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
+                        final UserHandle user = args.getUser();
+                        if (getDefaultVerificationResponse(user)
+                                == PackageManager.VERIFICATION_ALLOW) {
                             Slog.i(TAG, "Continuing with installation of " + originUri);
                             state.setVerifierResponse(Binder.getCallingUid(),
                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
                             broadcastPackageVerified(verificationId, originUri,
-                                    PackageManager.VERIFICATION_ALLOW,
-                                    state.getInstallArgs().getUser());
+                                    PackageManager.VERIFICATION_ALLOW, user);
                             try {
                                 ret = args.copyApk(mContainerService, true);
                             } catch (RemoteException e) {
@@ -1755,8 +1756,7 @@
                             }
                         } else {
                             broadcastPackageVerified(verificationId, originUri,
-                                    PackageManager.VERIFICATION_REJECT,
-                                    state.getInstallArgs().getUser());
+                                    PackageManager.VERIFICATION_REJECT, user);
                         }
 
                         Trace.asyncTraceEnd(
@@ -4218,7 +4218,6 @@
             final boolean allowMatchInstant =
                     (includeInstantApps
                             && Intent.ACTION_VIEW.equals(intent.getAction())
-                            && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
                             && hasWebURI(intent))
                     || isSpecialProcess
                     || mContext.checkCallingOrSelfPermission(
@@ -14208,7 +14207,10 @@
      *
      * @return default verification response code
      */
-    private int getDefaultVerificationResponse() {
+    private int getDefaultVerificationResponse(UserHandle user) {
+        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
+            return PackageManager.VERIFICATION_REJECT;
+        }
         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
                 DEFAULT_VERIFICATION_RESPONSE);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 640bac2..982561c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -53,6 +53,7 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.SystemClock;
@@ -70,6 +71,8 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 
+import static android.os.Build.VERSION_CODES.O;
+
 class AppTokenList extends ArrayList<AppWindowToken> {
 }
 
@@ -1245,7 +1248,11 @@
      */
     @Override
     int getOrientation(int candidate) {
-        if (!fillsParent()) {
+        // We do not allow non-fullscreen apps to influence orientation at and beyond O. While we do
+        // throw an exception in {@link Activity#onCreate} and
+        // {@link Activity#setRequestedOrientation}, we also ignore the orientation here so that
+        // other calculations aren't affected.
+        if (!fillsParent() && mTargetSdk >= O) {
             // Can't specify orientation if app doesn't fill parent.
             return SCREEN_ORIENTATION_UNSET;
         }
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 876008b..46f10c1 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -173,8 +173,8 @@
         token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         token.setFillsParent(false);
-        // Can not specify orientation if app doesn't fill parent.
-        assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
+        // Can specify orientation if app doesn't fill parent. Allowed for SDK <= 25.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
 
         token.setFillsParent(true);
         token.hidden = true;