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*/
1791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectpackage com.android.packageinstaller;
1891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
1991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.app.Activity;
20d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruverimport android.app.ActivityManagerNative;
2191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.app.AlertDialog;
2291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.app.Dialog;
239e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackbornimport android.content.Context;
2491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.DialogInterface;
2591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
261f45fa5f219a6577265c480a81af77450985d532Gilles Debunneimport android.content.Intent;
279e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackbornimport android.content.SharedPreferences;
2891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.ApplicationInfo;
29aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackbornimport android.content.pm.PackageInfo;
3091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.PackageManager;
31aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackbornimport android.content.pm.PackageUserState;
3291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException;
331f45fa5f219a6577265c480a81af77450985d532Gilles Debunneimport android.content.pm.PackageParser;
34d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruverimport android.content.pm.VerificationParams;
35ee21cab0e684710a77df85577ff16d1f00edaf4dAdam Powellimport android.graphics.Rect;
3691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.net.Uri;
3791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.os.Bundle;
3891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.provider.Settings;
3937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackbornimport android.support.v4.view.PagerAdapter;
4037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackbornimport android.support.v4.view.ViewPager;
4191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.util.Log;
429762658939747166e3c40d817971aa5b17231ee7Dianne Hackbornimport android.view.LayoutInflater;
43d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapuimport android.view.View;
44d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapuimport android.view.View.OnClickListener;
45ee21cab0e684710a77df85577ff16d1f00edaf4dAdam Powellimport android.view.ViewGroup;
46d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapuimport android.widget.AppSecurityPermissions;
47d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapuimport android.widget.Button;
489762658939747166e3c40d817971aa5b17231ee7Dianne Hackbornimport android.widget.ScrollView;
499762658939747166e3c40d817971aa5b17231ee7Dianne Hackbornimport android.widget.TabHost;
509762658939747166e3c40d817971aa5b17231ee7Dianne Hackbornimport android.widget.TabWidget;
519762658939747166e3c40d817971aa5b17231ee7Dianne Hackbornimport android.widget.TextView;
5291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
5379da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkeyimport java.io.File;
549762658939747166e3c40d817971aa5b17231ee7Dianne Hackbornimport java.util.ArrayList;
5579da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
5691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project/*
5791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * This activity is launched when a new application is installed via side loading
5891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * The package is first parsed and the user is notified of parse errors via a dialog.
5991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * If the package is successfully parsed, the user is notified to turn on the install unknown
6091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * applications setting. A memory check is made at this point and the user is notified of out
6191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * of memory conditions if any. If the package is already existing on the device,
6291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * a confirmation dialog (to replace the existing package) is presented to the user.
6391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * Based on the user response the package is then installed by launching InstallAppConfirm
6491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * sub activity. All state transitions are handled in this activity
6591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project */
66d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapupublic class PackageInstallerActivity extends Activity implements OnCancelListener, OnClickListener {
6791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    private static final String TAG = "PackageInstaller";
68319efc1c099a0c0c516d3a0d3d110c8608c9eee9Rich Cannings    private Uri mPackageURI;
69916ad007619e025218665298ef9793c152ced070rich cannings    private Uri mOriginatingURI;
70916ad007619e025218665298ef9793c152ced070rich cannings    private Uri mReferrerURI;
71d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver    private int mOriginatingUid = VerificationParams.NO_UID;
72d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
7391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    private boolean localLOGV = false;
7491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    PackageManager mPm;
75aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn    PackageInfo mPkgInfo;
769e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn    ApplicationInfo mSourceInfo;
7791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
7891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    // ApplicationInfo object primarily used for already existing applications
7991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    private ApplicationInfo mAppInfo = null;
8091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
81d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    // View for install progress
82d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    View mInstallConfirm;
83d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    // Buttons to indicate user acceptance
84d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    private Button mOk;
85d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    private Button mCancel;
868ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn    CaffeinatedScrollView mScrollView = null;
878ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn    private boolean mOkCanInstall = false;
88d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu
899e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn    static final String PREFS_ALLOWED_SOURCES = "allowed_sources";
909e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn
9191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    // Dialog identifiers used in showDialog
9291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    private static final int DLG_BASE = 0;
9337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    private static final int DLG_UNKNOWN_APPS = DLG_BASE + 1;
9437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    private static final int DLG_PACKAGE_ERROR = DLG_BASE + 2;
9537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    private static final int DLG_OUT_OF_SPACE = DLG_BASE + 3;
9637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    private static final int DLG_INSTALL_ERROR = DLG_BASE + 4;
9737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    private static final int DLG_ALLOW_SOURCE = DLG_BASE + 5;
9837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
9937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    /**
10037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * This is a helper class that implements the management of tabs and all
10137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * details of connecting a ViewPager with associated TabHost.  It relies on a
10237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * trick.  Normally a tab host has a simple API for supplying a View or
10337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * Intent that each tab will show.  This is not sufficient for switching
10437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * between pages.  So instead we make the content part of the tab host
10537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
10637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * view to show as the tab content.  It listens to changes in tabs, and takes
10737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * care of switch to the correct paged in the ViewPager whenever the selected
10837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     * tab changes.
10937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn     */
11037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    public static class TabsAdapter extends PagerAdapter
11137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
11237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        private final Context mContext;
11337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        private final TabHost mTabHost;
11437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        private final ViewPager mViewPager;
11537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
11637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        private final Rect mTempRect = new Rect();
11737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
11837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        static final class TabInfo {
11937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            private final String tag;
12037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            private final View view;
12137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
12237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            TabInfo(String _tag, View _view) {
12337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                tag = _tag;
12437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                view = _view;
12537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            }
12637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
12737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
12837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        static class DummyTabFactory implements TabHost.TabContentFactory {
12937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            private final Context mContext;
13037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
13137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            public DummyTabFactory(Context context) {
13237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                mContext = context;
13337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            }
13437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
13537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            @Override
13637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            public View createTabContent(String tag) {
13737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                View v = new View(mContext);
13837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                v.setMinimumWidth(0);
13937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                v.setMinimumHeight(0);
14037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                return v;
14137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            }
14237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
14337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
14437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public TabsAdapter(Activity activity, TabHost tabHost, ViewPager pager) {
14537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mContext = activity;
14637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mTabHost = tabHost;
14737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mViewPager = pager;
14837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mTabHost.setOnTabChangedListener(this);
14937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mViewPager.setAdapter(this);
15037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mViewPager.setOnPageChangeListener(this);
15137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
15237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
15337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public void addTab(TabHost.TabSpec tabSpec, View view) {
15437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            tabSpec.setContent(new DummyTabFactory(mContext));
15537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            String tag = tabSpec.getTag();
15637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
15737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            TabInfo info = new TabInfo(tag, view);
15837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mTabs.add(info);
15937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mTabHost.addTab(tabSpec);
16037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            notifyDataSetChanged();
16137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
16237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
16337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
16437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public int getCount() {
16537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            return mTabs.size();
16637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
16737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
16837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
16937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public Object instantiateItem(ViewGroup container, int position) {
17037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            View view = mTabs.get(position).view;
17137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            container.addView(view);
17237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            return view;
17337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
17437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
17537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
17637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public void destroyItem(ViewGroup container, int position, Object object) {
17737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            container.removeView((View)object);
17837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
17937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
18037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
18137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public boolean isViewFromObject(View view, Object object) {
18237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            return view == object;
18337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
18437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
18537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
18637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public void onTabChanged(String tabId) {
18737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            int position = mTabHost.getCurrentTab();
18837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mViewPager.setCurrentItem(position);
18937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
19037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
19137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
19237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
19337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
19437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
19537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
19637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public void onPageSelected(int position) {
19737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            // Unfortunately when TabHost changes the current tab, it kindly
19837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            // also takes care of putting focus on it when not in touch mode.
19937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            // The jerk.
20037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            // This hack tries to prevent this from pulling focus out of our
20137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            // ViewPager.
20237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            TabWidget widget = mTabHost.getTabWidget();
20337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            int oldFocusability = widget.getDescendantFocusability();
20437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
20537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mTabHost.setCurrentTab(position);
20637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            widget.setDescendantFocusability(oldFocusability);
20737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
20837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            // Scroll the current tab into visibility if needed.
20937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            View tab = widget.getChildTabViewAt(position);
21037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            mTempRect.set(tab.getLeft(), tab.getTop(), tab.getRight(), tab.getBottom());
21137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            widget.requestRectangleOnScreen(mTempRect, false);
21237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
21337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            // Make sure the scrollbars are visible for a moment after selection
21437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            final View contentView = mTabs.get(position).view;
21537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            if (contentView instanceof CaffeinatedScrollView) {
21637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                ((CaffeinatedScrollView) contentView).awakenScrollBars();
21737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            }
21837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
21937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
22037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        @Override
22137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        public void onPageScrollStateChanged(int state) {
22237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
22337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn    }
22491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
225d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    private void startInstallConfirm() {
22637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost);
22737df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        tabHost.setup();
22837df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        ViewPager viewPager = (ViewPager)findViewById(R.id.pager);
22937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        TabsAdapter adapter = new TabsAdapter(this, tabHost, viewPager);
23037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn
231d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        boolean permVisible = false;
2328ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn        mScrollView = null;
2338ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn        mOkCanInstall = false;
23437df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        int msg = 0;
23537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        if (mPkgInfo != null) {
23637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            AppSecurityPermissions perms = new AppSecurityPermissions(this, mPkgInfo);
2378ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            final int NP = perms.getPermissionCount(AppSecurityPermissions.WHICH_PERSONAL);
2388ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            final int ND = perms.getPermissionCount(AppSecurityPermissions.WHICH_DEVICE);
23937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            if (mAppInfo != null) {
24037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
24137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                        ? R.string.install_confirm_question_update_system
24237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                        : R.string.install_confirm_question_update;
2438ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                mScrollView = new CaffeinatedScrollView(this);
2448ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                mScrollView.setFillViewport(true);
24537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                if (perms.getPermissionCount(AppSecurityPermissions.WHICH_NEW) > 0) {
2468ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    permVisible = true;
2478ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    mScrollView.addView(perms.getPermissionsView(
2488ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                            AppSecurityPermissions.WHICH_NEW));
24937df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                } else {
25037df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                    LayoutInflater inflater = (LayoutInflater)getSystemService(
25137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                            Context.LAYOUT_INFLATER_SERVICE);
25237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                    TextView label = (TextView)inflater.inflate(R.layout.label, null);
25337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                    label.setText(R.string.no_new_perms);
2548ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    mScrollView.addView(label);
25537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                }
25637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                adapter.addTab(tabHost.newTabSpec("new").setIndicator(
2578ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                        getText(R.string.newPerms)), mScrollView);
2588ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            } else  {
2598ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                findViewById(R.id.tabscontainer).setVisibility(View.GONE);
260860959202df6e79636a68cc94ea94268fcbdc305Dianne Hackborn                findViewById(R.id.divider).setVisibility(View.VISIBLE);
26137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            }
2628ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            if (NP > 0 || ND > 0) {
26337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn                permVisible = true;
2648ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                LayoutInflater inflater = (LayoutInflater)getSystemService(
2658ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                        Context.LAYOUT_INFLATER_SERVICE);
2668ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                View root = inflater.inflate(R.layout.permissions_list, null);
2678ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if (mScrollView == null) {
2688ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    mScrollView = (CaffeinatedScrollView)root.findViewById(R.id.scrollview);
2698ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
2708ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if (NP > 0) {
2718ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    ((ViewGroup)root.findViewById(R.id.privacylist)).addView(
2728ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                            perms.getPermissionsView(AppSecurityPermissions.WHICH_PERSONAL));
2738ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                } else {
2748ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    root.findViewById(R.id.privacylist).setVisibility(View.GONE);
2758ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
2768ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if (ND > 0) {
2778ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    ((ViewGroup)root.findViewById(R.id.devicelist)).addView(
2788ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                            perms.getPermissionsView(AppSecurityPermissions.WHICH_DEVICE));
2798ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                } else {
2808ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    root.findViewById(R.id.devicelist).setVisibility(View.GONE);
2818ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
2828ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                adapter.addTab(tabHost.newTabSpec("all").setIndicator(
2838ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                        getText(R.string.allPerms)), root);
284d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu            }
285fe069ea729efec01a8b6f16f9e76a2db4988404aJacek Surazski        }
28637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        if (!permVisible) {
28703347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn            if (mAppInfo != null) {
28803347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn                // This is an update to an application, but there are no
28903347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn                // permissions at all.
29003347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn                msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
29103347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn                        ? R.string.install_confirm_question_update_system_no_perms
29203347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn                        : R.string.install_confirm_question_update_no_perms;
29303347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn            } else {
29403347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn                // This is a new application with no permissions.
29503347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn                msg = R.string.install_confirm_question_no_perms;
29637df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            }
297860959202df6e79636a68cc94ea94268fcbdc305Dianne Hackborn            tabHost.setVisibility(View.GONE);
29803347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn            findViewById(R.id.filler).setVisibility(View.VISIBLE);
29903347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn            findViewById(R.id.divider).setVisibility(View.GONE);
30003347bac6c91b8a8371b05783f6b23ef883b8c9aDianne Hackborn            mScrollView = null;
30137df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        }
30237df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        if (msg != 0) {
30337df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn            ((TextView)findViewById(R.id.install_confirm_question)).setText(msg);
304d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        }
305d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        mInstallConfirm.setVisibility(View.VISIBLE);
306d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        mOk = (Button)findViewById(R.id.ok_button);
307d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        mCancel = (Button)findViewById(R.id.cancel_button);
308d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        mOk.setOnClickListener(this);
309d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        mCancel.setOnClickListener(this);
3108ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn        if (mScrollView == null) {
3118ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            // There is nothing to scroll view, so the ok button is immediately
3128ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            // set to install.
3138ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            mOk.setText(R.string.install);
3148ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            mOkCanInstall = true;
3158ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn        } else {
3168ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            mScrollView.setFullScrollAction(new Runnable() {
3178ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                @Override
3188ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                public void run() {
3198ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    mOk.setText(R.string.install);
3208ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    mOkCanInstall = true;
3218ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
3228ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            });
3238ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn        }
32491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
32591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
32691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    private void showDialogInner(int id) {
32791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        // TODO better fix for this? Remove dialog so that it gets created again
32891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        removeDialog(id);
32991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        showDialog(id);
33091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
33191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
33291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    @Override
3339ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    public Dialog onCreateDialog(int id, Bundle bundle) {
33491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        switch (id) {
33591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        case DLG_UNKNOWN_APPS:
33691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            return new AlertDialog.Builder(this)
33791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setTitle(R.string.unknown_apps_dlg_title)
33891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setMessage(R.string.unknown_apps_dlg_text)
33991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
34091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        public void onClick(DialogInterface dialog, int which) {
34191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            Log.i(TAG, "Finishing off activity so that user can navigate to settings manually");
34291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            finish();
34391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        }})
34491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() {
34591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        public void onClick(DialogInterface dialog, int which) {
34691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            Log.i(TAG, "Launching settings");
34791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            launchSettingsAppAndFinish();
34891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        }
34991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    })
35091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setOnCancelListener(this)
35191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .create();
35291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        case DLG_PACKAGE_ERROR :
35391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            return new AlertDialog.Builder(this)
35491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setTitle(R.string.Parse_error_dlg_title)
35591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setMessage(R.string.Parse_error_dlg_text)
35691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
35791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        public void onClick(DialogInterface dialog, int which) {
35891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            finish();
35991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        }
36091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    })
36191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setOnCancelListener(this)
36291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .create();
36391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        case DLG_OUT_OF_SPACE:
36491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            // Guaranteed not to be null. will default to package name if not set by app
36591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            CharSequence appTitle = mPm.getApplicationLabel(mPkgInfo.applicationInfo);
36691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            String dlgText = getString(R.string.out_of_space_dlg_text,
36791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    appTitle.toString());
36891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            return new AlertDialog.Builder(this)
36991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setTitle(R.string.out_of_space_dlg_title)
37091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setMessage(dlgText)
37191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setPositiveButton(R.string.manage_applications, new DialogInterface.OnClickListener() {
37291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        public void onClick(DialogInterface dialog, int which) {
37391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            //launch manage applications
37491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE");
37538199c5efdb4e650b0ffbe873d8cf27c35f51db6Kenny Root                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
37691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            startActivity(intent);
37791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            finish();
37891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        }
37991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    })
38091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
38191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        public void onClick(DialogInterface dialog, int which) {
38291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            Log.i(TAG, "Canceling installation");
38391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            finish();
38491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        }
38591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                  })
38691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                  .setOnCancelListener(this)
38791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                  .create();
38891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        case DLG_INSTALL_ERROR :
38991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            // Guaranteed not to be null. will default to package name if not set by app
39091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            CharSequence appTitle1 = mPm.getApplicationLabel(mPkgInfo.applicationInfo);
39191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            String dlgText1 = getString(R.string.install_failed_msg,
39291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    appTitle1.toString());
39391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            return new AlertDialog.Builder(this)
39491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setTitle(R.string.install_failed)
39591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
39691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        public void onClick(DialogInterface dialog, int which) {
39791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                            finish();
39891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                        }
39991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    })
40091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setMessage(dlgText1)
40191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .setOnCancelListener(this)
40291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    .create();
4039e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        case DLG_ALLOW_SOURCE:
4049e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            CharSequence appTitle2 = mPm.getApplicationLabel(mSourceInfo);
4059e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            String dlgText2 = getString(R.string.allow_source_dlg_text,
4069e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    appTitle2.toString());
4079e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            return new AlertDialog.Builder(this)
4089e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    .setTitle(R.string.allow_source_dlg_title)
4099e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    .setMessage(dlgText2)
4109e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
4119e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        public void onClick(DialogInterface dialog, int which) {
4129e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                            setResult(RESULT_CANCELED);
4139e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                            finish();
4149e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        }})
4159e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
4169e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        public void onClick(DialogInterface dialog, int which) {
4179e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                            SharedPreferences prefs = getSharedPreferences(PREFS_ALLOWED_SOURCES,
4189e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                                    Context.MODE_PRIVATE);
4199e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                            prefs.edit().putBoolean(mSourceInfo.packageName, true).apply();
4209e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                            startInstallConfirm();
4219e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        }
4229e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    })
4239e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    .setOnCancelListener(this)
4249e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    .create();
42591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project       }
42691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project       return null;
42791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project   }
42891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
42991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    private void launchSettingsAppAndFinish() {
4301f45fa5f219a6577265c480a81af77450985d532Gilles Debunne        // Create an intent to launch SettingsTwo activity
4311f45fa5f219a6577265c480a81af77450985d532Gilles Debunne        Intent launchSettingsIntent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
43238199c5efdb4e650b0ffbe873d8cf27c35f51db6Kenny Root        launchSettingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
43391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        startActivity(launchSettingsIntent);
43491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        finish();
43591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
43691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
43791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    private boolean isInstallingUnknownAppsAllowed() {
4389e8baaab93202587c4c01bcaaba29d39bc35ba67Jeff Brown        return Settings.Global.getInt(getContentResolver(),
4399e8baaab93202587c4c01bcaaba29d39bc35ba67Jeff Brown            Settings.Global.INSTALL_NON_MARKET_APPS, 0) > 0;
44091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
44191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
4423d07f28761d467664ea97a7be7cbedf92762f14cSuchi Amalapurapu    private void initiateInstall() {
4430d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn        String pkgName = mPkgInfo.packageName;
4440d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn        // Check if there is already a package on the device with this name
4450d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn        // but it has been renamed to something else.
4460d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn        String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
4470d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn        if (oldName != null && oldName.length > 0 && oldName[0] != null) {
4480d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn            pkgName = oldName[0];
449aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            mPkgInfo.packageName = pkgName;
450aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            mPkgInfo.applicationInfo.packageName = pkgName;
4510d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn        }
45291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        // Check if package is already installed. display confirmation dialog if replacing pkg
45391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        try {
454aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            // This is a little convoluted because we want to get all uninstalled
455aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            // apps, but this may include apps with just data, and if it is just
456aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            // data we still want to count it as "installed".
4570d4ff37341fc970195d9a737a8ab166c550aa2b3Dianne Hackborn            mAppInfo = mPm.getApplicationInfo(pkgName,
45891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project                    PackageManager.GET_UNINSTALLED_PACKAGES);
459aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
460aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                mAppInfo = null;
461aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            }
46291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        } catch (NameNotFoundException e) {
46391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            mAppInfo = null;
46491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        }
46537df032e580ab6bed29eb40b72df1f49cefd2af1Dianne Hackborn        startInstallConfirm();
46691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
4679e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn
4689e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn    void setPmResult(int pmResult) {
4699e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        Intent result = new Intent();
4709e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        result.putExtra(Intent.EXTRA_INSTALL_RESULT, pmResult);
4719e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        setResult(pmResult == PackageManager.INSTALL_SUCCEEDED
4729e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                ? RESULT_OK : RESULT_FIRST_USER, result);
4739e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn    }
4749e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn
47591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    @Override
476d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    protected void onCreate(Bundle icicle) {
47791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        super.onCreate(icicle);
47879da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
47979da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        // get intent information
48091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        final Intent intent = getIntent();
48191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        mPackageURI = intent.getData();
482916ad007619e025218665298ef9793c152ced070rich cannings        mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
483916ad007619e025218665298ef9793c152ced070rich cannings        mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
48491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        mPm = getPackageManager();
48579da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
48679da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        final String scheme = mPackageURI.getScheme();
487aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn        if (scheme != null && !"file".equals(scheme) && !"package".equals(scheme)) {
488aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            Log.w(TAG, "Unsupported scheme " + scheme);
489aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI);
490aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            return;
49179da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        }
49279da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
493aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn        final PackageUtil.AppSnippet as;
494aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn        if ("package".equals(mPackageURI.getScheme())) {
495aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            try {
496aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                mPkgInfo = mPm.getPackageInfo(mPackageURI.getSchemeSpecificPart(),
497aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                        PackageManager.GET_PERMISSIONS | PackageManager.GET_UNINSTALLED_PACKAGES);
498aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            } catch (NameNotFoundException e) {
499aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            }
500aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            if (mPkgInfo == null) {
501aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                Log.w(TAG, "Requested package " + mPackageURI.getScheme()
502aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                        + " not available. Discontinuing installation");
503aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                showDialogInner(DLG_PACKAGE_ERROR);
504aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
505aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                return;
506aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            }
507aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            as = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo),
508aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                    mPm.getApplicationIcon(mPkgInfo.applicationInfo));
509aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn        } else {
510aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            final File sourceFile = new File(mPackageURI.getPath());
511aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            PackageParser.Package parsed = PackageUtil.getPackageInfo(sourceFile);
512aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn
513aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            // Check for parse errors
514aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            if (parsed == null) {
515aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
516aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                showDialogInner(DLG_PACKAGE_ERROR);
517aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
518aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                return;
519aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            }
520aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
521aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                    PackageManager.GET_PERMISSIONS, 0, 0, null,
522aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn                    new PackageUserState());
523aba0bed7a4f6301c6e3067fc799d8ef47aaca0b2Dianne Hackborn            as = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
52491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        }
52591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
52691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        //set view
52791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        setContentView(R.layout.install_start);
528d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        mInstallConfirm = findViewById(R.id.install_confirm_panel);
529d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        mInstallConfirm.setVisibility(View.INVISIBLE);
5309ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
5319e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn
532d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        mOriginatingUid = getOriginatingUid(intent);
533d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
5349e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        // Deal with install source.
5359e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        String callerPackage = getCallingPackage();
5369e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        if (callerPackage != null && intent.getBooleanExtra(
5379e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)) {
5389e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            try {
5399e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                mSourceInfo = mPm.getApplicationInfo(callerPackage, 0);
5409e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                if (mSourceInfo != null) {
5419e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    if ((mSourceInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5429e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        // System apps don't need to be approved.
5439e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        initiateInstall();
5449e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        return;
5459e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    }
5469e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    /* for now this is disabled, since the user would need to
5479e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                     * have enabled the global "unknown sources" setting in the
5489e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                     * first place in order to get here.
5499e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    SharedPreferences prefs = getSharedPreferences(PREFS_ALLOWED_SOURCES,
5509e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                            Context.MODE_PRIVATE);
5519e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    if (prefs.getBoolean(mSourceInfo.packageName, false)) {
5529e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        // User has already allowed this one.
5539e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        initiateInstall();
5549e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                        return;
5559e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    }
5569e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    //ask user to enable setting first
5579e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    showDialogInner(DLG_ALLOW_SOURCE);
5589e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                    return;
5599e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                     */
5609e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn                }
5619e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            } catch (NameNotFoundException e) {
5629e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            }
5639e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        }
5649e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn
5659e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        // Check unknown sources.
5669e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn        if (!isInstallingUnknownAppsAllowed()) {
56791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            //ask user to enable setting first
56891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            showDialogInner(DLG_UNKNOWN_APPS);
56991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project            return;
57091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        }
5719ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        initiateInstall();
57291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
573d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
574d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver    /** Get the ApplicationInfo for the calling package, if available */
575d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver    private ApplicationInfo getSourceInfo() {
576d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        String callingPackage = getCallingPackage();
577d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        if (callingPackage != null) {
578d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            try {
579d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                return mPm.getApplicationInfo(callingPackage, 0);
580d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            } catch (NameNotFoundException ex) {
581d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                // ignore
582d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            }
583d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        }
584d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        return null;
585d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver    }
586d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
587d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
588d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver    /** Get the originating uid if possible, or VerificationParams.NO_UID if not available */
589d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver    private int getOriginatingUid(Intent intent) {
590d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // The originating uid from the intent. We only trust/use this if it comes from a
591d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // system application
592d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        int uidFromIntent = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID,
593d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                VerificationParams.NO_UID);
594d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
595d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // Get the source info from the calling package, if available. This will be the
596d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // definitive calling package, but it only works if the intent was started using
597d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // startActivityForResult,
598d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        ApplicationInfo sourceInfo = getSourceInfo();
599d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        if (sourceInfo != null) {
600d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            if (uidFromIntent != VerificationParams.NO_UID &&
601d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                    (mSourceInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
602d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                return uidFromIntent;
603d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
604d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            }
605d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            // We either didn't get a uid in the intent, or we don't trust it. Use the
606d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            // uid of the calling package instead.
607d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            return sourceInfo.uid;
608d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        }
609d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
610d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // We couldn't get the specific calling package. Let's get the uid instead
611d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        int callingUid;
612d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        try {
613d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            callingUid = ActivityManagerNative.getDefault()
614d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                    .getLaunchedFromUid(getActivityToken());
615d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        } catch (android.os.RemoteException ex) {
616d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            Log.w(TAG, "Could not determine the launching uid.");
617d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            // nothing else we can do
618d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            return VerificationParams.NO_UID;
619d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        }
620d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
621d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // If we got a uid from the intent, we need to verify that the caller is a
622d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // system package before we use it
623d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        if (uidFromIntent != VerificationParams.NO_UID) {
624d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            String[] callingPackages = mPm.getPackagesForUid(callingUid);
625d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            if (callingPackages != null) {
626d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                for (String packageName: callingPackages) {
627d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                    try {
628d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                        ApplicationInfo applicationInfo =
629d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                                mPm.getApplicationInfo(packageName, 0);
630d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
631d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                        if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
632d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                            return uidFromIntent;
633d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                        }
634d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                    } catch (NameNotFoundException ex) {
635d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                        // ignore it, and try the next package
636d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                    }
637d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                }
638d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver            }
639d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        }
640d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // We either didn't get a uid from the intent, or we don't trust it. Use the
641d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        // calling uid instead.
642d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver        return callingUid;
643d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver    }
644d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver
64591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    // Generic handling when pressing back key
64691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public void onCancel(DialogInterface dialog) {
64791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project        finish();
64891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
649d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu
650d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    public void onClick(View v) {
651d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        if(v == mOk) {
6528ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            if (mOkCanInstall || mScrollView == null) {
6538ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                // Start subactivity to actually install the application
6548ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                Intent newIntent = new Intent();
6558ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
6568ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                        mPkgInfo.applicationInfo);
6578ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                newIntent.setData(mPackageURI);
6588ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                newIntent.setClass(this, InstallAppProgress.class);
6598ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                String installerPackageName = getIntent().getStringExtra(
6608ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                        Intent.EXTRA_INSTALLER_PACKAGE_NAME);
6618ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if (mOriginatingURI != null) {
6628ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    newIntent.putExtra(Intent.EXTRA_ORIGINATING_URI, mOriginatingURI);
6638ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
6648ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if (mReferrerURI != null) {
6658ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI);
6668ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
667d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                if (mOriginatingUid != VerificationParams.NO_UID) {
668d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                    newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid);
669d58f150060e9300038ff86eeeffc86c2440303c8Ben Gruver                }
6708ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if (installerPackageName != null) {
6718ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME,
6728ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                            installerPackageName);
6738ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
6748ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
6758ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
6768ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                    newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
6778ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                }
6788ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
6798ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                startActivity(newIntent);
6808ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                finish();
6818ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn            } else {
6828ec226e8c778a3d1b4268edc33cd7c515d88ab31Dianne Hackborn                mScrollView.pageScroll(View.FOCUS_DOWN);
6839e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            }
684d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        } else if(v == mCancel) {
685d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu            // Cancel and finish
6869e9721266feafdf16786b94f6fac4c06220cd422Dianne Hackborn            setResult(RESULT_CANCELED);
687d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu            finish();
688d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu        }
689d9b773b7041894e37c1b6f62d6b221dd3c8e4c43Suchi Amalapurapu    }
69091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project}
691