Merge "Media Complication Introduction."
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e34d133..d6e4815 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -5873,6 +5873,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterMuteAwaitConnectionCallback(@NonNull android.media.AudioManager.MuteAwaitConnectionCallback);
     method public void unregisterVolumeGroupCallback(@NonNull android.media.AudioManager.VolumeGroupCallback);
+    field public static final String ACTION_VOLUME_CHANGED = "android.media.VOLUME_CHANGED_ACTION";
     field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
     field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
     field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
@@ -5881,7 +5882,10 @@
     field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
     field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
     field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
+    field public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
+    field public static final String EXTRA_VOLUME_STREAM_VALUE = "android.media.EXTRA_VOLUME_STREAM_VALUE";
     field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int STREAM_ASSISTANT = 11; // 0xb
+    field public static final int STREAM_BLUETOOTH_SCO = 6; // 0x6
     field public static final int SUCCESS = 0; // 0x0
   }
 
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 7b55b6c..b1956ef 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -16,6 +16,11 @@
 
 package android.app;
 
+import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED;
+import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_NOT_COLORED;
+import static android.app.admin.DevicePolicyResources.Drawables.UNDEFINED;
+import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON;
+import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON_BADGE;
 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256;
 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512;
 import static android.content.pm.Checksum.TYPE_WHOLE_MD5;
@@ -31,6 +36,7 @@
 import android.annotation.StringRes;
 import android.annotation.UserIdInt;
 import android.annotation.XmlRes;
+import android.app.admin.DevicePolicyManager;
 import android.app.role.RoleManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
@@ -62,7 +68,6 @@
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
@@ -74,7 +79,6 @@
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VersionedPackage;
 import android.content.pm.dex.ArtManager;
-import android.content.pm.pkg.FrameworkPackageUserState;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
@@ -122,7 +126,6 @@
 
 import libcore.util.EmptyArray;
 
-import java.io.File;
 import java.lang.ref.WeakReference;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
@@ -172,6 +175,8 @@
     private PackageInstaller mInstaller;
     @GuardedBy("mLock")
     private ArtManager mArtManager;
+    @GuardedBy("mLock")
+    private DevicePolicyManager mDevicePolicyManager;
 
     @GuardedBy("mDelegates")
     private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
@@ -188,6 +193,15 @@
         }
     }
 
+    DevicePolicyManager getDevicePolicyManager() {
+        synchronized (mLock) {
+            if (mDevicePolicyManager == null) {
+                mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+            }
+            return mDevicePolicyManager;
+        }
+    }
+
     private PermissionManager getPermissionManager() {
         synchronized (mLock) {
             if (mPermissionManager == null) {
@@ -1876,12 +1890,27 @@
         if (!hasUserBadge(user.getIdentifier())) {
             return icon;
         }
+
+        final Drawable badgeForeground = getDevicePolicyManager().getDrawable(
+                getUpdatableUserIconBadgeId(user),
+                SOLID_COLORED,
+                () -> getDefaultUserIconBadge(user));
+
         Drawable badge = new LauncherIcons(mContext).getBadgeDrawable(
-                getUserManager().getUserIconBadgeResId(user.getIdentifier()),
+                badgeForeground,
                 getUserBadgeColor(user, false));
         return getBadgedDrawable(icon, badge, null, true);
     }
 
+    private String getUpdatableUserIconBadgeId(UserHandle user) {
+        return getUserManager().isManagedProfile(user.getIdentifier())
+                ? WORK_PROFILE_ICON_BADGE : UNDEFINED;
+    }
+
+    private Drawable getDefaultUserIconBadge(UserHandle user) {
+        return mContext.getDrawable(getUserManager().getUserIconBadgeResId(user.getIdentifier()));
+    }
+
     @Override
     public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
             Rect badgeLocation, int badgeDensity) {
@@ -1913,13 +1942,28 @@
         if (badgeColor == null) {
             return null;
         }
-        Drawable badgeForeground = getDrawableForDensity(
-                getUserManager().getUserBadgeResId(user.getIdentifier()), density);
+
+        final Drawable badgeForeground = getDevicePolicyManager().getDrawableForDensity(
+                getUpdatableUserBadgeId(user),
+                SOLID_COLORED,
+                density,
+                () -> getDefaultUserBadgeForDensity(user, density));
+
         badgeForeground.setTint(getUserBadgeColor(user, false));
         Drawable badge = new LayerDrawable(new Drawable[] {badgeColor, badgeForeground });
         return badge;
     }
 
+    private String getUpdatableUserBadgeId(UserHandle user) {
+        return getUserManager().isManagedProfile(user.getIdentifier())
+                ? WORK_PROFILE_ICON : UNDEFINED;
+    }
+
+    private Drawable getDefaultUserBadgeForDensity(UserHandle user, int density) {
+        return getDrawableForDensity(
+                getUserManager().getUserBadgeResId(user.getIdentifier()), density);
+    }
+
     /**
      * Returns the badge color based on whether device has dark theme enabled or not.
      */
@@ -1928,14 +1972,24 @@
         if (!hasUserBadge(user.getIdentifier())) {
             return null;
         }
-        Drawable badge = getDrawableForDensity(
-                getUserManager().getUserBadgeNoBackgroundResId(user.getIdentifier()), density);
+
+        final Drawable badge = getDevicePolicyManager().getDrawableForDensity(
+                getUpdatableUserBadgeId(user),
+                SOLID_NOT_COLORED,
+                density,
+                () -> getDefaultUserBadgeNoBackgroundForDensity(user, density));
+
         if (badge != null) {
             badge.setTint(getUserBadgeColor(user, true));
         }
         return badge;
     }
 
+    private Drawable getDefaultUserBadgeNoBackgroundForDensity(UserHandle user, int density) {
+        return getDrawableForDensity(
+                getUserManager().getUserBadgeNoBackgroundResId(user.getIdentifier()), density);
+    }
+
     private Drawable getDrawableForDensity(int drawableId, int density) {
         if (density <= 0) {
             density = mContext.getResources().getDisplayMetrics().densityDpi;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index d57c288..6a14772 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -17,6 +17,10 @@
 package android.app;
 
 import static android.annotation.Dimension.DP;
+import static android.app.admin.DevicePolicyResources.Drawables.Source.NOTIFICATION;
+import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED;
+import static android.app.admin.DevicePolicyResources.Drawables.UNDEFINED;
+import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON;
 import static android.graphics.drawable.Icon.TYPE_URI;
 import static android.graphics.drawable.Icon.TYPE_URI_ADAPTIVE_BITMAP;
 
@@ -39,6 +43,7 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.app.admin.DevicePolicyManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
@@ -71,6 +76,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.text.BidiFormatter;
 import android.text.SpannableStringBuilder;
@@ -5046,6 +5052,18 @@
             }
             // Note: This assumes that the current user can read the profile badge of the
             // originating user.
+            DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+            return dpm.getDrawable(
+                    getUpdatableProfileBadgeId(), SOLID_COLORED, NOTIFICATION,
+                    this::getDefaultProfileBadgeDrawable);
+        }
+
+        private String getUpdatableProfileBadgeId() {
+            return mContext.getSystemService(UserManager.class).isManagedProfile()
+                    ? WORK_PROFILE_ICON : UNDEFINED;
+        }
+
+        private Drawable getDefaultProfileBadgeDrawable() {
             return mContext.getPackageManager().getUserBadgeForDensityNoBackground(
                     new UserHandle(mContext.getUserId()), 0);
         }
diff --git a/core/java/android/util/IconDrawableFactory.java b/core/java/android/util/IconDrawableFactory.java
index b5e8dd7..5bb263a 100644
--- a/core/java/android/util/IconDrawableFactory.java
+++ b/core/java/android/util/IconDrawableFactory.java
@@ -15,7 +15,12 @@
  */
 package android.util;
 
+import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED;
+import static android.app.admin.DevicePolicyResources.Drawables.UNDEFINED;
+import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON_BADGE;
+
 import android.annotation.UserIdInt;
+import android.app.admin.DevicePolicyManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -37,6 +42,7 @@
     protected final Context mContext;
     protected final PackageManager mPm;
     protected final UserManager mUm;
+    protected final DevicePolicyManager mDpm;
     protected final LauncherIcons mLauncherIcons;
     protected final boolean mEmbedShadow;
 
@@ -44,6 +50,7 @@
         mContext = context;
         mPm = context.getPackageManager();
         mUm = context.getSystemService(UserManager.class);
+        mDpm = context.getSystemService(DevicePolicyManager.class);
         mLauncherIcons = new LauncherIcons(context);
         mEmbedShadow = embedShadow;
     }
@@ -73,18 +80,32 @@
         if (appInfo.isInstantApp()) {
             int badgeColor = Resources.getSystem().getColor(
                     com.android.internal.R.color.instant_app_badge, null);
+            Drawable badge = mContext.getDrawable(
+                    com.android.internal.R.drawable.ic_instant_icon_badge_bolt);
             icon = mLauncherIcons.getBadgedDrawable(icon,
-                    com.android.internal.R.drawable.ic_instant_icon_badge_bolt,
+                    badge,
                     badgeColor);
         }
         if (mUm.hasBadge(userId)) {
-            icon = mLauncherIcons.getBadgedDrawable(icon,
-                    mUm.getUserIconBadgeResId(userId),
-                    mUm.getUserBadgeColor(userId));
+
+            Drawable badge = mDpm.getDrawable(
+                    getUpdatableUserIconBadgeId(userId),
+                    SOLID_COLORED,
+                    () -> getDefaultUserIconBadge(userId));
+
+            icon = mLauncherIcons.getBadgedDrawable(icon, badge, mUm.getUserBadgeColor(userId));
         }
         return icon;
     }
 
+    private String getUpdatableUserIconBadgeId(int userId) {
+        return mUm.isManagedProfile(userId) ? WORK_PROFILE_ICON_BADGE : UNDEFINED;
+    }
+
+    private Drawable getDefaultUserIconBadge(int userId) {
+        return mContext.getResources().getDrawable(mUm.getUserIconBadgeResId(userId));
+    }
+
     /**
      * Add shadow to the icon if {@link AdaptiveIconDrawable}
      */
diff --git a/core/java/android/util/LauncherIcons.java b/core/java/android/util/LauncherIcons.java
index e652e17..355b2e9 100644
--- a/core/java/android/util/LauncherIcons.java
+++ b/core/java/android/util/LauncherIcons.java
@@ -45,10 +45,12 @@
     private final SparseArray<Bitmap> mShadowCache = new SparseArray<>();
     private final int mIconSize;
     private final Resources mRes;
+    private final Context mContext;
 
     public LauncherIcons(Context context) {
         mRes = context.getResources();
         mIconSize = mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
+        mContext = context;
     }
 
     public Drawable wrapIconDrawableWithShadow(Drawable drawable) {
@@ -98,14 +100,14 @@
         return shadow;
     }
 
-    public Drawable getBadgeDrawable(int foregroundRes, int backgroundColor) {
-        return getBadgedDrawable(null, foregroundRes, backgroundColor);
+    public Drawable getBadgeDrawable(Drawable badgeForeground, int backgroundColor) {
+        return getBadgedDrawable(null, badgeForeground, backgroundColor);
     }
 
-    public Drawable getBadgedDrawable(Drawable base, int foregroundRes, int backgroundColor) {
+    public Drawable getBadgedDrawable(
+            Drawable base, Drawable badgeForeground, int backgroundColor) {
         Resources overlayableRes =
                 ActivityThread.currentActivityThread().getApplication().getResources();
-
         // ic_corp_icon_badge_shadow is not work-profile-specific.
         Drawable badgeShadow = overlayableRes.getDrawable(
                 com.android.internal.R.drawable.ic_corp_icon_badge_shadow);
@@ -115,7 +117,6 @@
                 com.android.internal.R.drawable.ic_corp_icon_badge_color)
                 .getConstantState().newDrawable().mutate();
 
-        Drawable badgeForeground = overlayableRes.getDrawable(foregroundRes);
         badgeForeground.setTint(backgroundColor);
 
         Drawable[] drawables = base == null
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index a2704f9..1b4c0bc 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -181,6 +181,22 @@
     public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
 
     /**
+     * @hide Broadcast intent when the volume for a particular stream type changes.
+     * Includes the stream, the new volume and previous volumes.
+     * Notes:
+     *  - for internal platform use only, do not make public,
+     *  - never used for "remote" volume changes
+     *
+     * @see #EXTRA_VOLUME_STREAM_TYPE
+     * @see #EXTRA_VOLUME_STREAM_VALUE
+     * @see #EXTRA_PREV_VOLUME_STREAM_VALUE
+     */
+    @SystemApi
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @SuppressLint("ActionValue")
+    public static final String ACTION_VOLUME_CHANGED = "android.media.VOLUME_CHANGED_ACTION";
+
+    /**
      * @hide Broadcast intent when the devices for a particular stream type changes.
      * Includes the stream, the new devices and previous devices.
      * Notes:
@@ -244,7 +260,8 @@
     /**
      * @hide The stream type for the volume changed intent.
      */
-    @UnsupportedAppUsage
+    @SystemApi
+    @SuppressLint("ActionValue")
     public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
 
     /**
@@ -261,7 +278,8 @@
     /**
      * @hide The volume associated with the stream for the volume changed intent.
      */
-    @UnsupportedAppUsage
+    @SystemApi
+    @SuppressLint("ActionValue")
     public static final String EXTRA_VOLUME_STREAM_VALUE =
         "android.media.EXTRA_VOLUME_STREAM_VALUE";
 
@@ -368,7 +386,7 @@
     public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;
     /** @hide Used to identify the volume of audio streams for phone calls when connected
      *        to bluetooth */
-    @UnsupportedAppUsage
+    @SystemApi
     public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO;
     /** @hide Used to identify the volume of audio streams for enforced system sounds
      *        in certain countries (e.g camera in Japan) */