1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 package com.android.packageinstaller;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.content.ActivityNotFoundException;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.PackageManager;
26 import android.content.pm.ResolveInfo;
27 import android.os.Bundle;
28 import android.util.Log;
29 import android.view.View;
30 import android.widget.Button;
31 
32 import androidx.annotation.Nullable;
33 
34 import java.util.List;
35 
36 /**
37  * Finish installation: Return status code to the caller or display "success" UI to user
38  */
39 public class InstallSuccess extends Activity {
40     private static final String LOG_TAG = InstallSuccess.class.getSimpleName();
41 
42     @Nullable
43     private PackageUtil.AppSnippet mAppSnippet;
44 
45     @Nullable
46     private String mAppPackageName;
47 
48     @Nullable
49     private Intent mLaunchIntent;
50 
51     private AlertDialog mDialog;
52 
53     @Override
onCreate(@ullable Bundle savedInstanceState)54     protected void onCreate(@Nullable Bundle savedInstanceState) {
55         super.onCreate(savedInstanceState);
56 
57         setFinishOnTouchOutside(true);
58 
59         if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
60             // Return result if requested
61             Intent result = new Intent();
62             result.putExtra(Intent.EXTRA_INSTALL_RESULT, PackageManager.INSTALL_SUCCEEDED);
63             setResult(Activity.RESULT_OK, result);
64             finish();
65         } else {
66             Intent intent = getIntent();
67             ApplicationInfo appInfo =
68                     intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
69             mAppPackageName = appInfo.packageName;
70             mAppSnippet = intent.getParcelableExtra(PackageInstallerActivity.EXTRA_APP_SNIPPET,
71                     PackageUtil.AppSnippet.class);
72 
73             mLaunchIntent = getPackageManager().getLaunchIntentForPackage(mAppPackageName);
74 
75             bindUi();
76         }
77     }
78 
79     @Override
onResume()80     protected void onResume() {
81         super.onResume();
82         bindUi();
83     }
84 
bindUi()85     private void bindUi() {
86         if (mAppSnippet == null) {
87             return;
88         }
89 
90         AlertDialog.Builder builder = new AlertDialog.Builder(this);
91         builder.setIcon(mAppSnippet.icon);
92         builder.setTitle(mAppSnippet.label);
93         builder.setView(R.layout.install_content_view);
94         builder.setPositiveButton(getString(R.string.launch), null);
95         builder.setNegativeButton(getString(R.string.done),
96                 (ignored, ignored2) -> {
97                     if (mAppPackageName != null) {
98                         Log.i(LOG_TAG, "Finished installing " + mAppPackageName);
99                     }
100                     finish();
101                 });
102         builder.setOnCancelListener(dialog -> {
103             if (mAppPackageName != null) {
104                 Log.i(LOG_TAG, "Finished installing " + mAppPackageName);
105             }
106             finish();
107         });
108         mDialog = builder.create();
109         mDialog.show();
110         mDialog.requireViewById(R.id.install_success).setVisibility(View.VISIBLE);
111         // Show or hide "launch" button
112         boolean visible = false;
113         if (mLaunchIntent != null) {
114             List<ResolveInfo> list = getPackageManager().queryIntentActivities(mLaunchIntent,
115                     0);
116             if (list != null && list.size() > 0) {
117                 visible = true;
118             }
119         }
120         visible = visible && isLauncherActivityEnabled(mLaunchIntent);
121 
122         Button launchButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
123         if (visible) {
124             launchButton.setOnClickListener(view -> {
125                 try {
126                     startActivity(mLaunchIntent.addFlags(
127                         Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP));
128                 } catch (ActivityNotFoundException | SecurityException e) {
129                     Log.e(LOG_TAG, "Could not start activity", e);
130                 }
131                 finish();
132             });
133         } else {
134             launchButton.setVisibility(View.GONE);
135         }
136     }
137 
isLauncherActivityEnabled(Intent intent)138     private boolean isLauncherActivityEnabled(Intent intent) {
139         if (intent == null || intent.getComponent() == null) {
140             return false;
141         }
142         return getPackageManager().getComponentEnabledSetting(intent.getComponent())
143             != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
144     }
145 }
146