• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.graphics.drawable.LevelListDrawable;
34 import android.net.Uri;
35 import android.os.Bundle;
36 import android.os.Handler;
37 import android.os.Message;
38 import android.util.Log;
39 import android.view.View;
40 import android.widget.Button;
41 import android.widget.ProgressBar;
42 import android.widget.TextView;
43 
44 import java.util.List;
45 
46 /**
47  * This activity corresponds to a download progress screen that is displayed
48  * when the user tries
49  * to install an application bundled as an apk file. The result of the application install
50  * is indicated in the result code that gets set to the corresponding installation status
51  * codes defined in PackageManager. If the package being installed already exists,
52  * the existing package is replaced with the new one.
53  */
54 public class InstallAppProgress extends Activity implements View.OnClickListener, OnCancelListener {
55     private final String TAG="InstallAppProgress";
56     private boolean localLOGV = false;
57     private ApplicationInfo mAppInfo;
58     private Uri mPackageURI;
59     private ProgressBar mProgressBar;
60     private View mOkPanel;
61     private TextView mStatusTextView;
62     private TextView mExplanationTextView;
63     private Button mDoneButton;
64     private Button mLaunchButton;
65     private final int INSTALL_COMPLETE = 1;
66     private Intent mLaunchIntent;
67     private static final int DLG_OUT_OF_SPACE = 1;
68     private CharSequence mLabel;
69 
70     private Handler mHandler = new Handler() {
71         public void handleMessage(Message msg) {
72             switch (msg.what) {
73                 case INSTALL_COMPLETE:
74                     if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
75                         Intent result = new Intent();
76                         result.putExtra(Intent.EXTRA_INSTALL_RESULT, msg.arg1);
77                         setResult(msg.arg1 == PackageManager.INSTALL_SUCCEEDED
78                                 ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER,
79                                         result);
80                         finish();
81                         return;
82                     }
83                     // Update the status text
84                     mProgressBar.setVisibility(View.INVISIBLE);
85                     // Show the ok button
86                     int centerTextLabel;
87                     int centerExplanationLabel = -1;
88                     LevelListDrawable centerTextDrawable = (LevelListDrawable) getResources()
89                             .getDrawable(R.drawable.ic_result_status);
90                     if (msg.arg1 == PackageManager.INSTALL_SUCCEEDED) {
91                         mLaunchButton.setVisibility(View.VISIBLE);
92                         centerTextDrawable.setLevel(0);
93                         centerTextLabel = R.string.install_done;
94                         // Enable or disable launch button
95                         mLaunchIntent = getPackageManager().getLaunchIntentForPackage(
96                                 mAppInfo.packageName);
97                         boolean enabled = false;
98                         if(mLaunchIntent != null) {
99                             List<ResolveInfo> list = getPackageManager().
100                                     queryIntentActivities(mLaunchIntent, 0);
101                             if (list != null && list.size() > 0) {
102                                 enabled = true;
103                             }
104                         }
105                         if (enabled) {
106                             mLaunchButton.setOnClickListener(InstallAppProgress.this);
107                         } else {
108                             mLaunchButton.setEnabled(false);
109                         }
110                     } else if (msg.arg1 == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
111                         showDialogInner(DLG_OUT_OF_SPACE);
112                         return;
113                     } else {
114                         // Generic error handling for all other error codes.
115                         centerTextDrawable.setLevel(1);
116                         centerExplanationLabel = getExplanationFromErrorCode(msg.arg1);
117                         centerTextLabel = R.string.install_failed;
118                         mLaunchButton.setVisibility(View.INVISIBLE);
119                     }
120                     if (centerTextDrawable != null) {
121                     centerTextDrawable.setBounds(0, 0,
122                             centerTextDrawable.getIntrinsicWidth(),
123                             centerTextDrawable.getIntrinsicHeight());
124                         mStatusTextView.setCompoundDrawables(centerTextDrawable, null, null, null);
125                     }
126                     mStatusTextView.setText(centerTextLabel);
127                     if (centerExplanationLabel != -1) {
128                         mExplanationTextView.setText(centerExplanationLabel);
129                         mExplanationTextView.setVisibility(View.VISIBLE);
130                     } else {
131                         mExplanationTextView.setVisibility(View.GONE);
132                     }
133                     mDoneButton.setOnClickListener(InstallAppProgress.this);
134                     mOkPanel.setVisibility(View.VISIBLE);
135                     break;
136                 default:
137                     break;
138             }
139         }
140     };
141 
getExplanationFromErrorCode(int errCode)142     private int getExplanationFromErrorCode(int errCode) {
143         Log.d(TAG, "Installation error code: " + errCode);
144         switch (errCode) {
145             case PackageManager.INSTALL_FAILED_INVALID_APK:
146                 return R.string.install_failed_invalid_apk;
147             case PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES:
148                 return R.string.install_failed_inconsistent_certificates;
149             case PackageManager.INSTALL_FAILED_OLDER_SDK:
150                 return R.string.install_failed_older_sdk;
151             case PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE:
152                 return R.string.install_failed_cpu_abi_incompatible;
153             default:
154                 return -1;
155         }
156     }
157 
158     @Override
onCreate(Bundle icicle)159     public void onCreate(Bundle icicle) {
160         super.onCreate(icicle);
161         Intent intent = getIntent();
162         mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
163         mPackageURI = intent.getData();
164         initView();
165     }
166 
167     @Override
onCreateDialog(int id, Bundle bundle)168     public Dialog onCreateDialog(int id, Bundle bundle) {
169         switch (id) {
170         case DLG_OUT_OF_SPACE:
171             String dlgText = getString(R.string.out_of_space_dlg_text, mLabel);
172             return new AlertDialog.Builder(this)
173                     .setTitle(R.string.out_of_space_dlg_title)
174                     .setMessage(dlgText)
175                     .setPositiveButton(R.string.manage_applications, new DialogInterface.OnClickListener() {
176                         public void onClick(DialogInterface dialog, int which) {
177                             //launch manage applications
178                             Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE");
179                             startActivity(intent);
180                             finish();
181                         }
182                     })
183                     .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
184                         public void onClick(DialogInterface dialog, int which) {
185                             Log.i(TAG, "Canceling installation");
186                             finish();
187                         }
188                     })
189                     .setOnCancelListener(this)
190                     .create();
191         }
192        return null;
193    }
194 
195     private void showDialogInner(int id) {
196         removeDialog(id);
197         showDialog(id);
198     }
199 
200     class PackageInstallObserver extends IPackageInstallObserver.Stub {
201         public void packageInstalled(String packageName, int returnCode) {
202             Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
203             msg.arg1 = returnCode;
204             mHandler.sendMessage(msg);
205         }
206     }
207 
208     public void initView() {
209         setContentView(R.layout.op_progress);
210         int installFlags = 0;
211         PackageManager pm = getPackageManager();
212         try {
213             PackageInfo pi = pm.getPackageInfo(mAppInfo.packageName,
214                     PackageManager.GET_UNINSTALLED_PACKAGES);
215             if(pi != null) {
216                 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
217             }
218         } catch (NameNotFoundException e) {
219         }
220         if((installFlags & PackageManager.INSTALL_REPLACE_EXISTING )!= 0) {
221             Log.w(TAG, "Replacing package:" + mAppInfo.packageName);
222         }
223         PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, mAppInfo,
224                 mPackageURI);
225         mLabel = as.label;
226         PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
227         mStatusTextView = (TextView)findViewById(R.id.center_text);
228         mStatusTextView.setText(R.string.installing);
229         mExplanationTextView = (TextView) findViewById(R.id.center_explanation);
230         mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
231         mProgressBar.setIndeterminate(true);
232         // Hide button till progress is being displayed
233         mOkPanel = (View)findViewById(R.id.buttons_panel);
234         mDoneButton = (Button)findViewById(R.id.done_button);
235         mLaunchButton = (Button)findViewById(R.id.launch_button);
236         mOkPanel.setVisibility(View.INVISIBLE);
237 
238         String installerPackageName = getIntent().getStringExtra(
239                 Intent.EXTRA_INSTALLER_PACKAGE_NAME);
240         PackageInstallObserver observer = new PackageInstallObserver();
241         pm.installPackage(mPackageURI, observer, installFlags, installerPackageName);
242     }
243 
244     @Override
245     protected void onDestroy() {
246         super.onDestroy();
247     }
248 
249     public void onClick(View v) {
250         if(v == mDoneButton) {
251             if (mAppInfo.packageName != null) {
252                 Log.i(TAG, "Finished installing "+mAppInfo.packageName);
253             }
254             finish();
255         } else if(v == mLaunchButton) {
256             startActivity(mLaunchIntent);
257             finish();
258         }
259     }
260 
261     public void onCancel(DialogInterface dialog) {
262         finish();
263     }
264 }
265