• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.media;
18 
19 import android.annotation.NonNull;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.PackageManagerInternal;
25 import android.content.pm.ResolveInfo;
26 import android.os.Binder;
27 import android.os.Process;
28 import android.os.UserHandle;
29 import android.text.TextUtils;
30 
31 import com.android.server.LocalServices;
32 
33 import java.io.PrintWriter;
34 import java.util.Arrays;
35 import java.util.List;
36 
37 /** Util class for media server. */
38 /* package */ class MediaServerUtils {
39 
40     /**
41      * Returns whether the provided {@link ComponentName} and {@code action} resolve to a valid
42      * activity for the user defined by {@code userHandle}.
43      */
isValidActivityComponentName( @onNull Context context, @NonNull ComponentName componentName, @NonNull String action, @NonNull UserHandle userHandle)44     public static boolean isValidActivityComponentName(
45             @NonNull Context context,
46             @NonNull ComponentName componentName,
47             @NonNull String action,
48             @NonNull UserHandle userHandle) {
49         Intent intent = new Intent(action);
50         intent.setComponent(componentName);
51         List<ResolveInfo> resolveInfos =
52                 context.getPackageManager()
53                         .queryIntentActivitiesAsUser(intent, /* flags= */ 0, userHandle);
54         return !resolveInfos.isEmpty();
55     }
56 
57     /**
58      * Throws if the given {@code packageName} does not correspond to the given {@code uid}.
59      *
60      * <p>This method trusts calls from {@link Process#ROOT_UID} and {@link Process#SHELL_UID}.
61      *
62      * @param packageName A package name to verify (usually sent over binder by an app).
63      * @param uid The calling uid, obtained via {@link Binder#getCallingUid()}.
64      * @throws IllegalArgumentException If the given {@code packageName} does not correspond to the
65      *     given {@code uid}, and {@code uid} is not the root uid, or the shell uid.
66      */
enforcePackageName( @onNull Context context, @NonNull String packageName, int uid)67     public static void enforcePackageName(
68             @NonNull Context context, @NonNull String packageName, int uid) {
69         if (uid == Process.ROOT_UID || uid == Process.SHELL_UID) {
70             return;
71         }
72         if (TextUtils.isEmpty(packageName)) {
73             throw new IllegalArgumentException("packageName may not be empty");
74         }
75         final PackageManagerInternal packageManagerInternal =
76                 LocalServices.getService(PackageManagerInternal.class);
77         if (!packageManagerInternal.isSameApp(packageName, uid, UserHandle.getUserId(uid))) {
78             String[] uidPackages = context.getPackageManager().getPackagesForUid(uid);
79             throw new IllegalArgumentException(
80                     "packageName does not belong to the calling uid; "
81                             + "pkg="
82                             + packageName
83                             + ", uid="
84                             + uid
85                             + " ("
86                             + Arrays.toString(uidPackages)
87                             + ")");
88         }
89     }
90 
91     /**
92      * Verify that caller holds {@link android.Manifest.permission#DUMP}.
93      */
checkDumpPermission(Context context, String tag, PrintWriter pw)94     public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
95         if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
96                 != PackageManager.PERMISSION_GRANTED) {
97             pw.println("Permission Denial: can't dump " + tag + " from from pid="
98                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
99                     + " due to missing android.permission.DUMP permission");
100             return false;
101         } else {
102             return true;
103         }
104     }
105 }
106