Merge "[Output Switcher] Add message when cast devices are not avaliable"
This commit is contained in:
@@ -85,6 +85,36 @@
|
||||
android:overScrollMode="never"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/cast_app_section"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginStart="@dimen/dialog_side_padding"
|
||||
android:layout_marginEnd="@dimen/dialog_side_padding"
|
||||
android:layout_marginBottom="@dimen/dialog_bottom_padding"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:id="@+id/launch_app_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:ellipsize="end"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:text="@string/media_output_dialog_launch_app_text"
|
||||
android:maxLines="1"
|
||||
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/launch_app_button"
|
||||
style="@style/Widget.Dialog.Button.BorderButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="5dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -1121,6 +1121,7 @@
|
||||
<dimen name="media_output_dialog_header_icon_padding">16dp</dimen>
|
||||
<dimen name="media_output_dialog_icon_corner_radius">16dp</dimen>
|
||||
<dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen>
|
||||
<dimen name="media_output_dialog_app_tier_icon_size">20dp</dimen>
|
||||
|
||||
<!-- Distance that the full shade transition takes in order for qs to fully transition to the
|
||||
shade -->
|
||||
|
||||
@@ -2205,6 +2205,11 @@
|
||||
<string name="media_output_dialog_connect_failed">Can\'t switch. Tap to try again.</string>
|
||||
<!-- Title for pairing item [CHAR LIMIT=60] -->
|
||||
<string name="media_output_dialog_pairing_new">Pair new device</string>
|
||||
<!-- Title for launch app [CHAR LIMIT=60] -->
|
||||
<string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
|
||||
<!-- App name when can't get app name [CHAR LIMIT=60] -->
|
||||
<string name="media_output_dialog_unknown_launch_app_name">Unknown app</string>
|
||||
|
||||
|
||||
<!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
|
||||
<string name="build_number_clip_data_label">Build number</string>
|
||||
|
||||
@@ -21,10 +21,15 @@ import static android.view.WindowInsets.Type.statusBars;
|
||||
|
||||
import android.app.WallpaperColors;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Bundle;
|
||||
@@ -76,8 +81,10 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
private ImageView mAppResourceIcon;
|
||||
private RecyclerView mDevicesRecyclerView;
|
||||
private LinearLayout mDeviceListLayout;
|
||||
private LinearLayout mCastAppLayout;
|
||||
private Button mDoneButton;
|
||||
private Button mStopButton;
|
||||
private Button mAppButton;
|
||||
private int mListMaxHeight;
|
||||
private WallpaperColors mWallpaperColors;
|
||||
|
||||
@@ -129,7 +136,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
|
||||
mDoneButton = mDialogView.requireViewById(R.id.done);
|
||||
mStopButton = mDialogView.requireViewById(R.id.stop);
|
||||
mAppButton = mDialogView.requireViewById(R.id.launch_app_button);
|
||||
mAppResourceIcon = mDialogView.requireViewById(R.id.app_source_icon);
|
||||
mCastAppLayout = mDialogView.requireViewById(R.id.cast_app_section);
|
||||
|
||||
mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||
mDeviceListLayoutListener);
|
||||
@@ -144,6 +153,13 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
mMediaOutputController.releaseSession();
|
||||
dismiss();
|
||||
});
|
||||
mAppButton.setOnClickListener(v -> {
|
||||
mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
|
||||
if (mMediaOutputController.getAppLaunchIntent() != null) {
|
||||
mContext.startActivity(mMediaOutputController.getAppLaunchIntent());
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,8 +185,16 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
final IconCompat iconCompat = getHeaderIcon();
|
||||
final Drawable appSourceDrawable = getAppSourceIcon();
|
||||
boolean colorSetUpdated = false;
|
||||
mCastAppLayout.setVisibility(
|
||||
mMediaOutputController.shouldShowLaunchSection()
|
||||
? View.VISIBLE : View.GONE);
|
||||
if (appSourceDrawable != null) {
|
||||
mAppResourceIcon.setImageDrawable(appSourceDrawable);
|
||||
mAppButton.setCompoundDrawablesWithIntrinsicBounds(resizeDrawable(appSourceDrawable,
|
||||
mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.media_output_dialog_app_tier_icon_size
|
||||
)),
|
||||
null, null, null);
|
||||
} else {
|
||||
mAppResourceIcon.setVisibility(View.GONE);
|
||||
}
|
||||
@@ -205,6 +229,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
R.dimen.media_output_dialog_header_icon_padding);
|
||||
mHeaderIcon.setLayoutParams(new LinearLayout.LayoutParams(size + padding, size));
|
||||
}
|
||||
mAppButton.setText(mMediaOutputController.getAppSourceName());
|
||||
// Update title and subtitle
|
||||
mHeaderTitle.setText(getHeaderText());
|
||||
final CharSequence subTitle = getHeaderSubtitle();
|
||||
@@ -229,6 +254,22 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
mStopButton.setVisibility(getStopButtonVisibility());
|
||||
}
|
||||
|
||||
private Drawable resizeDrawable(Drawable drawable, int size) {
|
||||
if (drawable == null) {
|
||||
return null;
|
||||
}
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
|
||||
: Bitmap.Config.RGB_565;
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, config);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, width, height);
|
||||
drawable.draw(canvas);
|
||||
return new BitmapDrawable(mContext.getResources(),
|
||||
Bitmap.createScaledBitmap(bitmap, size, size, false));
|
||||
}
|
||||
|
||||
abstract Drawable getAppSourceIcon();
|
||||
|
||||
abstract int getHeaderIconRes();
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.app.Notification;
|
||||
import android.app.WallpaperColors;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
@@ -45,6 +46,8 @@ import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
import androidx.mediarouter.media.MediaRouterParams;
|
||||
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
@@ -171,6 +174,12 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
|
||||
mLocalMediaManager.startScan();
|
||||
}
|
||||
|
||||
boolean shouldShowLaunchSection() {
|
||||
MediaRouterParams routerParams = MediaRouter.getInstance(mContext).getRouterParams();
|
||||
Log.d(TAG, "try to get routerParams: " + routerParams);
|
||||
return routerParams != null && !routerParams.isMediaTransferReceiverEnabled();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (mMediaController != null) {
|
||||
mMediaController.unregisterCallback(mCb);
|
||||
@@ -220,6 +229,32 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
|
||||
}
|
||||
}
|
||||
|
||||
String getAppSourceName() {
|
||||
if (mPackageName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final PackageManager packageManager = mContext.getPackageManager();
|
||||
ApplicationInfo applicationInfo;
|
||||
try {
|
||||
applicationInfo = packageManager.getApplicationInfo(mPackageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
applicationInfo = null;
|
||||
}
|
||||
final String applicationName =
|
||||
(String) (applicationInfo != null ? packageManager.getApplicationLabel(
|
||||
applicationInfo)
|
||||
: mContext.getString(R.string.media_output_dialog_unknown_launch_app_name));
|
||||
return applicationName;
|
||||
}
|
||||
|
||||
Intent getAppLaunchIntent() {
|
||||
if (mPackageName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return mContext.getPackageManager().getLaunchIntentForPackage(mPackageName);
|
||||
}
|
||||
|
||||
CharSequence getHeaderTitle() {
|
||||
if (mMediaController != null) {
|
||||
final MediaMetadata metadata = mMediaController.getMetadata();
|
||||
|
||||
Reference in New Issue
Block a user