1 /*
2  * Copyright (C) 2018 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.internal.app;
18 
19 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
20 
21 import android.app.ActivityOptions;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.Intent;
25 import android.content.IntentSender;
26 import android.content.pm.ApplicationInfo;
27 import android.content.pm.PackageItemInfo;
28 import android.content.pm.PackageManager;
29 import android.os.Bundle;
30 import android.util.Log;
31 import android.view.View;
32 import android.widget.TextView;
33 
34 import com.android.internal.R;
35 
36 /**
37  * This dialog is shown to the user before an activity in a harmful app is launched.
38  *
39  * See {@code PackageManager.setHarmfulAppInfo} for more info.
40  */
41 public class HarmfulAppWarningActivity extends AlertActivity implements
42         DialogInterface.OnClickListener {
43     private static final String TAG = HarmfulAppWarningActivity.class.getSimpleName();
44 
45     private static final String EXTRA_HARMFUL_APP_WARNING = "harmful_app_warning";
46 
47     private String mPackageName;
48     private String mHarmfulAppWarning;
49     private IntentSender mTarget;
50 
51     @Override
onCreate(Bundle savedInstanceState)52     protected void onCreate(Bundle savedInstanceState) {
53         super.onCreate(savedInstanceState);
54 
55         getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
56         final Intent intent = getIntent();
57         mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
58         mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class);
59         mHarmfulAppWarning = intent.getStringExtra(EXTRA_HARMFUL_APP_WARNING);
60 
61         if (mPackageName == null || mTarget == null || mHarmfulAppWarning == null) {
62             Log.wtf(TAG, "Invalid intent: " + intent.toString());
63             finish();
64         }
65 
66         final ApplicationInfo applicationInfo;
67         try {
68             applicationInfo = getPackageManager().getApplicationInfo(mPackageName, 0 /*flags*/);
69         } catch (PackageManager.NameNotFoundException e) {
70             Log.e(TAG, "Could not show warning because package does not exist ", e);
71             finish();
72             return;
73         }
74 
75         final AlertController.AlertParams p = mAlertParams;
76         p.mTitle = getString(R.string.harmful_app_warning_title);
77         p.mView = createView(applicationInfo);
78 
79         p.mPositiveButtonText = getString(R.string.harmful_app_warning_uninstall);
80         p.mPositiveButtonListener = this;
81         p.mNegativeButtonText = getString(R.string.harmful_app_warning_open_anyway);
82         p.mNegativeButtonListener = this;
83 
84         mAlert.installContent(mAlertParams);
85     }
86 
createView(ApplicationInfo applicationInfo)87     private View createView(ApplicationInfo applicationInfo) {
88         final View view = getLayoutInflater().inflate(R.layout.harmful_app_warning_dialog,
89                 null /*root*/);
90         ((TextView) view.findViewById(R.id.app_name_text))
91                 .setText(applicationInfo.loadSafeLabel(getPackageManager(),
92                         PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
93                         PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE
94                                 | PackageItemInfo.SAFE_LABEL_FLAG_TRIM));
95         ((TextView) view.findViewById(R.id.message))
96                 .setText(mHarmfulAppWarning);
97         return view;
98     }
99 
100     @Override
onClick(DialogInterface dialog, int which)101     public void onClick(DialogInterface dialog, int which) {
102         switch (which) {
103             case DialogInterface.BUTTON_POSITIVE:
104                 getPackageManager().deletePackage(mPackageName, null /*observer*/, 0 /*flags*/);
105                 EventLogTags.writeHarmfulAppWarningUninstall(mPackageName);
106                 finish();
107                 break;
108             case DialogInterface.BUTTON_NEGATIVE:
109                 getPackageManager().setHarmfulAppWarning(mPackageName, null /*warning*/);
110 
111                 final IntentSender target = getIntent().getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class);
112                 Bundle activityOptions =
113                         ActivityOptions.makeBasic()
114                                 .setPendingIntentBackgroundActivityStartMode(
115                                         ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
116                                 .toBundle();
117                 try {
118                     startIntentSenderForResult(target, -1 /*requestCode*/, null /*fillInIntent*/,
119                             0 /*flagsMask*/, 0 /*flagsValue*/, 0 /*extraFlags*/, activityOptions);
120                 } catch (IntentSender.SendIntentException e) {
121                     Log.e(TAG, "Error while starting intent sender", e);
122                 }
123                 EventLogTags.writeHarmfulAppWarningLaunchAnyway(mPackageName);
124                 finish();
125                 break;
126         }
127     }
128 
createHarmfulAppWarningIntent(Context context, String targetPackageName, IntentSender target, CharSequence harmfulAppWarning)129     public static Intent createHarmfulAppWarningIntent(Context context, String targetPackageName,
130             IntentSender target, CharSequence harmfulAppWarning) {
131         final Intent intent = new Intent();
132         intent.setClass(context, HarmfulAppWarningActivity.class);
133         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName);
134         intent.putExtra(Intent.EXTRA_INTENT, target);
135         intent.putExtra(EXTRA_HARMFUL_APP_WARNING, harmfulAppWarning);
136         return intent;
137     }
138 }
139