Apply delivery group policies to SERVICE_STATE broadcast.

- The "set-defer-until-active" policy is applied so that the
broadcast targeted to apps in the Cached state is deferred until
they come out of that state.
- The "deliver-most-recent" policy is applied so that if there are
already pending broadcasts waiting to be delivered when a new
broadcast is sent, the old ones are discarded.

Bug: 255527697
Test: TH
Change-Id: If698166cda15b3984047e7b7e328b774a46dfed6
This commit is contained in:
Sudheer Shanka
2023-03-08 10:39:51 +00:00
parent 8348312f8b
commit 1895a83c01
4 changed files with 50 additions and 13 deletions

View File

@@ -1299,7 +1299,7 @@ class ContextImpl extends Context {
@Override
public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
String[] excludedPermissions, String[] excludedPackages) {
String[] excludedPermissions, String[] excludedPackages, BroadcastOptions options) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
@@ -1307,7 +1307,8 @@ class ContextImpl extends Context {
ActivityManager.getService().broadcastIntentWithFeature(
mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
null, Activity.RESULT_OK, null, null, receiverPermissions, excludedPermissions,
excludedPackages, AppOpsManager.OP_NONE, null, false, false, getUserId());
excludedPackages, AppOpsManager.OP_NONE,
options == null ? null : options.toBundle(), false, false, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -2399,7 +2399,6 @@ public abstract class Context {
sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions, null);
}
/**
* Like {@link #sendBroadcastMultiplePermissions(Intent, String[], String[])}, but also allows
* specification of a list of excluded packages.
@@ -2409,6 +2408,19 @@ public abstract class Context {
public void sendBroadcastMultiplePermissions(@NonNull Intent intent,
@NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions,
@Nullable String[] excludedPackages) {
sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions,
excludedPackages, null);
}
/**
* Like {@link #sendBroadcastMultiplePermissions(Intent, String[], String[], String[])}, but
* also allows specification of options generated from {@link android.app.BroadcastOptions}.
*
* @hide
*/
public void sendBroadcastMultiplePermissions(@NonNull Intent intent,
@NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions,
@Nullable String[] excludedPackages, @Nullable BroadcastOptions options) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}

View File

@@ -24,6 +24,7 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UiContext;
import android.app.BroadcastOptions;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.app.compat.CompatChanges;
@@ -519,9 +520,9 @@ public class ContextWrapper extends Context {
@Override
public void sendBroadcastMultiplePermissions(@NonNull Intent intent,
@NonNull String[] receiverPermissions, @Nullable String[] excludedPermissions,
@Nullable String[] excludedPackages) {
@Nullable String[] excludedPackages, @Nullable BroadcastOptions options) {
mBase.sendBroadcastMultiplePermissions(intent, receiverPermissions, excludedPermissions,
excludedPackages);
excludedPackages, options);
}
/** @hide */

View File

@@ -28,6 +28,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
@@ -3533,28 +3534,36 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
// - Sanitized ServiceState sent to all other apps with READ_PHONE_STATE
// - Sanitized ServiceState sent to all other apps with READ_PRIVILEGED_PHONE_STATE but not
// READ_PHONE_STATE
BroadcastOptions options = createServiceStateBroadcastOptions(subId, phoneId);
if (LocationAccessPolicy.isLocationModeEnabled(mContext, mContext.getUserId())) {
Intent fullIntent = createServiceStateIntent(state, subId, phoneId, false);
mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
fullIntent,
new String[]{Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION});
Manifest.permission.ACCESS_FINE_LOCATION},
options);
mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
fullIntent,
new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION},
new String[]{Manifest.permission.READ_PHONE_STATE});
new String[]{Manifest.permission.READ_PHONE_STATE},
null,
options);
Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true);
mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
sanitizedIntent,
new String[]{Manifest.permission.READ_PHONE_STATE},
new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
null,
options);
mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
sanitizedIntent,
new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
new String[]{Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION});
Manifest.permission.ACCESS_FINE_LOCATION},
null,
options);
} else {
String[] locationBypassPackages = Binder.withCleanCallingIdentity(() ->
LocationAccessPolicy.getLocationBypassPackages(mContext));
@@ -3563,11 +3572,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
fullIntent.setPackage(locationBypassPackage);
mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
fullIntent,
new String[]{Manifest.permission.READ_PHONE_STATE});
new String[]{Manifest.permission.READ_PHONE_STATE},
options);
mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
fullIntent,
new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
new String[]{Manifest.permission.READ_PHONE_STATE});
new String[]{Manifest.permission.READ_PHONE_STATE},
null,
options);
}
Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true);
@@ -3575,12 +3587,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
sanitizedIntent,
new String[]{Manifest.permission.READ_PHONE_STATE},
new String[]{/* no excluded permissions */},
locationBypassPackages);
locationBypassPackages,
options);
mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
sanitizedIntent,
new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
new String[]{Manifest.permission.READ_PHONE_STATE},
locationBypassPackages);
locationBypassPackages,
options);
}
}
@@ -3602,6 +3616,15 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
return intent;
}
private BroadcastOptions createServiceStateBroadcastOptions(int subId, int phoneId) {
return new BroadcastOptions()
.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
// Use a combination of subId and phoneId as the key so that older broadcasts
// with same subId and phoneId will get discarded.
.setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE, subId + "-" + phoneId)
.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
}
private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId,
int subId) {
final long ident = Binder.clearCallingIdentity();