• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.sdksandbox;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.content.pm.PackageManager;
22 import android.os.Binder;
23 import android.os.IBinder;
24 import android.os.UserHandle;
25 
26 import java.util.Objects;
27 
28 /**
29  * Representation of a caller for an SDK sandbox.
30  * @hide
31  */
32 public final class CallingInfo {
33 
34     private final int mUid;
35     private final String mPackageName;
36     private final @Nullable IBinder mAppProcessToken;
37 
enforceCallingPackageBelongsToUid( Context context, int uid, String packageName)38     private static void enforceCallingPackageBelongsToUid(
39             Context context, int uid, String packageName) {
40         int packageUid;
41         PackageManager pm =
42                 context.createContextAsUser(UserHandle.getUserHandleForUid(uid), 0)
43                         .getPackageManager();
44         try {
45             packageUid = pm.getPackageUid(packageName, 0);
46         } catch (PackageManager.NameNotFoundException e) {
47             throw new SecurityException(packageName + " not found");
48         }
49         if (packageUid != uid) {
50             throw new SecurityException(packageName + " does not belong to uid " + uid);
51         }
52     }
53 
CallingInfo(int uid, String packageName, @Nullable IBinder processTokenBinder)54     public CallingInfo(int uid, String packageName, @Nullable IBinder processTokenBinder) {
55         mUid = uid;
56         mPackageName = Objects.requireNonNull(packageName);
57         mAppProcessToken = processTokenBinder;
58     }
59 
CallingInfo(int uid, String packageName)60     public CallingInfo(int uid, String packageName) {
61         this(uid, packageName, null);
62     }
63 
fromExternal(Context context, int uid, String packageNameUnchecked)64     static CallingInfo fromExternal(Context context, int uid, String packageNameUnchecked) {
65         enforceCallingPackageBelongsToUid(context, uid, packageNameUnchecked);
66         return new CallingInfo(uid, packageNameUnchecked);
67     }
68 
fromBinder(Context context, String packageNameUnchecked)69     static CallingInfo fromBinder(Context context, String packageNameUnchecked) {
70         return fromBinderWithApplicationThread(context, packageNameUnchecked, null);
71     }
72 
fromBinderWithApplicationThread( Context context, String packageNameUnchecked, @Nullable IBinder callingApplicationThread)73     static CallingInfo fromBinderWithApplicationThread(
74             Context context,
75             String packageNameUnchecked,
76             @Nullable IBinder callingApplicationThread) {
77         final int uid = Binder.getCallingUid();
78         enforceCallingPackageBelongsToUid(context, uid, packageNameUnchecked);
79 
80         return new CallingInfo(uid, packageNameUnchecked, callingApplicationThread);
81     }
82 
getUid()83     public int getUid() {
84         return mUid;
85     }
86 
getAppProcessToken()87     public @Nullable IBinder getAppProcessToken() {
88         return mAppProcessToken;
89     }
90 
getPackageName()91     public String getPackageName() {
92         return mPackageName;
93     }
94 
95     @Override
toString()96     public String toString() {
97         return "CallingInfo{"
98                 + "mUid="
99                 + mUid
100                 + ", mPackageName='"
101                 + mPackageName
102                 + ", mAppProcessToken='"
103                 + mAppProcessToken
104                 + "'}";
105     }
106 
107     @Override
equals(Object o)108     public boolean equals(Object o) {
109         // Note that mApplicationThread is not part of the comparison, because it is not always set,
110         // nor is it necessary to determine whether two instances refer to the same caller.
111         if (this == o) return true;
112         if (!(o instanceof CallingInfo)) return false;
113         CallingInfo that = (CallingInfo) o;
114         return mUid == that.mUid && mPackageName.equals(that.mPackageName);
115     }
116 
117     @Override
hashCode()118     public int hashCode() {
119         return mUid ^ mPackageName.hashCode();
120     }
121 }
122