Merge "Add album art and colorize players in new layout"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a5a2f681c6
26
packages/SystemUI/res/drawable/ic_media_next.xml
Normal file
26
packages/SystemUI/res/drawable/ic_media_next.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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:width="12dp"
|
||||
android:height="12dp"
|
||||
android:viewportWidth="12"
|
||||
android:viewportHeight="12">
|
||||
<path
|
||||
android:pathData="M0,12L8.5,6L0,0V12ZM2,3.86L5.03,6L2,8.14V3.86ZM12,0H10V12H12V0Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
26
packages/SystemUI/res/drawable/ic_media_pause.xml
Normal file
26
packages/SystemUI/res/drawable/ic_media_pause.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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:width="14dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="14"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M9.1818,15.6363H13.5455V0.3635H9.1818V15.6363ZM0.4546,15.6363H4.8182V0.3635H0.4546V15.6363Z"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
26
packages/SystemUI/res/drawable/ic_media_play.xml
Normal file
26
packages/SystemUI/res/drawable/ic_media_play.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M20,12L6,21V3L20,12ZM15.26,12L8.55,7.68V16.32L15.26,12Z"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
26
packages/SystemUI/res/drawable/ic_media_prev.xml
Normal file
26
packages/SystemUI/res/drawable/ic_media_prev.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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:width="12dp"
|
||||
android:height="12dp"
|
||||
android:viewportWidth="12"
|
||||
android:viewportHeight="12">
|
||||
<path
|
||||
android:pathData="M0,0H2V12H0V0ZM3.5,6L12,12V0L3.5,6ZM6.97,6L10,8.14V3.86L6.97,6Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
26
packages/SystemUI/res/drawable/qs_media_scrim.xml
Normal file
26
packages/SystemUI/res/drawable/qs_media_scrim.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/notification_corner_radius"/>
|
||||
<!-- gradient from 25% in the center to 100% at edges -->
|
||||
<gradient
|
||||
android:type="radial"
|
||||
android:gradientRadius="100%p"
|
||||
android:startColor="#40000000"
|
||||
android:endColor="#FF000000" />
|
||||
</shape>
|
||||
@@ -28,6 +28,22 @@
|
||||
android:background="@drawable/qs_media_background"
|
||||
android:theme="@style/MediaPlayer">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="184dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:translationZ="0dp"
|
||||
android:id="@+id/album_art"
|
||||
android:scaleType="centerCrop"
|
||||
android:adjustViewBounds="true"
|
||||
android:clipToOutline="true"
|
||||
android:foreground="@drawable/qs_media_scrim"
|
||||
android:background="@drawable/qs_media_scrim"
|
||||
/>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/center_vertical_guideline"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -281,6 +297,7 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
||||
<TextView
|
||||
android:id="@+id/cancel_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|bottom"
|
||||
@@ -304,6 +321,7 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
||||
<TextView
|
||||
android:id="@+id/dismiss_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|bottom"
|
||||
|
||||
@@ -264,6 +264,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancel_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|bottom"
|
||||
@@ -288,6 +289,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/remove_text">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dismiss_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|bottom"
|
||||
|
||||
@@ -411,7 +411,6 @@ class MediaCarouselController @Inject constructor(
|
||||
|
||||
// Returns true if new player is added
|
||||
private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData): Boolean {
|
||||
val dataCopy = data.copy(backgroundColor = bgColor)
|
||||
MediaPlayerData.moveIfExists(oldKey, key)
|
||||
val existingPlayer = MediaPlayerData.getMediaPlayer(key)
|
||||
val curVisibleMediaKey = MediaPlayerData.playerKeys()
|
||||
@@ -431,14 +430,14 @@ class MediaCarouselController @Inject constructor(
|
||||
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
newPlayer.mediaViewHolder?.player?.setLayoutParams(lp)
|
||||
newPlayer.bindPlayer(dataCopy, key)
|
||||
newPlayer.bindPlayer(data, key)
|
||||
newPlayer.setListening(currentlyExpanded)
|
||||
MediaPlayerData.addMediaPlayer(key, dataCopy, newPlayer, systemClock)
|
||||
MediaPlayerData.addMediaPlayer(key, data, newPlayer, systemClock)
|
||||
updatePlayerToState(newPlayer, noAnimation = true)
|
||||
reorderAllPlayers(curVisibleMediaKey)
|
||||
} else {
|
||||
existingPlayer.bindPlayer(dataCopy, key)
|
||||
MediaPlayerData.addMediaPlayer(key, dataCopy, existingPlayer, systemClock)
|
||||
existingPlayer.bindPlayer(data, key)
|
||||
MediaPlayerData.addMediaPlayer(key, data, existingPlayer, systemClock)
|
||||
if (visualStabilityManager.isReorderingAllowed || shouldScrollToActivePlayer) {
|
||||
reorderAllPlayers(curVisibleMediaKey)
|
||||
} else {
|
||||
@@ -543,7 +542,11 @@ class MediaCarouselController @Inject constructor(
|
||||
}
|
||||
|
||||
private fun getForegroundColor(): Int {
|
||||
return context.getColor(android.R.color.system_accent2_900)
|
||||
return if (mediaFlags.useMediaSessionLayout()) {
|
||||
context.getColor(android.R.color.system_neutral2_200)
|
||||
} else {
|
||||
context.getColor(android.R.color.system_accent2_900)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePageIndicator() {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.media;
|
||||
import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.WallpaperColors;
|
||||
import android.app.smartspace.SmartspaceAction;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -40,6 +41,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -54,6 +56,7 @@ import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||
import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
|
||||
import com.android.systemui.monet.ColorScheme;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.shared.system.SysUiStatsLog;
|
||||
@@ -405,7 +408,7 @@ public class MediaControlPanel {
|
||||
seamlessView.setContentDescription(deviceString);
|
||||
|
||||
// Dismiss
|
||||
mMediaViewHolder.getDismissLabel().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
|
||||
mMediaViewHolder.getDismissText().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
|
||||
mMediaViewHolder.getDismiss().setEnabled(isDismissible);
|
||||
mMediaViewHolder.getDismiss().setOnClickListener(v -> {
|
||||
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return;
|
||||
@@ -438,11 +441,10 @@ public class MediaControlPanel {
|
||||
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
|
||||
|
||||
// Album art
|
||||
PlayerViewHolder playerHolder = (PlayerViewHolder) mMediaViewHolder;
|
||||
ImageView albumView = playerHolder.getAlbumView();
|
||||
ImageView albumView = mMediaViewHolder.getAlbumView();
|
||||
boolean hasArtwork = data.getArtwork() != null;
|
||||
if (hasArtwork) {
|
||||
Drawable artwork = scaleDrawable(data.getArtwork());
|
||||
Drawable artwork = getScaledThumbnail(data.getArtwork());
|
||||
albumView.setPadding(0, 0, 0, 0);
|
||||
albumView.setImageDrawable(artwork);
|
||||
} else {
|
||||
@@ -548,6 +550,19 @@ public class MediaControlPanel {
|
||||
|
||||
/** Bind elements specific to PlayerSessionViewHolder */
|
||||
private void bindSessionPlayer(@NonNull MediaData data, String key) {
|
||||
// Default colors
|
||||
int surfaceColor = mBackgroundColor;
|
||||
int accentPrimary = com.android.settingslib.Utils.getColorAttr(mContext,
|
||||
com.android.internal.R.attr.textColorPrimary).getDefaultColor();
|
||||
int textPrimary = com.android.settingslib.Utils.getColorAttr(mContext,
|
||||
com.android.internal.R.attr.textColorPrimary).getDefaultColor();
|
||||
int textPrimaryInverse = com.android.settingslib.Utils.getColorAttr(mContext,
|
||||
com.android.internal.R.attr.textColorPrimaryInverse).getDefaultColor();
|
||||
int textSecondary = com.android.settingslib.Utils.getColorAttr(mContext,
|
||||
com.android.internal.R.attr.textColorSecondary).getDefaultColor();
|
||||
int textTertiary = com.android.settingslib.Utils.getColorAttr(mContext,
|
||||
com.android.internal.R.attr.textColorTertiary).getDefaultColor();
|
||||
|
||||
// App icon - use launcher icon
|
||||
ImageView appIconView = mMediaViewHolder.getAppIcon();
|
||||
appIconView.clearColorFilter();
|
||||
@@ -567,26 +582,106 @@ public class MediaControlPanel {
|
||||
appIconView.setColorFilter(color);
|
||||
}
|
||||
|
||||
// Album art
|
||||
ColorScheme colorScheme = null;
|
||||
ImageView albumView = mMediaViewHolder.getAlbumView();
|
||||
boolean hasArtwork = data.getArtwork() != null;
|
||||
if (hasArtwork) {
|
||||
colorScheme = new ColorScheme(WallpaperColors.fromBitmap(data.getArtwork().getBitmap()),
|
||||
true);
|
||||
|
||||
// Scale artwork to fit background
|
||||
int width = mMediaViewHolder.getPlayer().getWidth();
|
||||
int height = mMediaViewHolder.getPlayer().getHeight();
|
||||
Drawable artwork = getScaledBackground(data.getArtwork(), width, height);
|
||||
albumView.setPadding(0, 0, 0, 0);
|
||||
albumView.setImageDrawable(artwork);
|
||||
albumView.setClipToOutline(true);
|
||||
} else {
|
||||
// If there's no artwork, use colors from the app icon
|
||||
try {
|
||||
Drawable icon = mContext.getPackageManager().getApplicationIcon(
|
||||
data.getPackageName());
|
||||
colorScheme = new ColorScheme(WallpaperColors.fromDrawable(icon), true);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// Get colors for player
|
||||
if (colorScheme != null) {
|
||||
surfaceColor = colorScheme.getAccent2().get(9); // A2-800
|
||||
accentPrimary = colorScheme.getAccent1().get(2); // A1-100
|
||||
textPrimary = colorScheme.getNeutral1().get(1); // N1-50
|
||||
textPrimaryInverse = colorScheme.getNeutral1().get(10); // N1-900
|
||||
textSecondary = colorScheme.getNeutral2().get(3); // N2-200
|
||||
textTertiary = colorScheme.getNeutral2().get(5); // N2-400
|
||||
}
|
||||
|
||||
ColorStateList bgColorList = ColorStateList.valueOf(surfaceColor);
|
||||
ColorStateList accentColorList = ColorStateList.valueOf(accentPrimary);
|
||||
ColorStateList textColorList = ColorStateList.valueOf(textPrimary);
|
||||
|
||||
// Gradient and background (visible when there is no art)
|
||||
albumView.setForegroundTintList(ColorStateList.valueOf(surfaceColor));
|
||||
albumView.setBackgroundTintList(
|
||||
ColorStateList.valueOf(surfaceColor));
|
||||
mMediaViewHolder.getPlayer().setBackgroundTintList(bgColorList);
|
||||
|
||||
// Metadata text
|
||||
mMediaViewHolder.getTitleText().setTextColor(textPrimary);
|
||||
mMediaViewHolder.getArtistText().setTextColor(textSecondary);
|
||||
|
||||
// Seekbar
|
||||
SeekBar seekbar = mMediaViewHolder.getSeekBar();
|
||||
seekbar.getThumb().setTintList(textColorList);
|
||||
seekbar.setProgressTintList(textColorList);
|
||||
seekbar.setProgressBackgroundTintList(ColorStateList.valueOf(textTertiary));
|
||||
|
||||
// Output switcher
|
||||
View seamlessView = mMediaViewHolder.getSeamlessButton();
|
||||
seamlessView.setBackgroundTintList(accentColorList);
|
||||
ImageView seamlessIconView = mMediaViewHolder.getSeamlessIcon();
|
||||
seamlessIconView.setImageTintList(bgColorList);
|
||||
TextView seamlessText = mMediaViewHolder.getSeamlessText();
|
||||
seamlessText.setTextColor(surfaceColor);
|
||||
|
||||
// Media action buttons
|
||||
MediaButton semanticActions = data.getSemanticActions();
|
||||
if (semanticActions != null) {
|
||||
PlayerSessionViewHolder sessionHolder = (PlayerSessionViewHolder) mMediaViewHolder;
|
||||
setSemanticButton(sessionHolder.getActionPlayPause(),
|
||||
semanticActions.getPlayOrPause());
|
||||
setSemanticButton(sessionHolder.getActionNext(),
|
||||
semanticActions.getNextOrCustom());
|
||||
setSemanticButton(sessionHolder.getActionPrev(),
|
||||
semanticActions.getPrevOrCustom());
|
||||
setSemanticButton(sessionHolder.getActionStart(),
|
||||
semanticActions.getStartCustom());
|
||||
setSemanticButton(sessionHolder.getActionEnd(),
|
||||
semanticActions.getEndCustom());
|
||||
|
||||
// Play/pause button has a background
|
||||
sessionHolder.getActionPlayPause().setBackgroundTintList(accentColorList);
|
||||
setSemanticButton(sessionHolder.getActionPlayPause(), semanticActions.getPlayOrPause(),
|
||||
ColorStateList.valueOf(textPrimaryInverse));
|
||||
|
||||
setSemanticButton(sessionHolder.getActionNext(), semanticActions.getNextOrCustom(),
|
||||
textColorList);
|
||||
setSemanticButton(sessionHolder.getActionPrev(), semanticActions.getPrevOrCustom(),
|
||||
textColorList);
|
||||
setSemanticButton(sessionHolder.getActionStart(), semanticActions.getStartCustom(),
|
||||
textColorList);
|
||||
setSemanticButton(sessionHolder.getActionEnd(), semanticActions.getEndCustom(),
|
||||
textColorList);
|
||||
} else {
|
||||
Log.w(TAG, "Using semantic player, but did not get buttons");
|
||||
}
|
||||
|
||||
// Long press buttons
|
||||
mMediaViewHolder.getLongPressText().setTextColor(textColorList);
|
||||
mMediaViewHolder.getSettingsText().setTextColor(textColorList);
|
||||
mMediaViewHolder.getSettingsText().setBackgroundTintList(accentColorList);
|
||||
mMediaViewHolder.getCancelText().setTextColor(textColorList);
|
||||
mMediaViewHolder.getCancelText().setBackgroundTintList(accentColorList);
|
||||
mMediaViewHolder.getDismissText().setTextColor(textColorList);
|
||||
mMediaViewHolder.getDismissText().setBackgroundTintList(accentColorList);
|
||||
|
||||
}
|
||||
|
||||
private void setSemanticButton(final ImageButton button, MediaAction mediaAction) {
|
||||
private void setSemanticButton(final ImageButton button, MediaAction mediaAction,
|
||||
ColorStateList fgColor) {
|
||||
button.setImageTintList(fgColor);
|
||||
if (mediaAction != null) {
|
||||
button.setImageIcon(mediaAction.getIcon());
|
||||
button.setContentDescription(mediaAction.getContentDescription());
|
||||
@@ -844,8 +939,11 @@ public class MediaControlPanel {
|
||||
mMediaViewController.openGuts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale drawable to fit into the square album art thumbnail
|
||||
*/
|
||||
@UiThread
|
||||
private Drawable scaleDrawable(Icon icon) {
|
||||
private Drawable getScaledThumbnail(Icon icon) {
|
||||
if (icon == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -869,6 +967,25 @@ public class MediaControlPanel {
|
||||
return drawable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale artwork to fill the background of the panel
|
||||
*/
|
||||
@UiThread
|
||||
private Drawable getScaledBackground(Icon icon, int width, int height) {
|
||||
if (icon == null) {
|
||||
return null;
|
||||
}
|
||||
Drawable drawable = icon.loadDrawable(mContext);
|
||||
Rect bounds = new Rect(0, 0, width, height);
|
||||
if (bounds.width() > width || bounds.height() > height) {
|
||||
float offsetX = (bounds.width() - width) / 2.0f;
|
||||
float offsetY = (bounds.height() - height) / 2.0f;
|
||||
bounds.offset((int) -offsetX, (int) -offsetY);
|
||||
}
|
||||
drawable.setBounds(bounds);
|
||||
return drawable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current media controller
|
||||
*
|
||||
|
||||
@@ -30,9 +30,7 @@ import android.content.IntentFilter
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.ImageDecoder
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.Icon
|
||||
import android.media.MediaDescription
|
||||
import android.media.MediaMetadata
|
||||
@@ -562,7 +560,7 @@ class MediaDataManager(
|
||||
val mediaController = mediaControllerFactory.create(token)
|
||||
val metadata = mediaController.metadata
|
||||
|
||||
// Foreground and Background colors computed from album art
|
||||
// Album art
|
||||
val notif: Notification = sbn.notification
|
||||
var artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ART)
|
||||
if (artworkBitmap == null) {
|
||||
@@ -576,24 +574,6 @@ class MediaDataManager(
|
||||
} else {
|
||||
Icon.createWithBitmap(artworkBitmap)
|
||||
}
|
||||
if (artWorkIcon != null) {
|
||||
// If we have art, get colors from that
|
||||
if (artworkBitmap == null) {
|
||||
if (artWorkIcon.type == Icon.TYPE_BITMAP ||
|
||||
artWorkIcon.type == Icon.TYPE_ADAPTIVE_BITMAP) {
|
||||
artworkBitmap = artWorkIcon.bitmap
|
||||
} else {
|
||||
val drawable: Drawable = artWorkIcon.loadDrawable(context)
|
||||
artworkBitmap = Bitmap.createBitmap(
|
||||
drawable.intrinsicWidth,
|
||||
drawable.intrinsicHeight,
|
||||
Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(artworkBitmap)
|
||||
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
|
||||
drawable.draw(canvas)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// App name
|
||||
val builder = Notification.Builder.recoverBuilder(context, notif)
|
||||
@@ -787,30 +767,28 @@ class MediaDataManager(
|
||||
return when (action) {
|
||||
PlaybackState.ACTION_PLAY -> {
|
||||
MediaAction(
|
||||
Icon.createWithResource(context, com.android.internal.R.drawable.ic_media_play),
|
||||
Icon.createWithResource(context, R.drawable.ic_media_play),
|
||||
{ controller.transportControls.play() },
|
||||
context.getString(R.string.controls_media_button_play)
|
||||
)
|
||||
}
|
||||
PlaybackState.ACTION_PAUSE -> {
|
||||
MediaAction(
|
||||
Icon.createWithResource(context,
|
||||
com.android.internal.R.drawable.ic_media_pause),
|
||||
Icon.createWithResource(context, R.drawable.ic_media_pause),
|
||||
{ controller.transportControls.pause() },
|
||||
context.getString(R.string.controls_media_button_pause)
|
||||
)
|
||||
}
|
||||
PlaybackState.ACTION_SKIP_TO_PREVIOUS -> {
|
||||
MediaAction(
|
||||
Icon.createWithResource(context,
|
||||
com.android.internal.R.drawable.ic_media_previous),
|
||||
Icon.createWithResource(context, R.drawable.ic_media_prev),
|
||||
{ controller.transportControls.skipToPrevious() },
|
||||
context.getString(R.string.controls_media_button_prev)
|
||||
)
|
||||
}
|
||||
PlaybackState.ACTION_SKIP_TO_NEXT -> {
|
||||
MediaAction(
|
||||
Icon.createWithResource(context, com.android.internal.R.drawable.ic_media_next),
|
||||
Icon.createWithResource(context, R.drawable.ic_media_next),
|
||||
{ controller.transportControls.skipToNext() },
|
||||
context.getString(R.string.controls_media_button_next)
|
||||
)
|
||||
@@ -900,7 +878,7 @@ class MediaDataManager(
|
||||
|
||||
private fun getResumeMediaAction(action: Runnable): MediaAction {
|
||||
return MediaAction(
|
||||
Icon.createWithResource(context, R.drawable.lb_ic_play).setTint(themeText),
|
||||
Icon.createWithResource(context, R.drawable.ic_media_play).setTint(themeText),
|
||||
action,
|
||||
context.getString(R.string.controls_media_resume)
|
||||
)
|
||||
|
||||
@@ -35,6 +35,7 @@ abstract class MediaViewHolder constructor(itemView: View) {
|
||||
val player = itemView as TransitionLayout
|
||||
|
||||
// Player information
|
||||
val albumView = itemView.requireViewById<ImageView>(R.id.album_art)
|
||||
val appIcon = itemView.requireViewById<ImageView>(R.id.icon)
|
||||
val titleText = itemView.requireViewById<TextView>(R.id.header_title)
|
||||
val artistText = itemView.requireViewById<TextView>(R.id.header_artist)
|
||||
@@ -53,8 +54,9 @@ abstract class MediaViewHolder constructor(itemView: View) {
|
||||
// Settings screen
|
||||
val longPressText = itemView.requireViewById<TextView>(R.id.remove_text)
|
||||
val cancel = itemView.requireViewById<View>(R.id.cancel)
|
||||
val cancelText = itemView.requireViewById<TextView>(R.id.cancel_text)
|
||||
val dismiss = itemView.requireViewById<ViewGroup>(R.id.dismiss)
|
||||
val dismissLabel = dismiss.getChildAt(0)
|
||||
val dismissText = itemView.requireViewById<TextView>(R.id.dismiss_text)
|
||||
val settings = itemView.requireViewById<View>(R.id.settings)
|
||||
val settingsText = itemView.requireViewById<TextView>(R.id.settings_text)
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.android.systemui.R
|
||||
|
||||
@@ -29,9 +28,6 @@ import com.android.systemui.R
|
||||
*/
|
||||
class PlayerViewHolder private constructor(itemView: View) : MediaViewHolder(itemView) {
|
||||
|
||||
// Player information
|
||||
val albumView = itemView.requireViewById<ImageView>(R.id.album_art)
|
||||
|
||||
// Seek bar
|
||||
val progressTimes = itemView.requireViewById<ViewGroup>(R.id.notification_media_progress_time)
|
||||
override val elapsedTimeView = itemView.requireViewById<TextView>(R.id.media_elapsed_time)
|
||||
|
||||
@@ -125,8 +125,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
private lateinit var settings: View
|
||||
private lateinit var settingsText: TextView
|
||||
private lateinit var cancel: View
|
||||
private lateinit var cancelText: TextView
|
||||
private lateinit var dismiss: FrameLayout
|
||||
private lateinit var dismissLabel: View
|
||||
private lateinit var dismissText: TextView
|
||||
|
||||
private lateinit var session: MediaSession
|
||||
private val device = MediaDeviceData(true, null, DEVICE_NAME)
|
||||
@@ -163,8 +164,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
settings = View(context)
|
||||
settingsText = TextView(context)
|
||||
cancel = View(context)
|
||||
cancelText = TextView(context)
|
||||
dismiss = FrameLayout(context)
|
||||
dismissLabel = View(context)
|
||||
dismissText = TextView(context)
|
||||
initPlayerHolderMocks()
|
||||
initSessionHolderMocks()
|
||||
|
||||
@@ -244,13 +246,15 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
whenever(holder.settings).thenReturn(settings)
|
||||
whenever(holder.settingsText).thenReturn(settingsText)
|
||||
whenever(holder.cancel).thenReturn(cancel)
|
||||
whenever(holder.cancelText).thenReturn(cancelText)
|
||||
whenever(holder.dismiss).thenReturn(dismiss)
|
||||
whenever(holder.dismissLabel).thenReturn(dismissLabel)
|
||||
whenever(holder.dismissText).thenReturn(dismissText)
|
||||
}
|
||||
|
||||
/** Mock view holder for session player */
|
||||
private fun initSessionHolderMocks() {
|
||||
whenever(sessionHolder.player).thenReturn(view)
|
||||
whenever(sessionHolder.albumView).thenReturn(albumView)
|
||||
whenever(sessionHolder.appIcon).thenReturn(appIcon)
|
||||
whenever(sessionHolder.titleText).thenReturn(titleText)
|
||||
whenever(sessionHolder.artistText).thenReturn(artistText)
|
||||
@@ -284,8 +288,9 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
whenever(sessionHolder.settings).thenReturn(settings)
|
||||
whenever(sessionHolder.settingsText).thenReturn(settingsText)
|
||||
whenever(sessionHolder.cancel).thenReturn(cancel)
|
||||
whenever(sessionHolder.cancelText).thenReturn(cancelText)
|
||||
whenever(sessionHolder.dismiss).thenReturn(dismiss)
|
||||
whenever(sessionHolder.dismissLabel).thenReturn(dismissLabel)
|
||||
whenever(sessionHolder.dismissText).thenReturn(dismissText)
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
Reference in New Issue
Block a user