191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project/*
291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** Copyright 2007, The Android Open Source Project
491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** you may not use this file except in compliance with the License.
791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** You may obtain a copy of the License at
891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
1191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** See the License for the specific language governing permissions and
1591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** limitations under the License.
1691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project*/
1779da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
1891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectpackage com.android.packageinstaller;
1991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
2091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.app.Activity;
2191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.ApplicationInfo;
2291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.PackageInfo;
2391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.PackageManager;
2491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.PackageParser;
25ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapuimport android.content.res.AssetManager;
26ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapuimport android.content.res.Resources;
2791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.graphics.drawable.Drawable;
2891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.util.DisplayMetrics;
2991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.view.View;
3091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.widget.ImageView;
3191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.widget.TextView;
3291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
33362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroyimport java.io.File;
34362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroyimport java.util.List;
35362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy
3691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project/**
3791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * This is a utility class for defining some utility methods and constants
3891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * used in the package installer application.
3991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project */
4091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectpublic class PackageUtil {
4191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String PREFIX="com.android.packageinstaller.";
4291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
4391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo";
4491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
4591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    //intent attribute strings related to uninstall
4691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
4779da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
4879da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
4979da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey     * Utility method to get application information for a given {@link File}
5091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project     */
5179da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    public static ApplicationInfo getApplicationInfo(File sourcePath) {
5279da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        final String archiveFilePath = sourcePath.getAbsolutePath();
5391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        PackageParser packageParser = new PackageParser(archiveFilePath);
5491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        File sourceFile = new File(archiveFilePath);
5591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        DisplayMetrics metrics = new DisplayMetrics();
5691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        metrics.setToDefaults();
5779da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        PackageParser.Package pkg = packageParser.parsePackage(
5879da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey                sourceFile, archiveFilePath, metrics, 0);
5991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        if (pkg == null) {
6091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            return null;
6191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        }
6291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        return pkg.applicationInfo;
6391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
6479da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
6579da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
6679da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey     * Utility method to get package information for a given {@link File}
6791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project     */
6879da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    public static PackageParser.Package getPackageInfo(File sourceFile) {
6979da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        final String archiveFilePath = sourceFile.getAbsolutePath();
7091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        PackageParser packageParser = new PackageParser(archiveFilePath);
7191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        DisplayMetrics metrics = new DisplayMetrics();
7291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        metrics.setToDefaults();
733d07f28761d467664ea97a7be7cbedf92762f14cSuchi Amalapurapu        PackageParser.Package pkg =  packageParser.parsePackage(sourceFile,
743d07f28761d467664ea97a7be7cbedf92762f14cSuchi Amalapurapu                archiveFilePath, metrics, 0);
75813a4bd48de33efe5c882ad3b9258e88d6d10fd7Nick Kralevich        if (pkg == null) {
76813a4bd48de33efe5c882ad3b9258e88d6d10fd7Nick Kralevich            return null;
77813a4bd48de33efe5c882ad3b9258e88d6d10fd7Nick Kralevich        }
788d3437fe1be41c2cebdb81de8241d17dca0b8cabKenny Root        if (!packageParser.collectManifestDigest(pkg)) {
79813a4bd48de33efe5c882ad3b9258e88d6d10fd7Nick Kralevich            return null;
80813a4bd48de33efe5c882ad3b9258e88d6d10fd7Nick Kralevich        }
813d07f28761d467664ea97a7be7cbedf92762f14cSuchi Amalapurapu        return pkg;
8291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
83ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu
84362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy    public static View initSnippet(View snippetView, CharSequence label, Drawable icon) {
85362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon);
86362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        ((TextView)snippetView.findViewById(R.id.app_name)).setText(label);
87362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        return snippetView;
88362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy    }
89362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy
9079da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
91362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy     * Utility method to display a snippet of an installed application.
92ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * The content view should have been set on context before invoking this method.
93ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * appSnippet view should include R.id.app_icon and R.id.app_name
94ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * defined on it.
95ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     *
96ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * @param pContext context of package that can load the resources
97362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy     * @param componentInfo ComponentInfo object whose resources are to be loaded
98362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy     * @param snippetView the snippet view
9991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project     */
100ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu    public static View initSnippetForInstalledApp(Activity pContext,
101362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy            ApplicationInfo appInfo, View snippetView) {
102362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        final PackageManager pm = pContext.getPackageManager();
103362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        return initSnippet(
104362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy                snippetView,
105362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy                appInfo.loadLabel(pm),
106362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy                appInfo.loadIcon(pm));
10791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
108ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu
10979da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
110ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * Utility method to display application snippet of a new package.
111ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * The content view should have been set on context before invoking this method.
112ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * appSnippet view should include R.id.app_icon and R.id.app_name
113ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * defined on it.
114ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     *
115ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * @param pContext context of package that can load the resources
116ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * @param appInfo ApplicationInfo object of package whose resources are to be loaded
117ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * @param snippetId view id of app snippet view
11891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project     */
1199ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    public static View initSnippetForNewApp(Activity pContext, AppSnippet as,
1209ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            int snippetId) {
121ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        View appSnippet = pContext.findViewById(snippetId);
1229ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        ((ImageView)appSnippet.findViewById(R.id.app_icon)).setImageDrawable(as.icon);
1239ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        ((TextView)appSnippet.findViewById(R.id.app_name)).setText(as.label);
1249ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        return appSnippet;
1259ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    }
1269ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu
1279ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    public static boolean isPackageAlreadyInstalled(Activity context, String pkgName) {
1289ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        List<PackageInfo> installedList = context.getPackageManager().getInstalledPackages(
1299ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu                PackageManager.GET_UNINSTALLED_PACKAGES);
1309ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        int installedListSize = installedList.size();
1319ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        for(int i = 0; i < installedListSize; i++) {
1329ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            PackageInfo tmp = installedList.get(i);
1339ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            if(pkgName.equalsIgnoreCase(tmp.packageName)) {
1349ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu                return true;
1359ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            }
1369ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        }
1379ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        return false;
1389ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    }
1399ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu
1409ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    static public class AppSnippet {
1419ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        CharSequence label;
1429ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        Drawable icon;
1439ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        public AppSnippet(CharSequence label, Drawable icon) {
1449ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            this.label = label;
1459ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            this.icon = icon;
1469ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        }
1479ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    }
14879da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
14979da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
1509ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     * Utility method to load application label
1519ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     *
1529ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     * @param pContext context of package that can load the resources
1539ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     * @param appInfo ApplicationInfo object of package whose resources are to be loaded
1549ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     * @param snippetId view id of app snippet view
1559ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     */
15679da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    public static AppSnippet getAppSnippet(
15779da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey            Activity pContext, ApplicationInfo appInfo, File sourceFile) {
15879da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        final String archiveFilePath = sourceFile.getAbsolutePath();
159ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu        Resources pRes = pContext.getResources();
160ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        AssetManager assmgr = new AssetManager();
161ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        assmgr.addAssetPath(archiveFilePath);
162ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu        Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
163ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        CharSequence label = null;
164ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // Try to load the label from the package's resources. If an app has not explicitly
165ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // specified any label, just use the package name.
166f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu        if (appInfo.labelRes != 0) {
167f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            try {
168f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu                label = res.getText(appInfo.labelRes);
169f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            } catch (Resources.NotFoundException e) {
170f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            }
171f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu        }
172ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu        if (label == null) {
173ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu            label = (appInfo.nonLocalizedLabel != null) ?
174ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu                    appInfo.nonLocalizedLabel : appInfo.packageName;
175ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        }
176ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        Drawable icon = null;
177ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // Try to load the icon from the package's resources. If an app has not explicitly
178ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // specified any resource, just use the default icon for now.
179f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu        if (appInfo.icon != 0) {
180f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            try {
181f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu                icon = res.getDrawable(appInfo.icon);
182f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            } catch (Resources.NotFoundException e) {
183f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            }
184f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu        }
185f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu        if (icon == null) {
186ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu            icon = pContext.getPackageManager().getDefaultActivityIcon();
187ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        }
1889ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        return new PackageUtil.AppSnippet(label, icon);
18991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
19091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project}
191