Loading core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -24326,15 +24326,19 @@ package android.media { public final class RouteListingPreference implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.content.ComponentName getInAppOnlyItemRoutingReceiver(); method @NonNull public java.util.List<android.media.RouteListingPreference.Item> getItems(); method public boolean getUseSystemOrdering(); method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA"; field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference> CREATOR; field public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID"; } public static final class RouteListingPreference.Builder { ctor public RouteListingPreference.Builder(); method @NonNull public android.media.RouteListingPreference build(); method @NonNull public android.media.RouteListingPreference.Builder setInAppOnlyItemRoutingReceiver(@Nullable android.content.ComponentName); method @NonNull public android.media.RouteListingPreference.Builder setItems(@NonNull java.util.List<android.media.RouteListingPreference.Item>); method @NonNull public android.media.RouteListingPreference.Builder setUseSystemOrdering(boolean); } Loading @@ -24349,6 +24353,7 @@ package android.media { field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference.Item> CREATOR; field public static final int DISABLE_REASON_AD = 3; // 0x3 field public static final int DISABLE_REASON_DOWNLOADED_CONTENT = 2; // 0x2 field public static final int DISABLE_REASON_IN_APP_ONLY = 4; // 0x4 field public static final int DISABLE_REASON_NONE = 0; // 0x0 field public static final int DISABLE_REASON_SUBSCRIPTION_REQUIRED = 1; // 0x1 field public static final int FLAG_ONGOING_SESSION = 1; // 0x1 media/java/android/media/RouteListingPreference.java +68 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package android.media; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; Loading @@ -40,6 +43,18 @@ import java.util.Objects; */ public final class RouteListingPreference implements Parcelable { /** * {@link Intent} action for apps to take the user to a screen for transferring media playback * to the route with the id provided by the extra with key {@link #EXTRA_ROUTE_ID}. */ public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA"; /** * {@link Intent} string extra key that contains the {@link Item#getRouteId() id} of the route * to transfer to, as part of an {@link #ACTION_TRANSFER_MEDIA} intent. */ public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID"; @NonNull public static final Creator<RouteListingPreference> CREATOR = new Creator<>() { Loading @@ -56,10 +71,12 @@ public final class RouteListingPreference implements Parcelable { @NonNull private final List<Item> mItems; private final boolean mUseSystemOrdering; @Nullable private final ComponentName mInAppOnlyItemRoutingReceiver; private RouteListingPreference(Builder builder) { mItems = builder.mItems; mUseSystemOrdering = builder.mUseSystemOrdering; mInAppOnlyItemRoutingReceiver = builder.mInAppOnlyItemRoutingReceiver; } private RouteListingPreference(Parcel in) { Loading @@ -67,6 +84,7 @@ public final class RouteListingPreference implements Parcelable { in.readParcelableList(new ArrayList<>(), Item.class.getClassLoader(), Item.class); mItems = List.copyOf(items); mUseSystemOrdering = in.readBoolean(); mInAppOnlyItemRoutingReceiver = ComponentName.readFromParcel(in); } /** Loading @@ -90,6 +108,21 @@ public final class RouteListingPreference implements Parcelable { return mUseSystemOrdering; } /** * Returns a {@link ComponentName} for handling routes disabled via {@link * Item#DISABLE_REASON_IN_APP_ONLY}, or null if the user needs to manually navigate to the app * in order to route to select the corresponding routes. * * <p>If the user selects an {@link Item} disabled via {@link Item#DISABLE_REASON_IN_APP_ONLY}, * and this method returns a non-null {@link ComponentName}, the system takes the user back to * the app by launching an intent to the returned {@link ComponentName}, using action {@link * #ACTION_TRANSFER_MEDIA}, with the extra {@link #EXTRA_ROUTE_ID}. */ @Nullable public ComponentName getInAppOnlyItemRoutingReceiver() { return mInAppOnlyItemRoutingReceiver; } // RouteListingPreference Parcelable implementation. @Override Loading @@ -101,6 +134,7 @@ public final class RouteListingPreference implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelableList(mItems, flags); dest.writeBoolean(mUseSystemOrdering); ComponentName.writeToParcel(mInAppOnlyItemRoutingReceiver, dest); } // Equals and hashCode. Loading @@ -114,12 +148,15 @@ public final class RouteListingPreference implements Parcelable { return false; } RouteListingPreference that = (RouteListingPreference) other; return mItems.equals(that.mItems) && mUseSystemOrdering == that.mUseSystemOrdering; return mItems.equals(that.mItems) && mUseSystemOrdering == that.mUseSystemOrdering && Objects.equals( mInAppOnlyItemRoutingReceiver, that.mInAppOnlyItemRoutingReceiver); } @Override public int hashCode() { return Objects.hash(mItems, mUseSystemOrdering); return Objects.hash(mItems, mUseSystemOrdering, mInAppOnlyItemRoutingReceiver); } /** Builder for {@link RouteListingPreference}. */ Loading @@ -127,6 +164,7 @@ public final class RouteListingPreference implements Parcelable { private List<Item> mItems; private boolean mUseSystemOrdering; private ComponentName mInAppOnlyItemRoutingReceiver; /** Creates a new instance with default values (documented in the setters). */ public Builder() { Loading Loading @@ -158,6 +196,18 @@ public final class RouteListingPreference implements Parcelable { return this; } /** * See {@link #getInAppOnlyItemRoutingReceiver()}. * * <p>The default value is {@code null}. */ @NonNull public Builder setInAppOnlyItemRoutingReceiver( @Nullable ComponentName inAppOnlyItemRoutingReceiver) { mInAppOnlyItemRoutingReceiver = inAppOnlyItemRoutingReceiver; return this; } /** * Creates and returns a new {@link RouteListingPreference} instance with the given * parameters. Loading Loading @@ -203,7 +253,8 @@ public final class RouteListingPreference implements Parcelable { DISABLE_REASON_NONE, DISABLE_REASON_SUBSCRIPTION_REQUIRED, DISABLE_REASON_DOWNLOADED_CONTENT, DISABLE_REASON_AD DISABLE_REASON_AD, DISABLE_REASON_IN_APP_ONLY }) public @interface DisableReason {} Loading @@ -221,6 +272,14 @@ public final class RouteListingPreference implements Parcelable { public static final int DISABLE_REASON_DOWNLOADED_CONTENT = 2; /** The corresponding route is not available because an ad is in progress. */ public static final int DISABLE_REASON_AD = 3; /** * The corresponding route is only available for routing from within the app. * * <p>The user may still select the corresponding route if the app provides an {@link * #getInAppOnlyItemRoutingReceiver() in-app routing receiver}, in which case the system * will take the user to the app. */ public static final int DISABLE_REASON_IN_APP_ONLY = 4; @NonNull public static final Creator<Item> CREATOR = Loading Loading @@ -257,7 +316,11 @@ public final class RouteListingPreference implements Parcelable { Preconditions.checkArgument(mSessionParticipantCount >= 0); } /** Returns the id of the route that corresponds to this route listing preference item. */ /** * Returns the id of the route that corresponds to this route listing preference item. * * @see MediaRoute2Info#getId() */ @NonNull public String getRouteId() { return mRouteId; Loading @@ -282,6 +345,7 @@ public final class RouteListingPreference implements Parcelable { * @see #DISABLE_REASON_SUBSCRIPTION_REQUIRED * @see #DISABLE_REASON_DOWNLOADED_CONTENT * @see #DISABLE_REASON_AD * @see #DISABLE_REASON_IN_APP_ONLY */ @DisableReason public int getDisableReason() { Loading services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +16 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading Loading @@ -285,6 +286,15 @@ class MediaRouter2ServiceImpl { public void setRouteListingPreference( @NonNull IMediaRouter2 router, @Nullable RouteListingPreference routeListingPreference) { ComponentName inAppOnlyItemRoutingReceiver = routeListingPreference != null ? routeListingPreference.getInAppOnlyItemRoutingReceiver() : null; if (inAppOnlyItemRoutingReceiver != null) { MediaServerUtils.enforcePackageName( inAppOnlyItemRoutingReceiver.getPackageName(), Binder.getCallingUid()); } final long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { Loading Loading @@ -787,6 +797,12 @@ class MediaRouter2ServiceImpl { obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManagers, routerRecord.mUserRecord.mHandler, routerRecord.mPackageName, null)); routerRecord.mUserRecord.mHandler.sendMessage( obtainMessage( UserHandler::notifyRouteListingPreferenceChangeToManagers, routerRecord.mUserRecord.mHandler, routerRecord.mPackageName, /* routeListingPreference= */ null)); userRecord.mHandler.sendMessage( obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler, userRecord.mHandler)); Loading services/core/java/com/android/server/media/MediaServerUtils.java +39 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,13 @@ package com.android.server.media; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; import com.android.server.LocalServices; import java.io.PrintWriter; Loading @@ -26,6 +32,39 @@ import java.io.PrintWriter; * Util class for media server. */ class MediaServerUtils { /** * Throws if the given {@code packageName} does not correspond to the given {@code uid}. * * <p>This method trusts calls from {@link Process#ROOT_UID} and {@link Process#SHELL_UID}. * * @param packageName A package name to verify (usually sent over binder by an app). * @param uid The calling uid, obtained via {@link Binder#getCallingUid()}. * @throws IllegalArgumentException If the given {@code packageName} does not correspond to the * given {@code uid}, and {@code uid} is not the root uid, or the shell uid. */ public static void enforcePackageName(String packageName, int uid) { if (uid == Process.ROOT_UID || uid == Process.SHELL_UID) { return; } if (TextUtils.isEmpty(packageName)) { throw new IllegalArgumentException("packageName may not be empty"); } final PackageManagerInternal packageManagerInternal = LocalServices.getService(PackageManagerInternal.class); final int actualUid = packageManagerInternal.getPackageUid( packageName, 0 /* flags */, UserHandle.getUserId(uid)); if (!UserHandle.isSameApp(uid, actualUid)) { throw new IllegalArgumentException( "packageName does not belong to the calling uid; " + "pkg=" + packageName + ", uid=" + uid); } } /** * Verify that caller holds {@link android.Manifest.permission#DUMP}. */ Loading services/core/java/com/android/server/media/MediaSessionService.java +6 −25 Original line number Diff line number Diff line Loading @@ -538,30 +538,11 @@ public class MediaSessionService extends SystemService implements Monitor { mHandler.postSessionsChanged(session); } private void enforcePackageName(String packageName, int uid) { if (TextUtils.isEmpty(packageName)) { throw new IllegalArgumentException("packageName may not be empty"); } if (uid == Process.ROOT_UID || uid == Process.SHELL_UID) { // If the caller is shell, then trust the packageName given and allow it // to proceed. return; } final PackageManagerInternal packageManagerInternal = LocalServices.getService(PackageManagerInternal.class); final int actualUid = packageManagerInternal.getPackageUid( packageName, 0 /* flags */, UserHandle.getUserId(uid)); if (!UserHandle.isSameApp(uid, actualUid)) { throw new IllegalArgumentException("packageName does not belong to the calling uid; " + "pkg=" + packageName + ", uid=" + uid); } } void tempAllowlistTargetPkgIfPossible(int targetUid, String targetPackage, int callingPid, int callingUid, String callingPackage, String reason) { final long token = Binder.clearCallingIdentity(); try { enforcePackageName(callingPackage, callingUid); MediaServerUtils.enforcePackageName(callingPackage, callingUid); if (targetUid != callingUid) { boolean canAllowWhileInUse = mActivityManagerLocal .canAllowWhileInUsePermissionInFgs(callingPid, callingUid, callingPackage); Loading Loading @@ -1206,7 +1187,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); int resolvedUserId = handleIncomingUser(pid, uid, userId, packageName); if (cb == null) { throw new IllegalArgumentException("Controller callback cannot be null"); Loading Loading @@ -1258,7 +1239,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int userId = userHandle.getIdentifier(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); enforceMediaPermissions(packageName, pid, uid, userId); MediaSessionRecordImpl record; Loading Loading @@ -1289,7 +1270,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int userId = userHandle.getIdentifier(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); enforceMediaPermissions(packageName, pid, uid, userId); MediaSessionRecordImpl record; Loading Loading @@ -1615,7 +1596,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int userId = userHandle.getIdentifier(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); enforceMediaPermissions(packageName, pid, uid, userId); synchronized (mLock) { Loading Loading @@ -2129,7 +2110,7 @@ public class MediaSessionService extends SystemService implements Monitor { // If they gave us a component name verify they own the // package packageName = componentName.getPackageName(); enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); } // Check that they can make calls on behalf of the user and get the final user id int resolvedUserId = handleIncomingUser(pid, uid, userId, packageName); Loading Loading
core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -24326,15 +24326,19 @@ package android.media { public final class RouteListingPreference implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.content.ComponentName getInAppOnlyItemRoutingReceiver(); method @NonNull public java.util.List<android.media.RouteListingPreference.Item> getItems(); method public boolean getUseSystemOrdering(); method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA"; field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference> CREATOR; field public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID"; } public static final class RouteListingPreference.Builder { ctor public RouteListingPreference.Builder(); method @NonNull public android.media.RouteListingPreference build(); method @NonNull public android.media.RouteListingPreference.Builder setInAppOnlyItemRoutingReceiver(@Nullable android.content.ComponentName); method @NonNull public android.media.RouteListingPreference.Builder setItems(@NonNull java.util.List<android.media.RouteListingPreference.Item>); method @NonNull public android.media.RouteListingPreference.Builder setUseSystemOrdering(boolean); } Loading @@ -24349,6 +24353,7 @@ package android.media { field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference.Item> CREATOR; field public static final int DISABLE_REASON_AD = 3; // 0x3 field public static final int DISABLE_REASON_DOWNLOADED_CONTENT = 2; // 0x2 field public static final int DISABLE_REASON_IN_APP_ONLY = 4; // 0x4 field public static final int DISABLE_REASON_NONE = 0; // 0x0 field public static final int DISABLE_REASON_SUBSCRIPTION_REQUIRED = 1; // 0x1 field public static final int FLAG_ONGOING_SESSION = 1; // 0x1
media/java/android/media/RouteListingPreference.java +68 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package android.media; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; Loading @@ -40,6 +43,18 @@ import java.util.Objects; */ public final class RouteListingPreference implements Parcelable { /** * {@link Intent} action for apps to take the user to a screen for transferring media playback * to the route with the id provided by the extra with key {@link #EXTRA_ROUTE_ID}. */ public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA"; /** * {@link Intent} string extra key that contains the {@link Item#getRouteId() id} of the route * to transfer to, as part of an {@link #ACTION_TRANSFER_MEDIA} intent. */ public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID"; @NonNull public static final Creator<RouteListingPreference> CREATOR = new Creator<>() { Loading @@ -56,10 +71,12 @@ public final class RouteListingPreference implements Parcelable { @NonNull private final List<Item> mItems; private final boolean mUseSystemOrdering; @Nullable private final ComponentName mInAppOnlyItemRoutingReceiver; private RouteListingPreference(Builder builder) { mItems = builder.mItems; mUseSystemOrdering = builder.mUseSystemOrdering; mInAppOnlyItemRoutingReceiver = builder.mInAppOnlyItemRoutingReceiver; } private RouteListingPreference(Parcel in) { Loading @@ -67,6 +84,7 @@ public final class RouteListingPreference implements Parcelable { in.readParcelableList(new ArrayList<>(), Item.class.getClassLoader(), Item.class); mItems = List.copyOf(items); mUseSystemOrdering = in.readBoolean(); mInAppOnlyItemRoutingReceiver = ComponentName.readFromParcel(in); } /** Loading @@ -90,6 +108,21 @@ public final class RouteListingPreference implements Parcelable { return mUseSystemOrdering; } /** * Returns a {@link ComponentName} for handling routes disabled via {@link * Item#DISABLE_REASON_IN_APP_ONLY}, or null if the user needs to manually navigate to the app * in order to route to select the corresponding routes. * * <p>If the user selects an {@link Item} disabled via {@link Item#DISABLE_REASON_IN_APP_ONLY}, * and this method returns a non-null {@link ComponentName}, the system takes the user back to * the app by launching an intent to the returned {@link ComponentName}, using action {@link * #ACTION_TRANSFER_MEDIA}, with the extra {@link #EXTRA_ROUTE_ID}. */ @Nullable public ComponentName getInAppOnlyItemRoutingReceiver() { return mInAppOnlyItemRoutingReceiver; } // RouteListingPreference Parcelable implementation. @Override Loading @@ -101,6 +134,7 @@ public final class RouteListingPreference implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelableList(mItems, flags); dest.writeBoolean(mUseSystemOrdering); ComponentName.writeToParcel(mInAppOnlyItemRoutingReceiver, dest); } // Equals and hashCode. Loading @@ -114,12 +148,15 @@ public final class RouteListingPreference implements Parcelable { return false; } RouteListingPreference that = (RouteListingPreference) other; return mItems.equals(that.mItems) && mUseSystemOrdering == that.mUseSystemOrdering; return mItems.equals(that.mItems) && mUseSystemOrdering == that.mUseSystemOrdering && Objects.equals( mInAppOnlyItemRoutingReceiver, that.mInAppOnlyItemRoutingReceiver); } @Override public int hashCode() { return Objects.hash(mItems, mUseSystemOrdering); return Objects.hash(mItems, mUseSystemOrdering, mInAppOnlyItemRoutingReceiver); } /** Builder for {@link RouteListingPreference}. */ Loading @@ -127,6 +164,7 @@ public final class RouteListingPreference implements Parcelable { private List<Item> mItems; private boolean mUseSystemOrdering; private ComponentName mInAppOnlyItemRoutingReceiver; /** Creates a new instance with default values (documented in the setters). */ public Builder() { Loading Loading @@ -158,6 +196,18 @@ public final class RouteListingPreference implements Parcelable { return this; } /** * See {@link #getInAppOnlyItemRoutingReceiver()}. * * <p>The default value is {@code null}. */ @NonNull public Builder setInAppOnlyItemRoutingReceiver( @Nullable ComponentName inAppOnlyItemRoutingReceiver) { mInAppOnlyItemRoutingReceiver = inAppOnlyItemRoutingReceiver; return this; } /** * Creates and returns a new {@link RouteListingPreference} instance with the given * parameters. Loading Loading @@ -203,7 +253,8 @@ public final class RouteListingPreference implements Parcelable { DISABLE_REASON_NONE, DISABLE_REASON_SUBSCRIPTION_REQUIRED, DISABLE_REASON_DOWNLOADED_CONTENT, DISABLE_REASON_AD DISABLE_REASON_AD, DISABLE_REASON_IN_APP_ONLY }) public @interface DisableReason {} Loading @@ -221,6 +272,14 @@ public final class RouteListingPreference implements Parcelable { public static final int DISABLE_REASON_DOWNLOADED_CONTENT = 2; /** The corresponding route is not available because an ad is in progress. */ public static final int DISABLE_REASON_AD = 3; /** * The corresponding route is only available for routing from within the app. * * <p>The user may still select the corresponding route if the app provides an {@link * #getInAppOnlyItemRoutingReceiver() in-app routing receiver}, in which case the system * will take the user to the app. */ public static final int DISABLE_REASON_IN_APP_ONLY = 4; @NonNull public static final Creator<Item> CREATOR = Loading Loading @@ -257,7 +316,11 @@ public final class RouteListingPreference implements Parcelable { Preconditions.checkArgument(mSessionParticipantCount >= 0); } /** Returns the id of the route that corresponds to this route listing preference item. */ /** * Returns the id of the route that corresponds to this route listing preference item. * * @see MediaRoute2Info#getId() */ @NonNull public String getRouteId() { return mRouteId; Loading @@ -282,6 +345,7 @@ public final class RouteListingPreference implements Parcelable { * @see #DISABLE_REASON_SUBSCRIPTION_REQUIRED * @see #DISABLE_REASON_DOWNLOADED_CONTENT * @see #DISABLE_REASON_AD * @see #DISABLE_REASON_IN_APP_ONLY */ @DisableReason public int getDisableReason() { Loading
services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +16 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading Loading @@ -285,6 +286,15 @@ class MediaRouter2ServiceImpl { public void setRouteListingPreference( @NonNull IMediaRouter2 router, @Nullable RouteListingPreference routeListingPreference) { ComponentName inAppOnlyItemRoutingReceiver = routeListingPreference != null ? routeListingPreference.getInAppOnlyItemRoutingReceiver() : null; if (inAppOnlyItemRoutingReceiver != null) { MediaServerUtils.enforcePackageName( inAppOnlyItemRoutingReceiver.getPackageName(), Binder.getCallingUid()); } final long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { Loading Loading @@ -787,6 +797,12 @@ class MediaRouter2ServiceImpl { obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManagers, routerRecord.mUserRecord.mHandler, routerRecord.mPackageName, null)); routerRecord.mUserRecord.mHandler.sendMessage( obtainMessage( UserHandler::notifyRouteListingPreferenceChangeToManagers, routerRecord.mUserRecord.mHandler, routerRecord.mPackageName, /* routeListingPreference= */ null)); userRecord.mHandler.sendMessage( obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler, userRecord.mHandler)); Loading
services/core/java/com/android/server/media/MediaServerUtils.java +39 −0 Original line number Diff line number Diff line Loading @@ -18,7 +18,13 @@ package com.android.server.media; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; import com.android.server.LocalServices; import java.io.PrintWriter; Loading @@ -26,6 +32,39 @@ import java.io.PrintWriter; * Util class for media server. */ class MediaServerUtils { /** * Throws if the given {@code packageName} does not correspond to the given {@code uid}. * * <p>This method trusts calls from {@link Process#ROOT_UID} and {@link Process#SHELL_UID}. * * @param packageName A package name to verify (usually sent over binder by an app). * @param uid The calling uid, obtained via {@link Binder#getCallingUid()}. * @throws IllegalArgumentException If the given {@code packageName} does not correspond to the * given {@code uid}, and {@code uid} is not the root uid, or the shell uid. */ public static void enforcePackageName(String packageName, int uid) { if (uid == Process.ROOT_UID || uid == Process.SHELL_UID) { return; } if (TextUtils.isEmpty(packageName)) { throw new IllegalArgumentException("packageName may not be empty"); } final PackageManagerInternal packageManagerInternal = LocalServices.getService(PackageManagerInternal.class); final int actualUid = packageManagerInternal.getPackageUid( packageName, 0 /* flags */, UserHandle.getUserId(uid)); if (!UserHandle.isSameApp(uid, actualUid)) { throw new IllegalArgumentException( "packageName does not belong to the calling uid; " + "pkg=" + packageName + ", uid=" + uid); } } /** * Verify that caller holds {@link android.Manifest.permission#DUMP}. */ Loading
services/core/java/com/android/server/media/MediaSessionService.java +6 −25 Original line number Diff line number Diff line Loading @@ -538,30 +538,11 @@ public class MediaSessionService extends SystemService implements Monitor { mHandler.postSessionsChanged(session); } private void enforcePackageName(String packageName, int uid) { if (TextUtils.isEmpty(packageName)) { throw new IllegalArgumentException("packageName may not be empty"); } if (uid == Process.ROOT_UID || uid == Process.SHELL_UID) { // If the caller is shell, then trust the packageName given and allow it // to proceed. return; } final PackageManagerInternal packageManagerInternal = LocalServices.getService(PackageManagerInternal.class); final int actualUid = packageManagerInternal.getPackageUid( packageName, 0 /* flags */, UserHandle.getUserId(uid)); if (!UserHandle.isSameApp(uid, actualUid)) { throw new IllegalArgumentException("packageName does not belong to the calling uid; " + "pkg=" + packageName + ", uid=" + uid); } } void tempAllowlistTargetPkgIfPossible(int targetUid, String targetPackage, int callingPid, int callingUid, String callingPackage, String reason) { final long token = Binder.clearCallingIdentity(); try { enforcePackageName(callingPackage, callingUid); MediaServerUtils.enforcePackageName(callingPackage, callingUid); if (targetUid != callingUid) { boolean canAllowWhileInUse = mActivityManagerLocal .canAllowWhileInUsePermissionInFgs(callingPid, callingUid, callingPackage); Loading Loading @@ -1206,7 +1187,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); int resolvedUserId = handleIncomingUser(pid, uid, userId, packageName); if (cb == null) { throw new IllegalArgumentException("Controller callback cannot be null"); Loading Loading @@ -1258,7 +1239,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int userId = userHandle.getIdentifier(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); enforceMediaPermissions(packageName, pid, uid, userId); MediaSessionRecordImpl record; Loading Loading @@ -1289,7 +1270,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int userId = userHandle.getIdentifier(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); enforceMediaPermissions(packageName, pid, uid, userId); MediaSessionRecordImpl record; Loading Loading @@ -1615,7 +1596,7 @@ public class MediaSessionService extends SystemService implements Monitor { final int userId = userHandle.getIdentifier(); final long token = Binder.clearCallingIdentity(); try { enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); enforceMediaPermissions(packageName, pid, uid, userId); synchronized (mLock) { Loading Loading @@ -2129,7 +2110,7 @@ public class MediaSessionService extends SystemService implements Monitor { // If they gave us a component name verify they own the // package packageName = componentName.getPackageName(); enforcePackageName(packageName, uid); MediaServerUtils.enforcePackageName(packageName, uid); } // Check that they can make calls on behalf of the user and get the final user id int resolvedUserId = handleIncomingUser(pid, uid, userId, packageName); Loading