Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ba2f94b authored by Hawkwood Glazier's avatar Hawkwood Glazier
Browse files

Spinner drawable for casting intermediate state

Fixes: 224771457
Test: Manual & new automated
Change-Id: I08807e98977cc642621efd20b2200ce48cfdfd4c
parent dd0a8fb6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2303,6 +2303,7 @@
  <java-symbol type="drawable" name="scrubber_control_disabled_holo" />
  <java-symbol type="drawable" name="scrubber_control_selector_holo" />
  <java-symbol type="drawable" name="scrubber_progress_horizontal_holo_dark" />
  <java-symbol type="drawable" name="progress_small_material" />
  <java-symbol type="string" name="chooseUsbActivity" />
  <java-symbol type="string" name="ext_media_badremoval_notification_message" />
  <java-symbol type="string" name="ext_media_badremoval_notification_title" />
+40 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2022 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:height="48dp"
        android:width="48dp"
        android:viewportHeight="48"
        android:viewportWidth="48">
    <group android:name="_R_G">
        <group android:name="_R_G_L_1_G"
                android:translateX="24"
                android:translateY="24"
                android:scaleX="0.5"
                android:scaleY="0.5"/>
        <group android:name="_R_G_L_0_G"
                android:translateX="24"
                android:translateY="24"
                android:scaleX="0.5"
                android:scaleY="0.5">
            <path android:name="_R_G_L_0_G_D_0_P_0"
                    android:fillColor="#ffddb3"
                    android:fillAlpha="1"
                    android:fillType="nonZero"
                    android:pathData=" M48 -16 C48,-16 48,16 48,16 C48,33.67 33.67,48 16,48 C16,48 -16,48 -16,48 C-33.67,48 -48,33.67 -48,16 C-48,16 -48,-16 -48,-16 C-48,-33.67 -33.67,-48 -16,-48 C-16,-48 16,-48 16,-48 C33.67,-48 48,-33.67 48,-16c "/>
        </group>
    </group>
</vector>
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -2199,6 +2199,8 @@
    <string name="controls_media_button_prev">Previous track</string>
    <!-- Description for button in media controls. Pressing button goes to next track [CHAR_LIMIT=NONE] -->
    <string name="controls_media_button_next">Next track</string>
    <!-- Description for button in media controls. Used when media is connecting to a remote device (via something like chromecast). Pressing button does nothing [CHAR_LIMIT=NONE] -->
    <string name="controls_media_button_connecting">Connecting</string>

    <!-- Title for Smartspace recommendation card within media controls. The "Play" means the action to play a media [CHAR_LIMIT=10] -->
    <string name="controls_media_smartspace_rec_title">Play</string>
+53 −28
Original line number Diff line number Diff line
@@ -660,8 +660,10 @@ public class MediaControlPanel {
            final ImageButton button, MediaAction mediaAction, ConstraintSet collapsedSet,
            ConstraintSet expandedSet, boolean showInCompact) {

        animHandler.unregisterAll();
        if (mediaAction != null) {
            if (animHandler.updateRebindId(mediaAction.getRebindId())) {
                animHandler.unregisterAll();

                final Drawable icon = mediaAction.getIcon();
                button.setImageDrawable(icon);
                button.setContentDescription(mediaAction.getContentDescription());
@@ -678,6 +680,7 @@ public class MediaControlPanel {
                    button.setEnabled(true);
                    button.setOnClickListener(v -> {
                        if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
                            mLogger.logTapAction(button.getId(), mUid, mPackageName, mInstanceId);
                            mLogger.logTapAction(button.getId(), mUid, mPackageName, mInstanceId);
                            logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT);
                            action.run();
@@ -691,7 +694,9 @@ public class MediaControlPanel {
                        }
                    });
                }
            }
        } else {
            animHandler.unregisterAll();
            button.setImageDrawable(null);
            button.setContentDescription(null);
            button.setEnabled(false);
@@ -702,9 +707,29 @@ public class MediaControlPanel {
        setVisibleAndAlpha(expandedSet, button.getId(), mediaAction != null);
    }

    // AnimationBindHandler is responsible for tracking the bound animation state and preventing
    // jank and conflicts due to media notifications arriving at any time during an animation. It
    // does this in two parts.
    //  - Exit animations fired as a result of user input are tracked. When these are running, any
    //      bind actions are delayed until the animation completes (and then fired in sequence).
    //  - Continuous animations are tracked using their rebind id. Later calls using the same
    //      rebind id will be totally ignored to prevent the continuous animation from restarting.
    private static class AnimationBindHandler extends Animatable2.AnimationCallback {
        private ArrayList<Runnable> mOnAnimationsComplete = new ArrayList<>();
        private ArrayList<Animatable2> mRegistrations = new ArrayList<>();
        private Integer mRebindId = null;

        // This check prevents rebinding to the action button if the identifier has not changed. A
        // null value is always considered to be changed. This is used to prevent the connecting
        // animation from rebinding (and restarting) if multiple buffer PlaybackStates are pushed by
        // an application in a row.
        public boolean updateRebindId(Integer rebindId) {
            if (mRebindId == null || rebindId == null || !mRebindId.equals(rebindId)) {
                mRebindId = rebindId;
                return true;
            }
            return false;
        }

        public void tryRegister(Drawable drawable) {
            if (drawable instanceof Animatable2) {
+6 −1
Original line number Diff line number Diff line
@@ -184,7 +184,12 @@ data class MediaAction(
    val icon: Drawable?,
    val action: Runnable?,
    val contentDescription: CharSequence?,
    val background: Drawable?
    val background: Drawable?,

    // Rebind Id is used to detect identical rebinds and ignore them. It is intended
    // to prevent continuously looping animations from restarting due to the arrival
    // of repeated media notifications that are visually identical.
    val rebindId: Int? = null
)

/** State of the media device. */
Loading