1 /* 2 ** 3 ** Copyright 2007, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 package com.android.packageinstaller; 18 19 import com.android.packageinstaller.R; 20 21 import android.app.Activity; 22 import android.app.AlertDialog; 23 import android.app.Dialog; 24 import android.content.DialogInterface; 25 import android.content.Intent; 26 import android.content.DialogInterface.OnCancelListener; 27 import android.content.pm.ApplicationInfo; 28 import android.content.pm.IPackageInstallObserver; 29 import android.content.pm.PackageInfo; 30 import android.content.pm.PackageManager; 31 import android.content.pm.ResolveInfo; 32 import android.content.pm.PackageManager.NameNotFoundException; 33 import android.content.res.Resources; 34 import android.graphics.drawable.Drawable; 35 import android.net.Uri; 36 import android.os.Bundle; 37 import android.os.Handler; 38 import android.os.Message; 39 import android.util.Log; 40 import android.view.View; 41 import android.view.Window; 42 import android.widget.Button; 43 import android.widget.ProgressBar; 44 import android.widget.TextView; 45 46 import java.util.List; 47 48 /** 49 * This activity corresponds to a download progress screen that is displayed 50 * when the user tries 51 * to install an application bundled as an apk file. The result of the application install 52 * is indicated in the result code that gets set to the corresponding installation status 53 * codes defined in PackageManager. If the package being installed already exists, 54 * the existing package is replaced with the new one. 55 */ 56 public class InstallAppProgress extends Activity implements View.OnClickListener, OnCancelListener { 57 private final String TAG="InstallAppProgress"; 58 private boolean localLOGV = false; 59 private ApplicationInfo mAppInfo; 60 private Uri mPackageURI; 61 private ProgressBar mProgressBar; 62 private View mOkPanel; 63 private TextView mStatusTextView; 64 private Button mDoneButton; 65 private Button mLaunchButton; 66 private final int INSTALL_COMPLETE = 1; 67 private Intent mLaunchIntent; 68 private static final int DLG_OUT_OF_SPACE = 1; 69 private CharSequence mLabel; 70 71 private Handler mHandler = new Handler() { 72 public void handleMessage(Message msg) { 73 switch (msg.what) { 74 case INSTALL_COMPLETE: 75 // Update the status text 76 mProgressBar.setVisibility(View.INVISIBLE); 77 // Show the ok button 78 int centerTextLabel; 79 Drawable centerTextDrawable = null; 80 if(msg.arg1 == PackageManager.INSTALL_SUCCEEDED) { 81 mLaunchButton.setVisibility(View.VISIBLE); 82 centerTextDrawable = getResources().getDrawable(R.drawable.button_indicator_finish); 83 centerTextLabel = R.string.install_done; 84 // Enable or disable launch button 85 mLaunchIntent = getPackageManager().getLaunchIntentForPackage( 86 mAppInfo.packageName); 87 boolean enabled = false; 88 if(mLaunchIntent != null) { 89 List<ResolveInfo> list = getPackageManager(). 90 queryIntentActivities(mLaunchIntent, 0); 91 if (list != null && list.size() > 0) { 92 enabled = true; 93 } 94 } 95 if (enabled) { 96 mLaunchButton.setOnClickListener(InstallAppProgress.this); 97 } else { 98 mLaunchButton.setEnabled(false); 99 } 100 } else if (msg.arg1 == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){ 101 showDialogInner(DLG_OUT_OF_SPACE); 102 return; 103 } else { 104 // Generic error handling for all other error codes. 105 centerTextDrawable = Resources.getSystem().getDrawable( 106 com.android.internal.R.drawable.ic_bullet_key_permission); 107 centerTextLabel = R.string.install_failed; 108 mLaunchButton.setVisibility(View.INVISIBLE); 109 } 110 if (centerTextDrawable != null) { 111 centerTextDrawable.setBounds(0, 0, 112 centerTextDrawable.getIntrinsicWidth(), 113 centerTextDrawable.getIntrinsicHeight()); 114 mStatusTextView.setCompoundDrawables(centerTextDrawable, null, null, null); 115 } 116 mStatusTextView.setText(centerTextLabel); 117 mDoneButton.setOnClickListener(InstallAppProgress.this); 118 mOkPanel.setVisibility(View.VISIBLE); 119 break; 120 default: 121 break; 122 } 123 } 124 }; 125 126 @Override onCreate(Bundle icicle)127 public void onCreate(Bundle icicle) { 128 super.onCreate(icicle); 129 Intent intent = getIntent(); 130 mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); 131 mPackageURI = intent.getData(); 132 initView(); 133 } 134 135 @Override onCreateDialog(int id, Bundle bundle)136 public Dialog onCreateDialog(int id, Bundle bundle) { 137 switch (id) { 138 case DLG_OUT_OF_SPACE: 139 String dlgText = getString(R.string.out_of_space_dlg_text, mLabel); 140 return new AlertDialog.Builder(this) 141 .setTitle(R.string.out_of_space_dlg_title) 142 .setMessage(dlgText) 143 .setPositiveButton(R.string.manage_applications, new DialogInterface.OnClickListener() { 144 public void onClick(DialogInterface dialog, int which) { 145 //launch manage applications 146 Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE"); 147 startActivity(intent); 148 finish(); 149 } 150 }) 151 .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 152 public void onClick(DialogInterface dialog, int which) { 153 Log.i(TAG, "Canceling installation"); 154 finish(); 155 } 156 }) 157 .setOnCancelListener(this) 158 .create(); 159 } 160 return null; 161 } 162 163 private void showDialogInner(int id) { 164 removeDialog(id); 165 showDialog(id); 166 } 167 168 class PackageInstallObserver extends IPackageInstallObserver.Stub { 169 public void packageInstalled(String packageName, int returnCode) { 170 Message msg = mHandler.obtainMessage(INSTALL_COMPLETE); 171 msg.arg1 = returnCode; 172 mHandler.sendMessage(msg); 173 } 174 } 175 176 public void initView() { 177 requestWindowFeature(Window.FEATURE_NO_TITLE); 178 setContentView(R.layout.op_progress); 179 int installFlags = 0; 180 PackageManager pm = getPackageManager(); 181 try { 182 PackageInfo pi = pm.getPackageInfo(mAppInfo.packageName, 183 PackageManager.GET_UNINSTALLED_PACKAGES); 184 if(pi != null) { 185 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 186 } 187 } catch (NameNotFoundException e) { 188 } 189 if((installFlags & PackageManager.INSTALL_REPLACE_EXISTING )!= 0) { 190 Log.w(TAG, "Replacing package:" + mAppInfo.packageName); 191 } 192 PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, mAppInfo, 193 mPackageURI); 194 mLabel = as.label; 195 PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); 196 mStatusTextView = (TextView)findViewById(R.id.center_text); 197 mStatusTextView.setText(R.string.installing); 198 mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); 199 mProgressBar.setIndeterminate(true); 200 // Hide button till progress is being displayed 201 mOkPanel = (View)findViewById(R.id.buttons_panel); 202 mDoneButton = (Button)findViewById(R.id.done_button); 203 mLaunchButton = (Button)findViewById(R.id.launch_button); 204 mOkPanel.setVisibility(View.INVISIBLE); 205 206 String installerPackageName = getIntent().getStringExtra( 207 Intent.EXTRA_INSTALLER_PACKAGE_NAME); 208 PackageInstallObserver observer = new PackageInstallObserver(); 209 pm.installPackage(mPackageURI, observer, installFlags, installerPackageName); 210 } 211 212 @Override 213 protected void onDestroy() { 214 super.onDestroy(); 215 } 216 217 public void onClick(View v) { 218 if(v == mDoneButton) { 219 if (mAppInfo.packageName != null) { 220 Log.i(TAG, "Finished installing "+mAppInfo.packageName); 221 } 222 finish(); 223 } else if(v == mLaunchButton) { 224 startActivity(mLaunchIntent); 225 finish(); 226 } 227 } 228 229 public void onCancel(DialogInterface dialog) { 230 finish(); 231 } 232 } 233