From 50814321c03a295ba9688cea180d6b4aa9040da1 Mon Sep 17 00:00:00 2001 From: Kyunglyul Hyun Date: Tue, 6 Apr 2021 16:50:58 +0000 Subject: [PATCH] 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 --- .../server/media/MediaRouter2ServiceImpl.java | 60 +++++++++++++++---- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 31edf43679e90..981b511dde2a5 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -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 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 discoveryPreferences = new ArrayList<>(); + List discoveryPreferences = Collections.emptyList(); List routerRecords = getRouterRecords(); List 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()); } }