summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorhughchen <hughchen@google.com>2020-01-17 15:19:04 +0800
committerhughchen <hughchen@google.com>2020-02-19 10:05:44 +0800
commit201b48b885f611c2e1779418a6a77c6e5ba4b2ad (patch)
tree24c0edeb4925d50687676b4f36011559728978cc /src
parent14b758f1c8d8b238f96d41f913c86c8f904b4605 (diff)
downloadpackages_apps_Settings-201b48b885f611c2e1779418a6a77c6e5ba4b2ad.tar.gz
packages_apps_Settings-201b48b885f611c2e1779418a6a77c6e5ba4b2ad.tar.bz2
packages_apps_Settings-201b48b885f611c2e1779418a6a77c6e5ba4b2ad.zip
Add stop casting button for output switch
This CL add a customize button to stop casting when media is transferred to info device. This CL include following change: - Add new methods to PanelContent.java. Let panels to customize "see more button". - MediaOutputPanel will check which device is used to transfer media currently. The customize button will shown on when transfer device is info device. Then user can use this button to stop casting. - Add test case. Bug: 147856563 Test: make -j42 RunSettingsRoboTests Change-Id: I8b201a10339f39f1d938d99b5659a82014e5bb89
Diffstat (limited to 'src')
-rw-r--r--src/com/android/settings/panel/MediaOutputPanel.java85
-rw-r--r--src/com/android/settings/panel/PanelContent.java27
-rw-r--r--src/com/android/settings/panel/PanelCustomizedButtonCallback.java29
-rw-r--r--src/com/android/settings/panel/PanelFragment.java39
4 files changed, 172 insertions, 8 deletions
diff --git a/src/com/android/settings/panel/MediaOutputPanel.java b/src/com/android/settings/panel/MediaOutputPanel.java
index d6030cc409..7b69fe382b 100644
--- a/src/com/android/settings/panel/MediaOutputPanel.java
+++ b/src/com/android/settings/panel/MediaOutputPanel.java
@@ -16,6 +16,9 @@
package com.android.settings.panel;
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
import static com.android.settings.media.MediaOutputSlice.MEDIA_PACKAGE_NAME;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI;
@@ -35,9 +38,15 @@ import android.text.TextUtils;
import android.util.Log;
import androidx.core.graphics.drawable.IconCompat;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
+import com.android.settingslib.media.InfoMediaDevice;
+import com.android.settingslib.media.LocalMediaManager;
+import com.android.settingslib.media.MediaDevice;
import java.util.ArrayList;
import java.util.List;
@@ -49,13 +58,20 @@ import java.util.List;
* Displays Media output item
* </p>
*/
-public class MediaOutputPanel implements PanelContent {
+public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceCallback,
+ LifecycleObserver {
private static final String TAG = "MediaOutputPanel";
private final Context mContext;
private final String mPackageName;
+ private PanelCustomizedButtonCallback mCallback;
+ private boolean mIsCustomizedButtonUsed = true;
+
+ @VisibleForTesting
+ LocalMediaManager mLocalMediaManager;
+
private MediaSessionManager mMediaSessionManager;
private MediaController mMediaController;
@@ -65,8 +81,9 @@ public class MediaOutputPanel implements PanelContent {
private MediaOutputPanel(Context context, String packageName) {
mContext = context.getApplicationContext();
- mPackageName = packageName;
- if (mPackageName != null) {
+ mPackageName = TextUtils.isEmpty(packageName) ? "" : packageName;
+
+ if (!TextUtils.isEmpty(mPackageName)) {
mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class);
for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
@@ -75,6 +92,7 @@ public class MediaOutputPanel implements PanelContent {
}
}
}
+
if (mMediaController == null) {
Log.e(TAG, "Unable to find " + mPackageName + " media controller");
}
@@ -157,7 +175,68 @@ public class MediaOutputPanel implements PanelContent {
}
@Override
+ public boolean isCustomizedButtonUsed() {
+ return mIsCustomizedButtonUsed;
+ }
+
+ @Override
+ public CharSequence getCustomButtonTitle() {
+ return mContext.getText(R.string.media_output_panel_stop_casting_button);
+ }
+
+ @Override
+ public void onClickCustomizedButton() {
+ }
+
+ @Override
+ public void registerCallback(PanelCustomizedButtonCallback callback) {
+ mCallback = callback;
+ }
+
+ @Override
public int getMetricsCategory() {
return SettingsEnums.PANEL_MEDIA_OUTPUT;
}
+
+ @Override
+ public void onSelectedDeviceStateChanged(MediaDevice device, int state) {
+ dispatchCustomButtonStateChanged();
+ }
+
+ @Override
+ public void onDeviceListUpdate(List<MediaDevice> devices) {
+ dispatchCustomButtonStateChanged();
+ }
+
+ @Override
+ public void onDeviceAttributesChanged() {
+ dispatchCustomButtonStateChanged();
+ }
+
+ private void dispatchCustomButtonStateChanged() {
+ hideCustomButtonIfNecessary();
+ if (mCallback != null) {
+ mCallback.onCustomizedButtonStateChanged();
+ }
+ }
+
+ private void hideCustomButtonIfNecessary() {
+ final MediaDevice device = mLocalMediaManager.getCurrentConnectedDevice();
+ mIsCustomizedButtonUsed = device instanceof InfoMediaDevice;
+ }
+
+ @OnLifecycleEvent(ON_START)
+ public void onStart() {
+ if (mLocalMediaManager == null) {
+ mLocalMediaManager = new LocalMediaManager(mContext, mPackageName, null);
+ }
+ mLocalMediaManager.registerCallback(this);
+ mLocalMediaManager.startScan();
+ }
+
+ @OnLifecycleEvent(ON_STOP)
+ public void onStop() {
+ mLocalMediaManager.unregisterCallback(this);
+ mLocalMediaManager.stopScan();
+ }
}
diff --git a/src/com/android/settings/panel/PanelContent.java b/src/com/android/settings/panel/PanelContent.java
index 60b9ed7ab1..352a304e24 100644
--- a/src/com/android/settings/panel/PanelContent.java
+++ b/src/com/android/settings/panel/PanelContent.java
@@ -74,4 +74,31 @@ public interface PanelContent extends Instrumentable {
default Intent getHeaderIconIntent() {
return null;
}
+
+ /**
+ * @return {@code true} to enable custom button to replace see more button,
+ * {@code false} otherwise.
+ */
+ default boolean isCustomizedButtonUsed() {
+ return false;
+ }
+
+ /**
+ * @return a string for the title of the custom button.
+ */
+ default CharSequence getCustomButtonTitle() {
+ return null;
+ }
+
+ /**
+ * Implement the click event for custom button.
+ */
+ default void onClickCustomizedButton() {}
+
+ /**
+ * Register to start receiving callbacks for custom button events.
+ *
+ * @param callback the callback to add.
+ */
+ default void registerCallback(PanelCustomizedButtonCallback callback) {}
}
diff --git a/src/com/android/settings/panel/PanelCustomizedButtonCallback.java b/src/com/android/settings/panel/PanelCustomizedButtonCallback.java
new file mode 100644
index 0000000000..8b4290ff1d
--- /dev/null
+++ b/src/com/android/settings/panel/PanelCustomizedButtonCallback.java
@@ -0,0 +1,29 @@
+/*
+ * 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.settings.panel;
+
+/**
+ * PanelCustomizedButtonCallback provides a callback interface for {@link PanelFragment} to receive
+ * events from {@link PanelContent}.
+ */
+public interface PanelCustomizedButtonCallback {
+
+ /**
+ * It will be called when customized button state is changed. For example, custom button
+ * would be hidden for specific behavior.
+ */
+ void onCustomizedButtonStateChanged();
+}
diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java
index 0f46758244..31e2ac6ee5 100644
--- a/src/com/android/settings/panel/PanelFragment.java
+++ b/src/com/android/settings/panel/PanelFragment.java
@@ -41,6 +41,7 @@ import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.IconCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
+import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LiveData;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -53,6 +54,7 @@ import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.panel.PanelLoggingContract.PanelClosedKeys;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.utils.ThreadUtils;
import com.google.android.setupdesign.DividerItemDecoration;
@@ -183,6 +185,11 @@ public class PanelFragment extends Fragment {
activity.finish();
}
+ mPanel.registerCallback(new LocalPanelCallback());
+ if (mPanel instanceof LifecycleObserver) {
+ getLifecycle().addObserver((LifecycleObserver) mPanel);
+ }
+
mMetricsProvider = FeatureFactory.getFactory(activity).getMetricsFeatureProvider();
mPanelSlices.setLayoutManager(new LinearLayoutManager((activity)));
@@ -208,8 +215,15 @@ public class PanelFragment extends Fragment {
mSeeMoreButton.setOnClickListener(getSeeMoreListener());
mDoneButton.setOnClickListener(getCloseListener());
- // If getSeeMoreIntent() is null, hide the mSeeMoreButton.
- if (mPanel.getSeeMoreIntent() == null) {
+ if (mPanel.isCustomizedButtonUsed()) {
+ final CharSequence customTitle = mPanel.getCustomButtonTitle();
+ if (TextUtils.isEmpty(customTitle)) {
+ mSeeMoreButton.setVisibility(View.GONE);
+ } else {
+ mSeeMoreButton.setText(customTitle);
+ }
+ } else if (mPanel.getSeeMoreIntent() == null) {
+ // If getSeeMoreIntent() is null hide the mSeeMoreButton.
mSeeMoreButton.setVisibility(View.GONE);
}
@@ -371,9 +385,13 @@ public class PanelFragment extends Fragment {
View.OnClickListener getSeeMoreListener() {
return (v) -> {
mPanelClosedKey = PanelClosedKeys.KEY_SEE_MORE;
- final FragmentActivity activity = getActivity();
- activity.startActivityForResult(mPanel.getSeeMoreIntent(), 0);
- activity.finish();
+ if (mPanel.isCustomizedButtonUsed()) {
+ mPanel.onClickCustomizedButton();
+ } else {
+ final FragmentActivity activity = getActivity();
+ activity.startActivityForResult(mPanel.getSeeMoreIntent(), 0);
+ activity.finish();
+ }
};
}
@@ -392,4 +410,15 @@ public class PanelFragment extends Fragment {
activity.startActivity(mPanel.getHeaderIconIntent());
};
}
+
+ class LocalPanelCallback implements PanelCustomizedButtonCallback {
+
+ @Override
+ public void onCustomizedButtonStateChanged() {
+ ThreadUtils.postOnMainThread(() -> {
+ mSeeMoreButton.setVisibility(
+ mPanel.isCustomizedButtonUsed() ? View.VISIBLE : View.GONE);
+ });
+ }
+ }
}