Loading services/core/java/com/android/server/media/MediaFeatureFlagManager.java +41 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.media; import android.annotation.StringDef; import android.app.ActivityThread; import android.app.Application; import android.provider.DeviceConfig; import java.lang.annotation.ElementType; Loading @@ -31,8 +33,11 @@ import java.lang.annotation.Target; */ private static final String NAMESPACE_MEDIA_BETTER_TOGETHER = "media_better_together"; @StringDef(prefix = "FEATURE_", value = { FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER @StringDef( prefix = "FEATURE_", value = { FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER, FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE }) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @Retention(RetentionPolicy.SOURCE) Loading @@ -46,6 +51,13 @@ import java.lang.annotation.Target; FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER = "BluetoothRouteController__enable_legacy_bluetooth_routes_controller"; /** * Whether to use IMPORTANCE_FOREGROUND (i.e. 100) or IMPORTANCE_FOREGROUND_SERVICE (i.e. 125) * as the minimum package importance for scanning. */ /* package */ static final @MediaFeatureFlag String FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE = "scanning_package_minimum_importance"; private static final MediaFeatureFlagManager sInstance = new MediaFeatureFlagManager(); private MediaFeatureFlagManager() { Loading @@ -63,4 +75,29 @@ import java.lang.annotation.Target; public boolean getBoolean(@MediaFeatureFlag String key, boolean defaultValue) { return DeviceConfig.getBoolean(NAMESPACE_MEDIA_BETTER_TOGETHER, key, defaultValue); } /** * Returns an int value from {@link DeviceConfig} from the system_time namespace, or {@code * defaultValue} if there is no explicit value set. */ public int getInt(@MediaFeatureFlag String key, int defaultValue) { return DeviceConfig.getInt(NAMESPACE_MEDIA_BETTER_TOGETHER, key, defaultValue); } /** * Adds a listener to react for changes in media feature flags values. Future calls to this * method with the same listener will replace the old namespace and executor. * * @param onPropertiesChangedListener The listener to add. */ public void addOnPropertiesChangedListener( DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) { Application currentApplication = ActivityThread.currentApplication(); if (currentApplication != null) { DeviceConfig.addOnPropertiesChangedListener( NAMESPACE_MEDIA_BETTER_TOGETHER, currentApplication.getMainExecutor(), onPropertiesChangedListener); } } } services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +46 −38 Original line number Diff line number Diff line Loading @@ -24,12 +24,12 @@ import static android.media.MediaRouter2Utils.getOriginalId; import static android.media.MediaRouter2Utils.getProviderId; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.media.MediaFeatureFlagManager.FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -92,15 +92,11 @@ class MediaRouter2ServiceImpl { // in MediaRouter2, remove this constant and replace the usages with the real request IDs. private static final long DUMMY_REQUEST_ID = -1; private static final String MEDIA_BETTER_TOGETHER_NAMESPACE = "media_better_together"; private static final String KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE = "scanning_package_minimum_importance"; private static int sPackageImportanceForScanning = DeviceConfig.getInt( MEDIA_BETTER_TOGETHER_NAMESPACE, /* name */ KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE, /* defaultValue */ IMPORTANCE_FOREGROUND_SERVICE); private static int sPackageImportanceForScanning = MediaFeatureFlagManager.getInstance() .getInt( FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE, IMPORTANCE_FOREGROUND_SERVICE); private final Context mContext; private final UserManagerInternal mUserManagerInternal; Loading Loading @@ -156,9 +152,8 @@ class MediaRouter2ServiceImpl { mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter); DeviceConfig.addOnPropertiesChangedListener(MEDIA_BETTER_TOGETHER_NAMESPACE, ActivityThread.currentApplication().getMainExecutor(), this::onDeviceConfigChange); MediaFeatureFlagManager.getInstance() .addOnPropertiesChangedListener(this::onDeviceConfigChange); } // Start of methods that implement MediaRouter2 operations. Loading Loading @@ -1002,7 +997,9 @@ class MediaRouter2ServiceImpl { return; } Slog.i(TAG, TextUtils.formatSimple( Slog.i( TAG, TextUtils.formatSimple( "setSessionVolumeWithRouter2 | router: %d, session: %s, volume: %d", routerRecord.mRouterId, uniqueSessionId, volume)); Loading @@ -1021,7 +1018,9 @@ class MediaRouter2ServiceImpl { return; } Slog.i(TAG, TextUtils.formatSimple( Slog.i( TAG, TextUtils.formatSimple( "releaseSessionWithRouter2 | router: %d, session: %s", routerRecord.mRouterId, uniqueSessionId)); Loading Loading @@ -1100,8 +1099,11 @@ class MediaRouter2ServiceImpl { // TODO: UserRecord <-> routerRecord, why do they reference each other? // How about removing mUserRecord from routerRecord? routerRecord.mUserRecord.mHandler.sendMessage( obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManager, routerRecord.mUserRecord.mHandler, routerRecord, manager)); obtainMessage( UserHandler::notifyDiscoveryPreferenceChangedToManager, routerRecord.mUserRecord.mHandler, routerRecord, manager)); } userRecord.mHandler.sendMessage( Loading Loading @@ -1381,8 +1383,9 @@ class MediaRouter2ServiceImpl { // End of locked methods that are used by both MediaRouter2 and MediaRouter2Manager. private void onDeviceConfigChange(@NonNull DeviceConfig.Properties properties) { sPackageImportanceForScanning = properties.getInt( /* name */ KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE, sPackageImportanceForScanning = properties.getInt( /* name */ FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE, /* defaultValue */ IMPORTANCE_FOREGROUND_SERVICE); } Loading Loading @@ -1734,10 +1737,10 @@ class MediaRouter2ServiceImpl { } boolean isUidRelevant; synchronized (service.mLock) { isUidRelevant = mUserRecord.mRouterRecords.stream().anyMatch( router -> router.mUid == uid) | mUserRecord.mManagerRecords.stream().anyMatch( manager -> manager.mUid == uid); isUidRelevant = mUserRecord.mRouterRecords.stream().anyMatch(router -> router.mUid == uid) | mUserRecord.mManagerRecords.stream() .anyMatch(manager -> manager.mUid == uid); } if (isUidRelevant) { sendMessage(PooledLambda.obtainMessage( Loading Loading @@ -2412,15 +2415,15 @@ class MediaRouter2ServiceImpl { } /** * Filters list of routes to return only public routes or routes provided by * the same package name or routes containing this package name in its allow list. * Filters list of routes to return only public routes or routes provided by the same * package name or routes containing this package name in its allow list. * * @param routes initial list of routes to be filtered. * @param packageName router's package name to filter routes for it. * @return only the routes that this package name is allowed to see. */ private static List<MediaRoute2Info> getFilteredRoutesForPackageName( @NonNull List<MediaRoute2Info> routes, @NonNull String packageName) { @NonNull List<MediaRoute2Info> routes, @NonNull String packageName) { List<MediaRoute2Info> filteredRoutes = new ArrayList<>(); for (MediaRoute2Info route : routes) { if (route.isVisibleTo(packageName)) { Loading Loading @@ -2609,8 +2612,12 @@ class MediaRouter2ServiceImpl { .map(record -> record.mDiscoveryPreference) .collect(Collectors.toList()); } else { discoveryPreferences = routerRecords.stream().filter(record -> service.mActivityManager.getPackageImportance(record.mPackageName) discoveryPreferences = routerRecords.stream() .filter( record -> service.mActivityManager.getPackageImportance( record.mPackageName) <= sPackageImportanceForScanning) .map(record -> record.mDiscoveryPreference) .collect(Collectors.toList()); Loading Loading @@ -2658,6 +2665,7 @@ class MediaRouter2ServiceImpl { return null; } } static final class SessionCreationRequest { public final RouterRecord mRouterRecord; public final long mUniqueRequestId; Loading Loading
services/core/java/com/android/server/media/MediaFeatureFlagManager.java +41 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.server.media; import android.annotation.StringDef; import android.app.ActivityThread; import android.app.Application; import android.provider.DeviceConfig; import java.lang.annotation.ElementType; Loading @@ -31,8 +33,11 @@ import java.lang.annotation.Target; */ private static final String NAMESPACE_MEDIA_BETTER_TOGETHER = "media_better_together"; @StringDef(prefix = "FEATURE_", value = { FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER @StringDef( prefix = "FEATURE_", value = { FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER, FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE }) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @Retention(RetentionPolicy.SOURCE) Loading @@ -46,6 +51,13 @@ import java.lang.annotation.Target; FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER = "BluetoothRouteController__enable_legacy_bluetooth_routes_controller"; /** * Whether to use IMPORTANCE_FOREGROUND (i.e. 100) or IMPORTANCE_FOREGROUND_SERVICE (i.e. 125) * as the minimum package importance for scanning. */ /* package */ static final @MediaFeatureFlag String FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE = "scanning_package_minimum_importance"; private static final MediaFeatureFlagManager sInstance = new MediaFeatureFlagManager(); private MediaFeatureFlagManager() { Loading @@ -63,4 +75,29 @@ import java.lang.annotation.Target; public boolean getBoolean(@MediaFeatureFlag String key, boolean defaultValue) { return DeviceConfig.getBoolean(NAMESPACE_MEDIA_BETTER_TOGETHER, key, defaultValue); } /** * Returns an int value from {@link DeviceConfig} from the system_time namespace, or {@code * defaultValue} if there is no explicit value set. */ public int getInt(@MediaFeatureFlag String key, int defaultValue) { return DeviceConfig.getInt(NAMESPACE_MEDIA_BETTER_TOGETHER, key, defaultValue); } /** * Adds a listener to react for changes in media feature flags values. Future calls to this * method with the same listener will replace the old namespace and executor. * * @param onPropertiesChangedListener The listener to add. */ public void addOnPropertiesChangedListener( DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) { Application currentApplication = ActivityThread.currentApplication(); if (currentApplication != null) { DeviceConfig.addOnPropertiesChangedListener( NAMESPACE_MEDIA_BETTER_TOGETHER, currentApplication.getMainExecutor(), onPropertiesChangedListener); } } }
services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +46 −38 Original line number Diff line number Diff line Loading @@ -24,12 +24,12 @@ import static android.media.MediaRouter2Utils.getOriginalId; import static android.media.MediaRouter2Utils.getProviderId; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.media.MediaFeatureFlagManager.FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -92,15 +92,11 @@ class MediaRouter2ServiceImpl { // in MediaRouter2, remove this constant and replace the usages with the real request IDs. private static final long DUMMY_REQUEST_ID = -1; private static final String MEDIA_BETTER_TOGETHER_NAMESPACE = "media_better_together"; private static final String KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE = "scanning_package_minimum_importance"; private static int sPackageImportanceForScanning = DeviceConfig.getInt( MEDIA_BETTER_TOGETHER_NAMESPACE, /* name */ KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE, /* defaultValue */ IMPORTANCE_FOREGROUND_SERVICE); private static int sPackageImportanceForScanning = MediaFeatureFlagManager.getInstance() .getInt( FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE, IMPORTANCE_FOREGROUND_SERVICE); private final Context mContext; private final UserManagerInternal mUserManagerInternal; Loading Loading @@ -156,9 +152,8 @@ class MediaRouter2ServiceImpl { mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter); DeviceConfig.addOnPropertiesChangedListener(MEDIA_BETTER_TOGETHER_NAMESPACE, ActivityThread.currentApplication().getMainExecutor(), this::onDeviceConfigChange); MediaFeatureFlagManager.getInstance() .addOnPropertiesChangedListener(this::onDeviceConfigChange); } // Start of methods that implement MediaRouter2 operations. Loading Loading @@ -1002,7 +997,9 @@ class MediaRouter2ServiceImpl { return; } Slog.i(TAG, TextUtils.formatSimple( Slog.i( TAG, TextUtils.formatSimple( "setSessionVolumeWithRouter2 | router: %d, session: %s, volume: %d", routerRecord.mRouterId, uniqueSessionId, volume)); Loading @@ -1021,7 +1018,9 @@ class MediaRouter2ServiceImpl { return; } Slog.i(TAG, TextUtils.formatSimple( Slog.i( TAG, TextUtils.formatSimple( "releaseSessionWithRouter2 | router: %d, session: %s", routerRecord.mRouterId, uniqueSessionId)); Loading Loading @@ -1100,8 +1099,11 @@ class MediaRouter2ServiceImpl { // TODO: UserRecord <-> routerRecord, why do they reference each other? // How about removing mUserRecord from routerRecord? routerRecord.mUserRecord.mHandler.sendMessage( obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManager, routerRecord.mUserRecord.mHandler, routerRecord, manager)); obtainMessage( UserHandler::notifyDiscoveryPreferenceChangedToManager, routerRecord.mUserRecord.mHandler, routerRecord, manager)); } userRecord.mHandler.sendMessage( Loading Loading @@ -1381,8 +1383,9 @@ class MediaRouter2ServiceImpl { // End of locked methods that are used by both MediaRouter2 and MediaRouter2Manager. private void onDeviceConfigChange(@NonNull DeviceConfig.Properties properties) { sPackageImportanceForScanning = properties.getInt( /* name */ KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE, sPackageImportanceForScanning = properties.getInt( /* name */ FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE, /* defaultValue */ IMPORTANCE_FOREGROUND_SERVICE); } Loading Loading @@ -1734,10 +1737,10 @@ class MediaRouter2ServiceImpl { } boolean isUidRelevant; synchronized (service.mLock) { isUidRelevant = mUserRecord.mRouterRecords.stream().anyMatch( router -> router.mUid == uid) | mUserRecord.mManagerRecords.stream().anyMatch( manager -> manager.mUid == uid); isUidRelevant = mUserRecord.mRouterRecords.stream().anyMatch(router -> router.mUid == uid) | mUserRecord.mManagerRecords.stream() .anyMatch(manager -> manager.mUid == uid); } if (isUidRelevant) { sendMessage(PooledLambda.obtainMessage( Loading Loading @@ -2412,15 +2415,15 @@ class MediaRouter2ServiceImpl { } /** * Filters list of routes to return only public routes or routes provided by * the same package name or routes containing this package name in its allow list. * Filters list of routes to return only public routes or routes provided by the same * package name or routes containing this package name in its allow list. * * @param routes initial list of routes to be filtered. * @param packageName router's package name to filter routes for it. * @return only the routes that this package name is allowed to see. */ private static List<MediaRoute2Info> getFilteredRoutesForPackageName( @NonNull List<MediaRoute2Info> routes, @NonNull String packageName) { @NonNull List<MediaRoute2Info> routes, @NonNull String packageName) { List<MediaRoute2Info> filteredRoutes = new ArrayList<>(); for (MediaRoute2Info route : routes) { if (route.isVisibleTo(packageName)) { Loading Loading @@ -2609,8 +2612,12 @@ class MediaRouter2ServiceImpl { .map(record -> record.mDiscoveryPreference) .collect(Collectors.toList()); } else { discoveryPreferences = routerRecords.stream().filter(record -> service.mActivityManager.getPackageImportance(record.mPackageName) discoveryPreferences = routerRecords.stream() .filter( record -> service.mActivityManager.getPackageImportance( record.mPackageName) <= sPackageImportanceForScanning) .map(record -> record.mDiscoveryPreference) .collect(Collectors.toList()); Loading Loading @@ -2658,6 +2665,7 @@ class MediaRouter2ServiceImpl { return null; } } static final class SessionCreationRequest { public final RouterRecord mRouterRecord; public final long mUniqueRequestId; Loading