summaryrefslogtreecommitdiff
path: root/packages/SystemUI/src
diff options
context:
space:
mode:
authortimhypeng <timhypeng@google.com>2020-12-08 06:29:28 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-12-08 06:29:28 +0000
commit04645b9997a38c582925abb954f880a0cbbbc001 (patch)
treee4c199caed39260c608d485131543d45eee0879d /packages/SystemUI/src
parent637e1d25130f6d6fe7a86f5670bc869addf9b589 (diff)
parent3e5de04302633a1def9047798f64aecfc0c7efce (diff)
Add Media Output Dialog for Output Switcher am: 3e5de04302
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13109603 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Iec4be1ac2a277b556c26548e152f4a9b705e14a7
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java220
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java78
2 files changed, 298 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
new file mode 100644
index 000000000000..781bf8d74d88
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package com.android.systemui.media.dialog;
+
+import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.statusBars;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.Window;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.core.graphics.drawable.IconCompat;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settingslib.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+/**
+ * Base dialog for media output UI
+ */
+public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
+ MediaOutputController.Callback {
+
+ private static final String TAG = "MediaOutputDialog";
+
+ private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
+ private final RecyclerView.LayoutManager mLayoutManager;
+
+ final Context mContext;
+ final MediaOutputController mMediaOutputController;
+
+ @VisibleForTesting
+ View mDialogView;
+ private TextView mHeaderTitle;
+ private TextView mHeaderSubtitle;
+ private ImageView mHeaderIcon;
+ private RecyclerView mDevicesRecyclerView;
+ private LinearLayout mDeviceListLayout;
+ private Button mDoneButton;
+ private Button mStopButton;
+ private View mListBottomPadding;
+ private int mListMaxHeight;
+
+ MediaOutputBaseAdapter mAdapter;
+ FrameLayout mGroupItemController;
+ View mGroupDivider;
+
+ private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
+ // Set max height for list
+ if (mDeviceListLayout.getHeight() > mListMaxHeight) {
+ ViewGroup.LayoutParams params = mDeviceListLayout.getLayoutParams();
+ params.height = mListMaxHeight;
+ mDeviceListLayout.setLayoutParams(params);
+ }
+ };
+
+ public MediaOutputBaseDialog(Context context, MediaOutputController mediaOutputController) {
+ super(context, R.style.Theme_SystemUI_Dialog_MediaOutput);
+ mContext = context;
+ mMediaOutputController = mediaOutputController;
+ mLayoutManager = new LinearLayoutManager(mContext);
+ mListMaxHeight = context.getResources().getDimensionPixelSize(
+ R.dimen.media_output_dialog_list_max_height);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mDialogView = LayoutInflater.from(mContext).inflate(R.layout.media_output_dialog, null);
+ final Window window = getWindow();
+ final WindowManager.LayoutParams lp = window.getAttributes();
+ lp.gravity = Gravity.BOTTOM;
+ // Config insets to make sure the layout is above the navigation bar
+ lp.setFitInsetsTypes(statusBars() | navigationBars());
+ lp.setFitInsetsSides(WindowInsets.Side.all());
+ lp.setFitInsetsIgnoringVisibility(true);
+ window.setAttributes(lp);
+ window.setContentView(mDialogView);
+ window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mHeaderTitle = mDialogView.requireViewById(R.id.header_title);
+ mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
+ mHeaderIcon = mDialogView.requireViewById(R.id.header_icon);
+ mDevicesRecyclerView = mDialogView.requireViewById(R.id.list_result);
+ mGroupItemController = mDialogView.requireViewById(R.id.group_item_controller);
+ mGroupDivider = mDialogView.requireViewById(R.id.group_item_divider);
+ mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
+ mDoneButton = mDialogView.requireViewById(R.id.done);
+ mStopButton = mDialogView.requireViewById(R.id.stop);
+ mListBottomPadding = mDialogView.requireViewById(R.id.list_bottom_padding);
+
+ mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
+ mDeviceListLayoutListener);
+ // Init device list
+ mDevicesRecyclerView.setLayoutManager(mLayoutManager);
+ mDevicesRecyclerView.setAdapter(mAdapter);
+ // Init bottom buttons
+ mDoneButton.setOnClickListener(v -> dismiss());
+ mStopButton.setOnClickListener(v -> {
+ mMediaOutputController.releaseSession();
+ dismiss();
+ });
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mMediaOutputController.start(this);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mMediaOutputController.stop();
+ }
+
+ @VisibleForTesting
+ void refresh() {
+ // Update header icon
+ final int iconRes = getHeaderIconRes();
+ final IconCompat iconCompat = getHeaderIcon();
+ if (iconRes != 0) {
+ mHeaderIcon.setVisibility(View.VISIBLE);
+ mHeaderIcon.setImageResource(iconRes);
+ } else if (iconCompat != null) {
+ mHeaderIcon.setVisibility(View.VISIBLE);
+ mHeaderIcon.setImageIcon(iconCompat.toIcon(mContext));
+ } else {
+ mHeaderIcon.setVisibility(View.GONE);
+ }
+ if (mHeaderIcon.getVisibility() == View.VISIBLE) {
+ final int size = getHeaderIconSize();
+ mHeaderIcon.setLayoutParams(new LinearLayout.LayoutParams(size, size));
+ }
+ // Update title and subtitle
+ mHeaderTitle.setText(getHeaderText());
+ final CharSequence subTitle = getHeaderSubtitle();
+ if (TextUtils.isEmpty(subTitle)) {
+ mHeaderSubtitle.setVisibility(View.GONE);
+ mHeaderTitle.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
+ } else {
+ mHeaderSubtitle.setVisibility(View.VISIBLE);
+ mHeaderSubtitle.setText(subTitle);
+ mHeaderTitle.setGravity(Gravity.NO_GRAVITY);
+ }
+ if (!mAdapter.isDragging()) {
+ mAdapter.notifyDataSetChanged();
+ }
+ // Add extra padding when device amount is less than 6
+ if (mMediaOutputController.getMediaDevices().size() < 6) {
+ mListBottomPadding.setVisibility(View.VISIBLE);
+ } else {
+ mListBottomPadding.setVisibility(View.GONE);
+ }
+ }
+
+ abstract int getHeaderIconRes();
+
+ abstract IconCompat getHeaderIcon();
+
+ abstract int getHeaderIconSize();
+
+ abstract CharSequence getHeaderText();
+
+ abstract CharSequence getHeaderSubtitle();
+
+ @Override
+ public void onMediaChanged() {
+ mMainThreadHandler.post(() -> refresh());
+ }
+
+ @Override
+ public void onMediaStoppedOrPaused() {
+ if (isShowing()) {
+ dismiss();
+ }
+ }
+
+ @Override
+ public void onRouteChanged() {
+ mMainThreadHandler.post(() -> refresh());
+ }
+
+ @Override
+ public void dismissDialog() {
+ dismiss();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
new file mode 100644
index 000000000000..d59971dea2d7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package com.android.systemui.media.dialog;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.core.graphics.drawable.IconCompat;
+
+import com.android.systemui.R;
+
+import javax.inject.Singleton;
+
+/**
+ * Dialog for media output transferring.
+ */
+@Singleton
+public class MediaOutputDialog extends MediaOutputBaseDialog {
+
+ MediaOutputDialog(Context context, boolean aboveStatusbar, MediaOutputController
+ mediaOutputController) {
+ super(context, mediaOutputController);
+ mAdapter = new MediaOutputAdapter(mMediaOutputController);
+ if (!aboveStatusbar) {
+ getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
+ }
+ show();
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mGroupItemController.setVisibility(View.GONE);
+ mGroupDivider.setVisibility(View.GONE);
+ }
+
+ @Override
+ int getHeaderIconRes() {
+ return 0;
+ }
+
+ @Override
+ IconCompat getHeaderIcon() {
+ return mMediaOutputController.getHeaderIcon();
+ }
+
+ @Override
+ int getHeaderIconSize() {
+ return mContext.getResources().getDimensionPixelSize(
+ R.dimen.media_output_dialog_header_album_icon_size);
+ }
+
+ @Override
+ CharSequence getHeaderText() {
+ return mMediaOutputController.getHeaderTitle();
+ }
+
+ @Override
+ CharSequence getHeaderSubtitle() {
+ return mMediaOutputController.getHeaderSubTitle();
+ }
+}