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