1 /* 2 ** 3 ** Copyright 2007, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 package com.android.packageinstaller; 19 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.app.Activity; 23 import android.content.Context; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.PackageInfo; 26 import android.content.pm.PackageManager; 27 import android.content.res.AssetManager; 28 import android.content.res.Resources; 29 import android.graphics.drawable.Drawable; 30 import android.os.UserHandle; 31 import android.util.Log; 32 import android.view.View; 33 import android.widget.ImageView; 34 import android.widget.TextView; 35 36 import java.io.File; 37 38 /** 39 * This is a utility class for defining some utility methods and constants 40 * used in the package installer application. 41 */ 42 public class PackageUtil { 43 private static final String LOG_TAG = PackageUtil.class.getSimpleName(); 44 45 public static final String PREFIX="com.android.packageinstaller."; 46 public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus"; 47 public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo"; 48 public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList"; 49 //intent attribute strings related to uninstall 50 public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName"; 51 52 /** 53 * Utility method to get package information for a given {@link File} 54 */ 55 @Nullable getPackageInfo(Context context, File sourceFile, int flags)56 public static PackageInfo getPackageInfo(Context context, File sourceFile, int flags) { 57 try { 58 return context.getPackageManager().getPackageArchiveInfo(sourceFile.getAbsolutePath(), 59 flags); 60 } catch (Exception ignored) { 61 return null; 62 } 63 } 64 initSnippet(View snippetView, CharSequence label, Drawable icon)65 public static View initSnippet(View snippetView, CharSequence label, Drawable icon) { 66 ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon); 67 ((TextView)snippetView.findViewById(R.id.app_name)).setText(label); 68 return snippetView; 69 } 70 71 /** 72 * Utility method to display a snippet of an installed application. 73 * The content view should have been set on context before invoking this method. 74 * appSnippet view should include R.id.app_icon and R.id.app_name 75 * defined on it. 76 * 77 * @param pContext context of package that can load the resources 78 * @param componentInfo ComponentInfo object whose resources are to be loaded 79 * @param snippetView the snippet view 80 */ initSnippetForInstalledApp(Context pContext, ApplicationInfo appInfo, View snippetView)81 public static View initSnippetForInstalledApp(Context pContext, 82 ApplicationInfo appInfo, View snippetView) { 83 return initSnippetForInstalledApp(pContext, appInfo, snippetView, null); 84 } 85 86 /** 87 * Utility method to display a snippet of an installed application. 88 * The content view should have been set on context before invoking this method. 89 * appSnippet view should include R.id.app_icon and R.id.app_name 90 * defined on it. 91 * 92 * @param pContext context of package that can load the resources 93 * @param componentInfo ComponentInfo object whose resources are to be loaded 94 * @param snippetView the snippet view 95 * @param UserHandle user that the app si installed for. 96 */ initSnippetForInstalledApp(Context pContext, ApplicationInfo appInfo, View snippetView, UserHandle user)97 public static View initSnippetForInstalledApp(Context pContext, 98 ApplicationInfo appInfo, View snippetView, UserHandle user) { 99 final PackageManager pm = pContext.getPackageManager(); 100 Drawable icon = appInfo.loadIcon(pm); 101 if (user != null) { 102 icon = pContext.getPackageManager().getUserBadgedIcon(icon, user); 103 } 104 return initSnippet( 105 snippetView, 106 appInfo.loadLabel(pm), 107 icon); 108 } 109 110 static public class AppSnippet { 111 @NonNull public CharSequence label; 112 @Nullable public Drawable icon; AppSnippet(@onNull CharSequence label, @Nullable Drawable icon)113 public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) { 114 this.label = label; 115 this.icon = icon; 116 } 117 } 118 119 /** 120 * Utility method to load application label 121 * 122 * @param pContext context of package that can load the resources 123 * @param appInfo ApplicationInfo object of package whose resources are to be loaded 124 * @param sourceFile File the package is in 125 */ getAppSnippet( Activity pContext, ApplicationInfo appInfo, File sourceFile)126 public static AppSnippet getAppSnippet( 127 Activity pContext, ApplicationInfo appInfo, File sourceFile) { 128 final String archiveFilePath = sourceFile.getAbsolutePath(); 129 Resources pRes = pContext.getResources(); 130 AssetManager assmgr = new AssetManager(); 131 assmgr.addAssetPath(archiveFilePath); 132 Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration()); 133 CharSequence label = null; 134 // Try to load the label from the package's resources. If an app has not explicitly 135 // specified any label, just use the package name. 136 if (appInfo.labelRes != 0) { 137 try { 138 label = res.getText(appInfo.labelRes); 139 } catch (Resources.NotFoundException e) { 140 } 141 } 142 if (label == null) { 143 label = (appInfo.nonLocalizedLabel != null) ? 144 appInfo.nonLocalizedLabel : appInfo.packageName; 145 } 146 Drawable icon = null; 147 // Try to load the icon from the package's resources. If an app has not explicitly 148 // specified any resource, just use the default icon for now. 149 try { 150 if (appInfo.icon != 0) { 151 try { 152 icon = res.getDrawable(appInfo.icon); 153 } catch (Resources.NotFoundException e) { 154 } 155 } 156 if (icon == null) { 157 icon = pContext.getPackageManager().getDefaultActivityIcon(); 158 } 159 } catch (OutOfMemoryError e) { 160 Log.i(LOG_TAG, "Could not load app icon", e); 161 } 162 return new PackageUtil.AppSnippet(label, icon); 163 } 164 165 /** 166 * Get the maximum target sdk for a UID. 167 * 168 * @param context The context to use 169 * @param uid The UID requesting the install/uninstall 170 * 171 * @return The maximum target SDK or -1 if the uid does not match any packages. 172 */ getMaxTargetSdkVersionForUid(@onNull Context context, int uid)173 static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) { 174 PackageManager pm = context.getPackageManager(); 175 final String[] packages = pm.getPackagesForUid(uid); 176 int targetSdkVersion = -1; 177 if (packages != null) { 178 for (String packageName : packages) { 179 try { 180 ApplicationInfo info = pm.getApplicationInfo(packageName, 0); 181 targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion); 182 } catch (PackageManager.NameNotFoundException e) { 183 // Ignore and try the next package 184 } 185 } 186 } 187 return targetSdkVersion; 188 } 189 } 190