Home | History | Annotate | Download | only in packageinstaller
      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.app.Activity;
     21 import android.content.Context;
     22 import android.content.pm.ApplicationInfo;
     23 import android.content.pm.PackageManager;
     24 import android.content.pm.PackageParser;
     25 import android.content.pm.PackageParser.PackageParserException;
     26 import android.content.res.AssetManager;
     27 import android.content.res.Resources;
     28 import android.graphics.drawable.Drawable;
     29 import android.os.UserHandle;
     30 import android.support.annotation.NonNull;
     31 import android.support.annotation.Nullable;
     32 import android.util.Log;
     33 import android.view.View;
     34 import android.widget.ImageView;
     35 import android.widget.TextView;
     36 
     37 import java.io.File;
     38 
     39 /**
     40  * This is a utility class for defining some utility methods and constants
     41  * used in the package installer application.
     42  */
     43 public class PackageUtil {
     44     private static final String LOG_TAG = PackageUtil.class.getSimpleName();
     45 
     46     public static final String PREFIX="com.android.packageinstaller.";
     47     public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
     48     public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo";
     49     public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
     50     //intent attribute strings related to uninstall
     51     public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
     52 
     53     /**
     54      * Utility method to get package information for a given {@link File}
     55      */
     56     public static PackageParser.Package getPackageInfo(Context context, File sourceFile) {
     57         final PackageParser parser = new PackageParser();
     58         parser.setCallback(new PackageParser.CallbackImpl(context.getPackageManager()));
     59         try {
     60             return parser.parsePackage(sourceFile, 0);
     61         } catch (PackageParserException e) {
     62             return null;
     63         }
     64     }
     65 
     66     public static View initSnippet(View snippetView, CharSequence label, Drawable icon) {
     67         ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon);
     68         ((TextView)snippetView.findViewById(R.id.app_name)).setText(label);
     69         return snippetView;
     70     }
     71 
     72     /**
     73      * Utility method to display a snippet of an installed application.
     74      * The content view should have been set on context before invoking this method.
     75      * appSnippet view should include R.id.app_icon and R.id.app_name
     76      * defined on it.
     77      *
     78      * @param pContext context of package that can load the resources
     79      * @param componentInfo ComponentInfo object whose resources are to be loaded
     80      * @param snippetView the snippet view
     81      */
     82     public static View initSnippetForInstalledApp(Context pContext,
     83             ApplicationInfo appInfo, View snippetView) {
     84         return initSnippetForInstalledApp(pContext, appInfo, snippetView, null);
     85     }
     86 
     87     /**
     88      * Utility method to display a snippet of an installed application.
     89      * The content view should have been set on context before invoking this method.
     90      * appSnippet view should include R.id.app_icon and R.id.app_name
     91      * defined on it.
     92      *
     93      * @param pContext context of package that can load the resources
     94      * @param componentInfo ComponentInfo object whose resources are to be loaded
     95      * @param snippetView the snippet view
     96      * @param UserHandle user that the app si installed for.
     97      */
     98     public static View initSnippetForInstalledApp(Context pContext,
     99             ApplicationInfo appInfo, View snippetView, UserHandle user) {
    100         final PackageManager pm = pContext.getPackageManager();
    101         Drawable icon = appInfo.loadIcon(pm);
    102         if (user != null) {
    103             icon = pContext.getPackageManager().getUserBadgedIcon(icon, user);
    104         }
    105         return initSnippet(
    106                 snippetView,
    107                 appInfo.loadLabel(pm),
    108                 icon);
    109     }
    110 
    111     /**
    112      * Utility method to display application snippet of a new package.
    113      * The content view should have been set on context before invoking this method.
    114      * appSnippet view should include R.id.app_icon and R.id.app_name
    115      * defined on it.
    116      *
    117      * @param pContext context of package that can load the resources
    118      * @param as The resources to be loaded
    119      * @param snippetId view id of app snippet view
    120      */
    121     @NonNull public static View initSnippetForNewApp(@NonNull Activity pContext,
    122             @NonNull AppSnippet as, int snippetId) {
    123         View appSnippet = pContext.findViewById(snippetId);
    124         if (as.icon != null) {
    125             ((ImageView) appSnippet.findViewById(R.id.app_icon)).setImageDrawable(as.icon);
    126         }
    127         ((TextView)appSnippet.findViewById(R.id.app_name)).setText(as.label);
    128         return appSnippet;
    129     }
    130 
    131     static public class AppSnippet {
    132         @NonNull public CharSequence label;
    133         @Nullable public Drawable icon;
    134         public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
    135             this.label = label;
    136             this.icon = icon;
    137         }
    138     }
    139 
    140     /**
    141      * Utility method to load application label
    142      *
    143      * @param pContext context of package that can load the resources
    144      * @param appInfo ApplicationInfo object of package whose resources are to be loaded
    145      * @param sourceFile File the package is in
    146      */
    147     public static AppSnippet getAppSnippet(
    148             Activity pContext, ApplicationInfo appInfo, File sourceFile) {
    149         final String archiveFilePath = sourceFile.getAbsolutePath();
    150         Resources pRes = pContext.getResources();
    151         AssetManager assmgr = new AssetManager();
    152         assmgr.addAssetPath(archiveFilePath);
    153         Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
    154         CharSequence label = null;
    155         // Try to load the label from the package's resources. If an app has not explicitly
    156         // specified any label, just use the package name.
    157         if (appInfo.labelRes != 0) {
    158             try {
    159                 label = res.getText(appInfo.labelRes);
    160             } catch (Resources.NotFoundException e) {
    161             }
    162         }
    163         if (label == null) {
    164             label = (appInfo.nonLocalizedLabel != null) ?
    165                     appInfo.nonLocalizedLabel : appInfo.packageName;
    166         }
    167         Drawable icon = null;
    168         // Try to load the icon from the package's resources. If an app has not explicitly
    169         // specified any resource, just use the default icon for now.
    170         try {
    171             if (appInfo.icon != 0) {
    172                 try {
    173                     icon = res.getDrawable(appInfo.icon);
    174                 } catch (Resources.NotFoundException e) {
    175                 }
    176             }
    177             if (icon == null) {
    178                 icon = pContext.getPackageManager().getDefaultActivityIcon();
    179             }
    180         } catch (OutOfMemoryError e) {
    181             Log.i(LOG_TAG, "Could not load app icon", e);
    182         }
    183         return new PackageUtil.AppSnippet(label, icon);
    184     }
    185 
    186     /**
    187      * Get the maximum target sdk for a UID.
    188      *
    189      * @param context The context to use
    190      * @param uid The UID requesting the install/uninstall
    191      *
    192      * @return The maximum target SDK or -1 if the uid does not match any packages.
    193      */
    194     static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) {
    195         PackageManager pm = context.getPackageManager();
    196         final String[] packages = pm.getPackagesForUid(uid);
    197         int targetSdkVersion = -1;
    198         if (packages != null) {
    199             for (String packageName : packages) {
    200                 try {
    201                     ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
    202                     targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion);
    203                 } catch (PackageManager.NameNotFoundException e) {
    204                     // Ignore and try the next package
    205                 }
    206             }
    207         }
    208         return targetSdkVersion;
    209     }
    210 }
    211