Merge "Add flag for MediaRouter2-based InfoMediaManager" into main
This commit is contained in:
@@ -58,6 +58,7 @@ android_library {
|
||||
"setupdesign",
|
||||
"zxing-core-1.7",
|
||||
"androidx.room_room-runtime",
|
||||
"settingslib_flags_lib",
|
||||
|
||||
],
|
||||
|
||||
@@ -88,3 +89,16 @@ java_defaults {
|
||||
"SettingsLib",
|
||||
],
|
||||
}
|
||||
|
||||
aconfig_declarations {
|
||||
name: "settingslib_media_flags",
|
||||
package: "com.android.settingslib.media.flags",
|
||||
srcs: [
|
||||
"aconfig/settingslib_media_flag_declarations.aconfig",
|
||||
],
|
||||
}
|
||||
|
||||
java_aconfig_library {
|
||||
name: "settingslib_flags_lib",
|
||||
aconfig_declarations: "settingslib_media_flags",
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settingslib">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name="com.android.settingslib.users.AvatarPickerActivity"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package: "com.android.settingslib.media.flags"
|
||||
|
||||
flag {
|
||||
name: "use_media_router2_for_info_media_manager"
|
||||
namespace: "placeholder_namespace"
|
||||
description: "Gates whether to use a MediaRouter2-based implementation of InfoMediaManager, instead of the legacy MediaRouter2Manager-based implementation."
|
||||
bug: "192657812"
|
||||
}
|
||||
@@ -62,6 +62,7 @@ import androidx.annotation.RequiresApi;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.media.flags.Flags;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -105,6 +106,28 @@ public abstract class InfoMediaManager extends MediaManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates an instance of InfoMediaManager. */
|
||||
public static InfoMediaManager createInstance(
|
||||
Context context,
|
||||
String packageName,
|
||||
Notification notification,
|
||||
LocalBluetoothManager localBluetoothManager) {
|
||||
if (Flags.useMediaRouter2ForInfoMediaManager()) {
|
||||
try {
|
||||
return new RouterInfoMediaManager(
|
||||
context, packageName, notification, localBluetoothManager);
|
||||
} catch (PackageNotAvailableException ex) {
|
||||
// TODO: b/293578081 - Propagate this exception to callers for proper handling.
|
||||
Log.w(TAG, "Returning a no-op InfoMediaManager for package " + packageName);
|
||||
return new NoOpInfoMediaManager(
|
||||
context, packageName, notification, localBluetoothManager);
|
||||
}
|
||||
} else {
|
||||
return new ManagerInfoMediaManager(
|
||||
context, packageName, notification, localBluetoothManager);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScan() {
|
||||
mMediaDevices.clear();
|
||||
|
||||
@@ -137,7 +137,7 @@ public class LocalMediaManager implements BluetoothCallback {
|
||||
}
|
||||
|
||||
mInfoMediaManager =
|
||||
new ManagerInfoMediaManager(
|
||||
InfoMediaManager.createInstance(
|
||||
context, packageName, notification, mLocalBluetoothManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.settingslib.media;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.media.MediaRoute2Info;
|
||||
import android.media.RouteListingPreference;
|
||||
import android.media.RoutingSessionInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* No-op implementation of {@link InfoMediaManager}.
|
||||
*
|
||||
* <p>This implementation is used when {@link RouterInfoMediaManager} throws a {@link
|
||||
* InfoMediaManager.PackageNotAvailableException}.
|
||||
*/
|
||||
// TODO - b/293578081: Remove once PackageNotAvailableException is propagated to library clients.
|
||||
/* package */ final class NoOpInfoMediaManager extends InfoMediaManager {
|
||||
|
||||
NoOpInfoMediaManager(
|
||||
Context context,
|
||||
String packageName,
|
||||
Notification notification,
|
||||
LocalBluetoothManager localBluetoothManager) {
|
||||
super(context, packageName, notification, localBluetoothManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopScan() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScanOnRouter() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean connectDeviceWithoutPackageName(@NonNull MediaDevice device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transferToRoute(@NonNull MediaRoute2Info route) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void selectRoute(@NonNull MediaRoute2Info route, @NonNull RoutingSessionInfo info) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deselectRoute(@NonNull MediaRoute2Info route, @NonNull RoutingSessionInfo info) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void releaseSession(@NonNull RoutingSessionInfo sessionInfo) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<MediaRoute2Info> getSelectableRoutes(@NonNull RoutingSessionInfo info) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<MediaRoute2Info> getDeselectableRoutes(@NonNull RoutingSessionInfo info) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<MediaRoute2Info> getSelectedRoutes(@NonNull RoutingSessionInfo info) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSessionVolume(@NonNull RoutingSessionInfo info, int volume) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setRouteVolume(@NonNull MediaRoute2Info route, int volume) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected RouteListingPreference getRouteListingPreference() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<RoutingSessionInfo> getRemoteSessions() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<RoutingSessionInfo> getRoutingSessionsForPackage() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected RoutingSessionInfo getRoutingSessionById(@NonNull String sessionId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<MediaRoute2Info> getAllRoutes() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<MediaRoute2Info> getAvailableRoutesFromRouter() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,14 @@ android_test {
|
||||
"androidx.test.core",
|
||||
"androidx.test.rules",
|
||||
"androidx.test.espresso.core",
|
||||
"flag-junit",
|
||||
"mockito-target-minus-junit4",
|
||||
"platform-test-annotations",
|
||||
"truth-prebuilt",
|
||||
"SettingsLibDeviceStateRotationLock",
|
||||
"SettingsLibSettingsSpinner",
|
||||
"SettingsLibUsageProgressBarPreference",
|
||||
"settingslib_flags_lib",
|
||||
],
|
||||
|
||||
dxflags: ["--multi-dex"],
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.settingslib.media;
|
||||
|
||||
import static com.android.settingslib.media.flags.Flags.FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.UiAutomation;
|
||||
import android.content.Context;
|
||||
import android.platform.test.annotations.RequiresFlagsDisabled;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class InfoMediaManagerIntegTest {
|
||||
|
||||
private static final String FAKE_PACKAGE = "FAKE_PACKAGE";
|
||||
|
||||
private Context mContext;
|
||||
private UiAutomation mUiAutomation;
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
|
||||
mUiAutomation.adoptShellPermissionIdentity(Manifest.permission.MEDIA_CONTENT_CONTROL);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mUiAutomation.dropShellPermissionIdentity();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
|
||||
public void createInstance_withMR2FlagOn_returnsRouterInfoMediaManager() {
|
||||
InfoMediaManager manager =
|
||||
InfoMediaManager.createInstance(mContext, mContext.getPackageName(), null, null);
|
||||
assertThat(manager).isInstanceOf(RouterInfoMediaManager.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
|
||||
public void createInstance_withMR2FlagOn_withFakePackage_returnsNoOpInfoMediaManager() {
|
||||
InfoMediaManager manager =
|
||||
InfoMediaManager.createInstance(mContext, FAKE_PACKAGE, null, null);
|
||||
assertThat(manager).isInstanceOf(NoOpInfoMediaManager.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
|
||||
public void createInstance_withMR2FlagOn_withNullPackage_returnsRouterInfoMediaManager() {
|
||||
InfoMediaManager manager = InfoMediaManager.createInstance(mContext, null, null, null);
|
||||
assertThat(manager).isInstanceOf(RouterInfoMediaManager.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsDisabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
|
||||
public void createInstance_withMR2FlagOff_returnsManagerInfoMediaManager() {
|
||||
InfoMediaManager manager =
|
||||
InfoMediaManager.createInstance(mContext, mContext.getPackageName(), null, null);
|
||||
assertThat(manager).isInstanceOf(ManagerInfoMediaManager.class);
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ package com.android.systemui.media.controls.pipeline
|
||||
|
||||
import android.content.Context
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager
|
||||
import com.android.settingslib.media.InfoMediaManager
|
||||
import com.android.settingslib.media.LocalMediaManager
|
||||
import com.android.settingslib.media.ManagerInfoMediaManager
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Factory to create [LocalMediaManager] objects. */
|
||||
@@ -31,8 +31,7 @@ constructor(
|
||||
) {
|
||||
/** Creates a [LocalMediaManager] for the given package. */
|
||||
fun create(packageName: String): LocalMediaManager {
|
||||
return ManagerInfoMediaManager(context, packageName, null, localBluetoothManager).run {
|
||||
LocalMediaManager(context, localBluetoothManager, this, packageName)
|
||||
}
|
||||
return InfoMediaManager.createInstance(context, packageName, null, localBluetoothManager)
|
||||
.run { LocalMediaManager(context, localBluetoothManager, this, packageName) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastMetadata;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.media.InfoMediaManager;
|
||||
import com.android.settingslib.media.LocalMediaManager;
|
||||
import com.android.settingslib.media.ManagerInfoMediaManager;
|
||||
import com.android.settingslib.media.MediaDevice;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.R;
|
||||
@@ -194,7 +193,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
||||
mKeyGuardManager = keyGuardManager;
|
||||
mFeatureFlags = featureFlags;
|
||||
mUserTracker = userTracker;
|
||||
InfoMediaManager imm = new ManagerInfoMediaManager(mContext, packageName, null, lbm);
|
||||
InfoMediaManager imm = InfoMediaManager.createInstance(mContext, packageName, null, lbm);
|
||||
mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName);
|
||||
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
|
||||
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||
|
||||
Reference in New Issue
Block a user