Merge "Keystore 2.0: Fix diagnosing invalid key in CipherSpiBase." into sc-dev
diff --git a/core/api/current.txt b/core/api/current.txt
index e1cb5e4..8bc603d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -52315,7 +52315,7 @@
     method @NonNull public java.util.List<android.view.textservice.SpellCheckerInfo> getEnabledSpellCheckerInfos();
     method public boolean isSpellCheckerEnabled();
     method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@Nullable android.os.Bundle, @Nullable java.util.Locale, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
-    method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@Nullable android.os.Bundle, @Nullable java.util.Locale, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean, int);
+    method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@Nullable java.util.Locale, boolean, int, @Nullable android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener);
   }
 
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 579f912..d4d3321 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6169,13 +6169,22 @@
 
     // STOPSHIP(b/174298501): clarify the expected return value following generateKeyPair call.
     /**
-     * Called by a device or profile owner, or delegated certificate installer, to query whether a
-     * certificate and private key are installed under a given alias.
+     * This API can be called by the following to query whether a certificate and private key are
+     * installed under a given alias:
+     * <ul>
+     *    <li>Device owner</li>
+     *    <li>Profile owner</li>
+     *    <li>Delegated certificate installer</li>
+     *    <li>Credential management app</li>
+     * </ul>
+     *
+     * If called by the credential management app, the alias must exist in the credential
+     * management app's {@link android.security.AppUriAuthenticationPolicy}.
      *
      * @param alias The alias under which the key pair is installed.
      * @return {@code true} if a key pair with this alias exists, {@code false} otherwise.
-     * @throws SecurityException if the caller is not a device or profile owner or a delegated
-     *         certificate installer.
+     * @throws SecurityException if the caller is not a device or profile owner, a delegated
+     *         certificate installer or the credential management app.
      * @see #setDelegatedScopes
      * @see #DELEGATION_CERT_INSTALL
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f0b22a9..13f3979 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -15835,6 +15835,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String BLOCK_UNTRUSTED_TOUCHES_MODE = "block_untrusted_touches";
 
         /**
@@ -15860,6 +15861,7 @@
          *
          * @hide
          */
+        @Readable
         public static final String MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH =
                 "maximum_obscuring_opacity_for_touch";
 
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index ba58b65..a449cf1 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -16,6 +16,8 @@
 
 package android.view.textservice;
 
+import android.annotation.BinderThread;
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Binder;
 import android.os.Build;
@@ -27,6 +29,7 @@
 import android.util.Log;
 import android.view.inputmethod.InputMethodManager;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.textservice.ISpellCheckerSession;
 import com.android.internal.textservice.ISpellCheckerSessionListener;
 import com.android.internal.textservice.ITextServicesSessionListener;
@@ -35,6 +38,7 @@
 
 import java.util.LinkedList;
 import java.util.Queue;
+import java.util.concurrent.Executor;
 
 /**
  * The SpellCheckerSession interface provides the per client functionality of SpellCheckerService.
@@ -102,38 +106,26 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private final SpellCheckerSessionListener mSpellCheckerSessionListener;
     private final SpellCheckerSessionListenerImpl mSpellCheckerSessionListenerImpl;
+    private final Executor mExecutor;
 
     private final CloseGuard mGuard = CloseGuard.get();
 
-    /** Handler that will execute the main tasks */
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_ON_GET_SUGGESTION_MULTIPLE:
-                    handleOnGetSuggestionsMultiple((SuggestionsInfo[]) msg.obj);
-                    break;
-                case MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE:
-                    handleOnGetSentenceSuggestionsMultiple((SentenceSuggestionsInfo[]) msg.obj);
-                    break;
-            }
-        }
-    };
-
     /**
      * Constructor
      * @hide
      */
     public SpellCheckerSession(
-            SpellCheckerInfo info, TextServicesManager tsm, SpellCheckerSessionListener listener) {
+            SpellCheckerInfo info, TextServicesManager tsm, SpellCheckerSessionListener listener,
+            Executor executor) {
         if (info == null || listener == null || tsm == null) {
             throw new NullPointerException();
         }
         mSpellCheckerInfo = info;
-        mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(mHandler);
+        mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(this);
         mInternalListener = new InternalListener(mSpellCheckerSessionListenerImpl);
         mTextServicesManager = tsm;
         mSpellCheckerSessionListener = listener;
+        mExecutor = executor;
 
         mGuard.open("finishSession");
     }
@@ -219,12 +211,13 @@
                 textInfos, suggestionsLimit, sequentialWords);
     }
 
-    private void handleOnGetSuggestionsMultiple(SuggestionsInfo[] suggestionInfos) {
-        mSpellCheckerSessionListener.onGetSuggestions(suggestionInfos);
+    void handleOnGetSuggestionsMultiple(SuggestionsInfo[] suggestionsInfos) {
+        mExecutor.execute(() -> mSpellCheckerSessionListener.onGetSuggestions(suggestionsInfos));
     }
 
-    private void handleOnGetSentenceSuggestionsMultiple(SentenceSuggestionsInfo[] suggestionInfos) {
-        mSpellCheckerSessionListener.onGetSentenceSuggestions(suggestionInfos);
+    void handleOnGetSentenceSuggestionsMultiple(SentenceSuggestionsInfo[] suggestionsInfos) {
+        mExecutor.execute(() ->
+                mSpellCheckerSessionListener.onGetSentenceSuggestions(suggestionsInfos));
     }
 
     private static final class SpellCheckerSessionListenerImpl
@@ -249,7 +242,8 @@
         }
 
         private final Queue<SpellCheckerParams> mPendingTasks = new LinkedList<>();
-        private Handler mHandler;
+        @GuardedBy("SpellCheckerSessionListenerImpl.this")
+        private SpellCheckerSession mSpellCheckerSession;
 
         private static final int STATE_WAIT_CONNECTION = 0;
         private static final int STATE_CONNECTED = 1;
@@ -270,8 +264,8 @@
         private HandlerThread mThread;
         private Handler mAsyncHandler;
 
-        public SpellCheckerSessionListenerImpl(Handler handler) {
-            mHandler = handler;
+        SpellCheckerSessionListenerImpl(SpellCheckerSession spellCheckerSession) {
+            mSpellCheckerSession = spellCheckerSession;
         }
 
         private static class SpellCheckerParams {
@@ -349,6 +343,7 @@
             }
         }
 
+        @GuardedBy("SpellCheckerSessionListenerImpl.this")
         private void processCloseLocked() {
             if (DBG) Log.d(TAG, "entering processCloseLocked:"
                     + " session" + (mISpellCheckerSession != null ? ".hashCode()=#"
@@ -358,7 +353,7 @@
             if (mThread != null) {
                 mThread.quit();
             }
-            mHandler = null;
+            mSpellCheckerSession = null;
             mPendingTasks.clear();
             mThread = null;
             mAsyncHandler = null;
@@ -502,23 +497,30 @@
             processTask(session, scp, false);
         }
 
+        @BinderThread
         @Override
         public void onGetSuggestions(SuggestionsInfo[] results) {
-            synchronized (this) {
-                if (mHandler != null) {
-                    mHandler.sendMessage(Message.obtain(mHandler,
-                            MSG_ON_GET_SUGGESTION_MULTIPLE, results));
-                }
+            SpellCheckerSession session = getSpellCheckerSession();
+            if (session != null) {
+                // Lock should not be held when calling callback, in order to avoid deadlock.
+                session.handleOnGetSuggestionsMultiple(results);
             }
         }
 
+        @BinderThread
         @Override
         public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
-            synchronized (this) {
-                if (mHandler != null) {
-                    mHandler.sendMessage(Message.obtain(mHandler,
-                            MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE, results));
-                }
+            SpellCheckerSession session = getSpellCheckerSession();
+            if (session != null) {
+                // Lock should not be held when calling callback, in order to avoid deadlock.
+                session.handleOnGetSentenceSuggestionsMultiple(results);
+            }
+        }
+
+        @Nullable
+        private SpellCheckerSession getSpellCheckerSession() {
+            synchronized (SpellCheckerSessionListenerImpl.this) {
+                return mSpellCheckerSession;
             }
         }
     }
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index 4f6fa27..bf91cca 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -16,6 +16,7 @@
 
 package android.view.textservice;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
@@ -25,6 +26,8 @@
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
@@ -40,6 +43,8 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
+import java.util.concurrent.Executor;
 
 /**
  * System API to the overall text services, which arbitrates interaction between applications
@@ -161,10 +166,12 @@
      * {@link SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS} will be passed to the spell
      * checker as supported attributes.
      *
-     * @see #newSpellCheckerSession(Bundle, Locale, SpellCheckerSessionListener, boolean, int)
+     * @see #newSpellCheckerSession(Locale, boolean, int, Bundle, Executor,
+     *      SpellCheckerSessionListener)
      * @param bundle A bundle to pass to the spell checker.
      * @param locale The locale for the spell checker.
      * @param listener A spell checker session lister for getting results from the spell checker.
+     *                 The listener will be called on the calling thread.
      * @param referToSpellCheckerLanguageSettings If true, the session for one of enabled
      *                                            languages in settings will be used.
      * @return A spell checker session from the spell checker.
@@ -174,10 +181,15 @@
             @Nullable Locale locale,
             @NonNull SpellCheckerSessionListener listener,
             boolean referToSpellCheckerLanguageSettings) {
-        return newSpellCheckerSession(bundle, locale, listener, referToSpellCheckerLanguageSettings,
-                SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
-                        | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
-                        | SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS);
+        // Attributes existed before {@link #newSpellCheckerSession(Locale, boolean, int, Bundle,
+        // Executor, SpellCheckerSessionListener)} was introduced.
+        int supportedAttributes = SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
+                | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
+                | SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS;
+        // Using the implicit looper to preserve the old behavior.
+        Executor executor = new HandlerExecutor(new Handler());
+        return newSpellCheckerSession(locale, referToSpellCheckerLanguageSettings,
+                supportedAttributes, bundle, executor, listener);
     }
 
     /**
@@ -191,25 +203,28 @@
      * language only (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be
      * selected.
      *
-     * @param bundle A bundle to pass to the spell checker.
      * @param locale The locale for the spell checker.
-     * @param listener A spell checker session lister for getting results from a spell checker.
      * @param referToSpellCheckerLanguageSettings If true, the session for one of enabled
      *                                            languages in settings will be used.
      * @param supportedAttributes A union of {@link SuggestionsInfo} attributes that the spell
      *                            checker can set in the spell checking results.
+     * @param bundle A bundle for passing implementation-specific extra parameters for the spell
+     *               checker. You can check the current spell checker package by
+     *               {@link #getCurrentSpellCheckerInfo()}.
+     * @param executor An executor to call the listener on.
+     * @param listener A spell checker session lister for getting results from a spell checker.
      * @return The spell checker session of the spell checker.
      */
     @Nullable
     public SpellCheckerSession newSpellCheckerSession(
-            @SuppressLint("NullableCollection") @Nullable Bundle bundle,
             @SuppressLint("UseIcu") @Nullable Locale locale,
-            @NonNull SpellCheckerSessionListener listener,
-            @SuppressLint("ListenerLast") boolean referToSpellCheckerLanguageSettings,
-            @SuppressLint("ListenerLast") @SuggestionsInfo.ResultAttrs int supportedAttributes) {
-        if (listener == null) {
-            throw new NullPointerException();
-        }
+            boolean referToSpellCheckerLanguageSettings,
+            @SuggestionsInfo.ResultAttrs int supportedAttributes,
+            @Nullable Bundle bundle,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull SpellCheckerSessionListener listener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
         if (!referToSpellCheckerLanguageSettings && locale == null) {
             throw new IllegalArgumentException("Locale should not be null if you don't refer"
                     + " settings.");
@@ -259,7 +274,7 @@
         if (subtypeInUse == null) {
             return null;
         }
-        final SpellCheckerSession session = new SpellCheckerSession(sci, this, listener);
+        final SpellCheckerSession session = new SpellCheckerSession(sci, this, listener, executor);
         try {
             mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(),
                     session.getTextServicesSessionListener(),
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 2464b4a..a63305e 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -126,14 +126,14 @@
                 || mTextServicesManager.getCurrentSpellCheckerSubtype(true) == null) {
             mSpellCheckerSession = null;
         } else {
+            int supportedAttributes = SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
+                    | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
+                    | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR
+                    | SuggestionsInfo.RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS;
             mSpellCheckerSession = mTextServicesManager.newSpellCheckerSession(
+                    mCurrentLocale, false, supportedAttributes,
                     null /* Bundle not currently used by the textServicesManager */,
-                    mCurrentLocale, this,
-                    false /* means any available languages from current spell checker */,
-                    SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
-                            | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
-                            | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR
-                            | SuggestionsInfo.RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS);
+                    mTextView.getContext().getMainExecutor(), this);
         }
 
         // Restore SpellCheckSpans in pool
diff --git a/data/etc/car/com.android.car.messenger.xml b/data/etc/car/com.android.car.messenger.xml
index 16595c3..9e5f339 100644
--- a/data/etc/car/com.android.car.messenger.xml
+++ b/data/etc/car/com.android.car.messenger.xml
@@ -16,6 +16,7 @@
   -->
 <permissions>
     <privapp-permissions package="com.android.car.messenger">
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"/>
     </privapp-permissions>
 </permissions>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml
index 8efe053..73b02f4 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable_thick.xml
@@ -18,33 +18,20 @@
             android:paddingMode="stack" >
     <item android:id="@android:id/background"
         android:gravity="center_vertical|fill_horizontal">
-        <layer-list>
-            <item>
-                <shape
-                    android:tint="?android:attr/colorControlActivated"
-                    android:alpha="?android:attr/disabledAlpha">
-                    <size android:height="@dimen/rounded_slider_height" />
-                    <solid android:color="@color/white_disabled" />
-                    <corners android:radius="@dimen/rounded_slider_corner_radius" />
-                </shape>
-            </item>
-            <item
-                android:gravity="center_vertical|left"
-                android:height="@dimen/rounded_slider_icon_size"
-                android:width="@dimen/rounded_slider_icon_size"
-                android:left="@dimen/rounded_slider_icon_inset">
-                <com.android.systemui.util.AlphaTintDrawableWrapper
-                    android:drawable="@drawable/ic_brightness"
-                    android:tint="?android:attr/colorControlActivated" />
-            </item>
-        </layer-list>
+        <inset
+            android:insetLeft="@dimen/rounded_slider_track_inset"
+            android:insetRight="@dimen/rounded_slider_track_inset" >
+            <shape>
+                <size android:height="@dimen/rounded_slider_track_width" />
+                <corners android:radius="@dimen/rounded_slider_track_corner_radius" />
+                <solid android:color="?android:attr/textColorPrimary" />
+            </shape>
+        </inset>
     </item>
     <item android:id="@android:id/progress"
           android:gravity="center_vertical|fill_horizontal">
-            <clip
+            <com.android.systemui.util.RoundedCornerProgressDrawable
                 android:drawable="@drawable/brightness_progress_full_drawable"
-                android:clipOrientation="horizontal"
-                android:gravity="left"
             />
     </item>
 </layer-list>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
index 5bc2773..41140a7 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_full_drawable.xml
@@ -26,10 +26,10 @@
     </item>
     <item
         android:id="@+id/slider_icon"
-        android:gravity="center_vertical|left"
+        android:gravity="center_vertical|right"
         android:height="@dimen/rounded_slider_icon_size"
         android:width="@dimen/rounded_slider_icon_size"
-        android:left="@dimen/rounded_slider_icon_inset">
+        android:right="@dimen/rounded_slider_icon_inset">
         <com.android.systemui.util.AlphaTintDrawableWrapper
             android:drawable="@drawable/ic_brightness"
             android:tint="?android:attr/colorBackground"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 2062104..6e270a7 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1356,11 +1356,15 @@
     <dimen name="people_space_image_radius">20dp</dimen>
     <dimen name="people_space_widget_background_padding">6dp</dimen>
 
-    <dimen name="rounded_slider_height">48dp</dimen>
+    <dimen name="rounded_slider_height">44dp</dimen>
     <!-- rounded_slider_height / 2 -->
-    <dimen name="rounded_slider_corner_radius">24dp</dimen>
-    <!-- rounded_slider_height / 2 -->
-    <dimen name="rounded_slider_icon_size">24dp</dimen>
-    <!-- rounded_slider_icon_size / 2 -->
+    <dimen name="rounded_slider_corner_radius">22dp</dimen>
+    <dimen name="rounded_slider_icon_size">20dp</dimen>
+    <!-- (rounded_slider_height - rounded_slider_icon_size) / 2 -->
     <dimen name="rounded_slider_icon_inset">12dp</dimen>
+    <!-- rounded_slider_corner_radius - rounded_slider_track_corner_radius -->
+    <dimen name="rounded_slider_track_inset">18dp</dimen>
+    <dimen name="rounded_slider_track_width">8dp</dimen>
+    <!-- rounded_slider_track_width / 2 -->
+    <dimen name="rounded_slider_track_corner_radius">4dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
index 6aadd10..dc86d58 100644
--- a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
@@ -17,8 +17,6 @@
 package com.android.systemui.util
 
 import android.content.res.Resources
-import android.graphics.Canvas
-import android.graphics.Path
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.DrawableWrapper
@@ -43,53 +41,25 @@
         private const val MAX_LEVEL = 10000 // Taken from Drawable
     }
 
-    private var clipPath: Path = Path()
-
-    init {
-        setClipPath(Rect())
-    }
-
     override fun onLayoutDirectionChanged(layoutDirection: Int): Boolean {
         onLevelChange(level)
         return super.onLayoutDirectionChanged(layoutDirection)
     }
 
     override fun onBoundsChange(bounds: Rect) {
-        setClipPath(bounds)
         super.onBoundsChange(bounds)
         onLevelChange(level)
     }
 
-    private fun setClipPath(bounds: Rect) {
-        clipPath.reset()
-        clipPath.addRoundRect(
-                bounds.left.toFloat(),
-                bounds.top.toFloat(),
-                bounds.right.toFloat(),
-                bounds.bottom.toFloat(),
-                bounds.height().toFloat() / 2,
-                bounds.height().toFloat() / 2,
-                Path.Direction.CW
-        )
-    }
-
     override fun onLevelChange(level: Int): Boolean {
         val db = drawable?.bounds!!
-        val width = bounds.width() * level / MAX_LEVEL
-        // Extra space on the left to keep the rounded shape on the right end
-        val leftBound = bounds.left - bounds.height()
-        drawable?.setBounds(leftBound, db.top, bounds.left + width, db.bottom)
+        // On 0, the width is bounds.height (a circle), and on MAX_LEVEL, the width is bounds.width
+        val width = bounds.height() + (bounds.width() - bounds.height()) * level / MAX_LEVEL
+        drawable?.setBounds(bounds.left, db.top, bounds.left + width, db.bottom)
         return super.onLevelChange(level)
     }
 
-    override fun draw(canvas: Canvas) {
-        canvas.save()
-        canvas.clipPath(clipPath)
-        super.draw(canvas)
-        canvas.restore()
-    }
-
-    override fun getConstantState(): ConstantState? {
+    override fun getConstantState(): ConstantState {
         // This should not be null as it was created with a state in the constructor.
         return RoundedCornerState(super.getConstantState()!!)
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 10b33b3..f2b4529 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5482,7 +5482,8 @@
     @Override
     public boolean hasKeyPair(String callerPackage, String alias) {
         final CallerIdentity caller = getCallerIdentity(callerPackage);
-        Preconditions.checkCallAuthorization(canManageCertificates(caller));
+        Preconditions.checkCallAuthorization(canManageCertificates(caller)
+                || isCredentialManagementApp(caller, alias));
 
         return mInjector.binderWithCleanCallingIdentity(() -> {
             try (KeyChainConnection keyChainConnection =