diff options
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java | 220 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java | 78 |
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(); + } +} |