1 /* 2 * Copyright (C) 2024 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.helpers; 18 19 import android.annotation.NonNull; 20 import android.content.Context; 21 import android.content.pm.ApplicationInfo; 22 import android.content.pm.PackageManager; 23 import android.content.pm.SharedLibraryInfo; 24 import android.os.UserHandle; 25 import android.util.Log; 26 27 import java.util.List; 28 import java.util.stream.Collectors; 29 30 /** 31 * Helper class for operations involving {@link PackageManager} 32 * 33 * @hide 34 */ 35 public class PackageManagerHelper { 36 private static final String TAG = "SdkSandboxManager"; 37 private final PackageManager mPackageManager; 38 PackageManagerHelper(Context context, int callingUid)39 public PackageManagerHelper(Context context, int callingUid) { 40 UserHandle userHandle = UserHandle.getUserHandleForUid(callingUid); 41 Context userContext = context.createContextAsUser(userHandle, /* flags= */ 0); 42 mPackageManager = userContext.getPackageManager(); 43 } 44 45 /** Returns {@link SharedLibraryInfo} object for the SDK belonging to the package */ 46 @NonNull getSdkSharedLibraryInfoForSdk( @onNull String packageName, @NonNull String sdkName)47 public SharedLibraryInfo getSdkSharedLibraryInfoForSdk( 48 @NonNull String packageName, @NonNull String sdkName) 49 throws PackageManager.NameNotFoundException { 50 List<SharedLibraryInfo> sharedLibraryInfos = getSdkSharedLibraryInfo(packageName); 51 sharedLibraryInfos = 52 sharedLibraryInfos.stream() 53 .filter(sharedLibraryInfo -> sharedLibraryInfo.getName().equals(sdkName)) 54 .collect(Collectors.toList()); 55 56 if (sharedLibraryInfos.size() == 0) { 57 throw new PackageManager.NameNotFoundException(sdkName); 58 } 59 return sharedLibraryInfos.get(0); 60 } 61 62 /** 63 * Returns a list of {@link SharedLibraryInfo} object for all the SDKs belonging to the package 64 */ 65 @NonNull getSdkSharedLibraryInfo(@onNull String packageName)66 public List<SharedLibraryInfo> getSdkSharedLibraryInfo(@NonNull String packageName) 67 throws PackageManager.NameNotFoundException { 68 ApplicationInfo info = 69 mPackageManager.getApplicationInfo( 70 packageName, 71 PackageManager.ApplicationInfoFlags.of( 72 PackageManager.GET_SHARED_LIBRARY_FILES)); 73 74 return info.getSharedLibraryInfos().stream() 75 .filter( 76 sharedLibraryInfo -> 77 (sharedLibraryInfo.getType() == SharedLibraryInfo.TYPE_SDK_PACKAGE)) 78 .collect(Collectors.toList()); 79 } 80 81 /** Returns {@link PackageManager.Property} object of the propertyName for the package */ 82 @NonNull getProperty( @onNull String propertyName, @NonNull String packageName)83 public PackageManager.Property getProperty( 84 @NonNull String propertyName, @NonNull String packageName) 85 throws PackageManager.NameNotFoundException { 86 return mPackageManager.getProperty(propertyName, packageName); 87 } 88 89 /** Returns {@link ApplicationInfo} for the {@link SharedLibraryInfo} with certain flags */ 90 @NonNull getApplicationInfoForSharedLibrary( @onNull SharedLibraryInfo sharedLibrary, int flags)91 public ApplicationInfo getApplicationInfoForSharedLibrary( 92 @NonNull SharedLibraryInfo sharedLibrary, int flags) 93 throws PackageManager.NameNotFoundException { 94 return mPackageManager.getPackageInfo(sharedLibrary.getDeclaringPackage(), flags) 95 .applicationInfo; 96 } 97 98 /** Returns the packageNames for the UID */ 99 @NonNull getPackageNamesForUid(int callingUid)100 public List<String> getPackageNamesForUid(int callingUid) 101 throws PackageManager.NameNotFoundException { 102 String[] possibleAppPackages = mPackageManager.getPackagesForUid(callingUid); 103 104 if (possibleAppPackages == null || possibleAppPackages.length == 0) { 105 throw new PackageManager.NameNotFoundException( 106 "Could not find package for " + callingUid); 107 } 108 if (possibleAppPackages.length > 1) { 109 Log.d( 110 TAG, 111 "More than one package name available for UID " 112 + callingUid 113 + ". Count: " 114 + possibleAppPackages.length); 115 } 116 return List.of(possibleAppPackages); 117 } 118 } 119