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