InstallFailed.java revision 74fa089b8c39d84b737607a3e3d2cde4d3b42d24
1327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann/* 2327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * Copyright (C) 2016 The Android Open Source Project 3327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * 4327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License"); 5327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * you may not use this file except in compliance with the License. 6327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * You may obtain a copy of the License at 7327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * 8327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * http://www.apache.org/licenses/LICENSE-2.0 9327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * 10327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * Unless required by applicable law or agreed to in writing, software 11327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS, 12327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * See the License for the specific language governing permissions and 14327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * limitations under the License. 15327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann */ 16327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 17327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannpackage com.android.packageinstaller; 18327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 19327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.app.Activity; 20327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.app.AlertDialog; 21327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.app.Dialog; 22327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.app.DialogFragment; 23327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.content.Context; 24327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.content.DialogInterface; 25327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.content.Intent; 26327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.content.pm.ApplicationInfo; 27327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.content.pm.PackageInstaller; 28327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.content.pm.PackageManager; 29327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.net.Uri; 30327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.os.Bundle; 3174fa089b8c39d84b737607a3e3d2cde4d3b42d24Philip P. Moltmannimport android.support.annotation.Nullable; 32327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.util.Log; 33327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.view.View; 34327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport android.widget.TextView; 35327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 36327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannimport java.io.File; 37327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 38327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann/** 39327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * Installation failed: Return status code to the caller or display failure UI to user 40327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann */ 41327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmannpublic class InstallFailed extends Activity { 42327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann private static final String LOG_TAG = InstallFailed.class.getSimpleName(); 43327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 44327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann /** Label of the app that failed to install */ 45327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann private CharSequence mLabel; 46327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 47327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann /** 48327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * Convert an package installer status code into the user friendly label. 49327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * 50327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * @param statusCode The status code from the package installer. 51327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * 52327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * @return The user friendly label for the status code 53327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann */ 54327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann private int getExplanationFromErrorCode(int statusCode) { 55327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann Log.d(LOG_TAG, "Installation status code: " + statusCode); 56327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 57327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann switch (statusCode) { 58327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann case PackageInstaller.STATUS_FAILURE_BLOCKED: 59327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann return R.string.install_failed_blocked; 60327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann case PackageInstaller.STATUS_FAILURE_CONFLICT: 61327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann return R.string.install_failed_conflict; 62327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE: 63327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann return R.string.install_failed_incompatible; 64327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann case PackageInstaller.STATUS_FAILURE_INVALID: 65327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann return R.string.install_failed_invalid_apk; 66327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann default: 67327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann return R.string.install_failed; 68327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 69327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 70327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 71327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann @Override 72327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann protected void onCreate(@Nullable Bundle savedInstanceState) { 73327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann super.onCreate(savedInstanceState); 74327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 75327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann int statusCode = getIntent().getIntExtra(PackageInstaller.EXTRA_STATUS, 76327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann PackageInstaller.STATUS_FAILURE); 77327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 78327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { 79ac9155b2b20164da52cdc0d82a6ab5c3a9d7ec38Philip P. Moltmann int legacyStatus = getIntent().getIntExtra(PackageInstaller.EXTRA_LEGACY_STATUS, 80ac9155b2b20164da52cdc0d82a6ab5c3a9d7ec38Philip P. Moltmann PackageManager.INSTALL_FAILED_INTERNAL_ERROR); 81ac9155b2b20164da52cdc0d82a6ab5c3a9d7ec38Philip P. Moltmann 82327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Return result if requested 83327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann Intent result = new Intent(); 84ac9155b2b20164da52cdc0d82a6ab5c3a9d7ec38Philip P. Moltmann result.putExtra(Intent.EXTRA_INSTALL_RESULT, legacyStatus); 85327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann setResult(Activity.RESULT_FIRST_USER, result); 86327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann finish(); 87327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } else { 88327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann Intent intent = getIntent(); 89327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann ApplicationInfo appInfo = intent 90327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); 91327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann Uri packageURI = intent.getData(); 92327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 93327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann setContentView(R.layout.install_failed); 94327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 95327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Set header icon and title 96327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann PackageUtil.AppSnippet as; 97327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann PackageManager pm = getPackageManager(); 98327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 99327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann if ("package".equals(packageURI.getScheme())) { 100327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo), 101327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann pm.getApplicationIcon(appInfo)); 102327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } else { 103327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann final File sourceFile = new File(packageURI.getPath()); 104327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann as = PackageUtil.getAppSnippet(this, appInfo, sourceFile); 105327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 106327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 107327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Store label for dialog 108327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann mLabel = as.label; 109327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 110327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); 111327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 112327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Show out of space dialog if needed 113327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann if (statusCode == PackageInstaller.STATUS_FAILURE_STORAGE) { 114327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann (new OutOfSpaceDialog()).show(getFragmentManager(), "outofspace"); 115327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 116327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 117327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Get status messages 118327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann int statusLabel = getExplanationFromErrorCode(statusCode); 119327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann String extendedStatusMessage = getIntent() 120327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE); 121327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 122327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Show simple or extended failure screen 123327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann if (extendedStatusMessage == null) { 124327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann ((TextView) findViewById(R.id.simple_status)).setText(statusLabel); 125327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } else { 126327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Switch from simple failure screen to extended view 127327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann findViewById(R.id.simple_status_view).setVisibility(View.GONE); 128327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann findViewById(R.id.extended_status_view).setVisibility(View.VISIBLE); 129327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 130327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann ((TextView) findViewById(R.id.extended_status)).setText(statusLabel); 131327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann ((TextView) findViewById(R.id.extended_status_message)) 132327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .setText(extendedStatusMessage); 133327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 134327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 135327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // Set up "done" button 136327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann findViewById(R.id.done_button).setOnClickListener(view -> finish()); 137327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 138327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 139327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 140327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann /** 141327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * Dialog shown when we ran out of space during installation. This contains a link to the 142327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann * "manage applications" settings page. 143327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann */ 144327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann public static class OutOfSpaceDialog extends DialogFragment { 145327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann private InstallFailed mActivity; 146327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 147327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann @Override 148327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann public void onAttach(Context context) { 149327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann super.onAttach(context); 150327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 151327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann mActivity = (InstallFailed) context; 152327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 153327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 154327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann @Override 155327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann public Dialog onCreateDialog(Bundle savedInstanceState) { 156327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann return new AlertDialog.Builder(mActivity) 157327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .setTitle(R.string.out_of_space_dlg_title) 158327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .setMessage(getString(R.string.out_of_space_dlg_text, mActivity.mLabel)) 159327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .setPositiveButton(R.string.manage_applications, (dialog, which) -> { 160327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann // launch manage applications 161327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE"); 162327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann startActivity(intent); 163327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann mActivity.finish(); 164327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann }) 165327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .setNegativeButton(R.string.cancel, (dialog, which) -> mActivity.finish()) 166327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann .create(); 167327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 168327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 169327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann @Override 170327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann public void onCancel(DialogInterface dialog) { 171327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann super.onCancel(dialog); 172327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann 173327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann mActivity.finish(); 174327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 175327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann } 176327a359bc96d8b532362fe966a451188f307b7cfPhilip P. Moltmann} 177