Adjust the condition for scanning in MRService

This CL allows foreground services to scan media route providers.

Android 12 restricts starting of FGS and doing this
enables apps to response while in the background.

Instead, the media router service unbinds from the provider services
when the device is not interactive.

Bug: 179160443
Test: manually && atest MediaRouterManagerTest
Change-Id: Ie3712e9d2cba1f801975ea49e6f48a287b3c003e
This commit is contained in:
Kyunglyul Hyun
2021-04-06 16:50:58 +00:00
parent 7eb1c4c24e
commit 50814321c0

View File

@@ -16,7 +16,9 @@
package com.android.server.media;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_SCREEN_ON;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
import static android.media.MediaRouter2Utils.getOriginalId;
import static android.media.MediaRouter2Utils.getProviderId;
@@ -26,7 +28,10 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.IMediaRouter2;
import android.media.IMediaRouter2Manager;
@@ -41,6 +46,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -62,6 +68,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* Implements features related to {@link android.media.MediaRouter2} and
@@ -74,12 +81,13 @@ class MediaRouter2ServiceImpl {
// TODO: (In Android S or later) if we add callback methods for generic failures
// 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 int PACKAGE_IMPORTANCE_FOR_DISCOVERY = IMPORTANCE_FOREGROUND;
private static final int PACKAGE_IMPORTANCE_FOR_DISCOVERY = IMPORTANCE_FOREGROUND_SERVICE;
private final Context mContext;
private final Object mLock = new Object();
final AtomicInteger mNextRouterOrManagerId = new AtomicInteger(1);
final ActivityManager mActivityManager;
final PowerManager mPowerManager;
@GuardedBy("mLock")
private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
@@ -100,11 +108,32 @@ class MediaRouter2ServiceImpl {
}
};
private final BroadcastReceiver mScreenOnOffReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
final int count = mUserRecords.size();
for (int i = 0; i < count; i++) {
UserHandler userHandler = mUserRecords.valueAt(i).mHandler;
userHandler.sendMessage(PooledLambda.obtainMessage(
UserHandler::updateDiscoveryPreferenceOnHandler, userHandler));
}
}
}
};
MediaRouter2ServiceImpl(Context context) {
mContext = context;
mActivityManager = mContext.getSystemService(ActivityManager.class);
mActivityManager.addOnUidImportanceListener(mOnUidImportanceListener,
PACKAGE_IMPORTANCE_FOR_DISCOVERY);
mPowerManager = mContext.getSystemService(PowerManager.class);
IntentFilter screenOnOffIntentFilter = new IntentFilter();
screenOnOffIntentFilter.addAction(ACTION_SCREEN_ON);
screenOnOffIntentFilter.addAction(ACTION_SCREEN_OFF);
mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter);
}
////////////////////////////////////////////////////////////////
@@ -2105,19 +2134,26 @@ class MediaRouter2ServiceImpl {
if (service == null) {
return;
}
List<RouteDiscoveryPreference> discoveryPreferences = new ArrayList<>();
List<RouteDiscoveryPreference> discoveryPreferences = Collections.emptyList();
List<RouterRecord> routerRecords = getRouterRecords();
List<ManagerRecord> managerRecords = getManagerRecords();
boolean isAnyManagerScanning =
managerRecords.stream().anyMatch(manager -> manager.mIsScanning
&& service.mActivityManager.getPackageImportance(manager.mPackageName)
<= PACKAGE_IMPORTANCE_FOR_DISCOVERY);
for (RouterRecord routerRecord : routerRecords) {
if (isAnyManagerScanning
|| service.mActivityManager.getPackageImportance(routerRecord.mPackageName)
<= PACKAGE_IMPORTANCE_FOR_DISCOVERY) {
discoveryPreferences.add(routerRecord.mDiscoveryPreference);
if (service.mPowerManager.isInteractive()) {
boolean isManagerScanning = managerRecords.stream().anyMatch(manager ->
manager.mIsScanning && service.mActivityManager
.getPackageImportance(manager.mPackageName)
<= PACKAGE_IMPORTANCE_FOR_DISCOVERY);
if (isManagerScanning) {
discoveryPreferences = routerRecords.stream()
.map(record -> record.mDiscoveryPreference)
.collect(Collectors.toList());
} else {
discoveryPreferences = routerRecords.stream().filter(record ->
service.mActivityManager.getPackageImportance(record.mPackageName)
<= PACKAGE_IMPORTANCE_FOR_DISCOVERY)
.map(record -> record.mDiscoveryPreference)
.collect(Collectors.toList());
}
}