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