Home | History | Annotate | Download | only in app
      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 android.Manifest;
     20 import android.app.AlertDialog;
     21 import android.content.DialogInterface;
     22 import android.content.Intent;
     23 import android.content.pm.PackageManager;
     24 import android.content.pm.ResolveInfo;
     25 import android.os.Bundle;
     26 import android.os.UserHandle;
     27 import android.util.Slog;
     28 import android.view.WindowManager;
     29 
     30 import com.android.internal.R;
     31 
     32 public class SuspendedAppActivity extends AlertActivity
     33         implements DialogInterface.OnClickListener {
     34     private static final String TAG = "SuspendedAppActivity";
     35     public static final String EXTRA_SUSPENDED_PACKAGE =
     36             "SuspendedAppActivity.extra.SUSPENDED_PACKAGE";
     37     public static final String EXTRA_SUSPENDING_PACKAGE =
     38             "SuspendedAppActivity.extra.SUSPENDING_PACKAGE";
     39     public static final String EXTRA_DIALOG_MESSAGE = "SuspendedAppActivity.extra.DIALOG_MESSAGE";
     40 
     41     private Intent mMoreDetailsIntent;
     42     private int mUserId;
     43     private PackageManager mPm;
     44 
     45     private CharSequence getAppLabel(String packageName) {
     46         try {
     47             return mPm.getApplicationInfoAsUser(packageName, 0, mUserId).loadLabel(mPm);
     48         } catch (PackageManager.NameNotFoundException ne) {
     49             Slog.e(TAG, "Package " + packageName + " not found", ne);
     50         }
     51         return packageName;
     52     }
     53 
     54     private Intent getMoreDetailsActivity(String suspendingPackage, String suspendedPackage,
     55             int userId) {
     56         final Intent moreDetailsIntent = new Intent(Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS)
     57                 .setPackage(suspendingPackage);
     58         final String requiredPermission = Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
     59         final ResolveInfo resolvedInfo = mPm.resolveActivityAsUser(moreDetailsIntent, 0, userId);
     60         if (resolvedInfo != null && resolvedInfo.activityInfo != null
     61                 && requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
     62             moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
     63                     .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
     64             return moreDetailsIntent;
     65         }
     66         return null;
     67     }
     68 
     69     @Override
     70     public void onCreate(Bundle icicle) {
     71         super.onCreate(icicle);
     72         mPm = getPackageManager();
     73         getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
     74 
     75         final Intent intent = getIntent();
     76         mUserId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1);
     77         if (mUserId < 0) {
     78             Slog.wtf(TAG, "Invalid user: " + mUserId);
     79             finish();
     80             return;
     81         }
     82         final String suppliedMessage = intent.getStringExtra(EXTRA_DIALOG_MESSAGE);
     83         final String suspendedPackage = intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE);
     84         final String suspendingPackage = intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE);
     85         final CharSequence suspendedAppLabel = getAppLabel(suspendedPackage);
     86         final CharSequence dialogMessage;
     87         if (suppliedMessage == null) {
     88             dialogMessage = getString(R.string.app_suspended_default_message, suspendedAppLabel,
     89                     getAppLabel(suspendingPackage));
     90         } else {
     91             dialogMessage = String.format(getResources().getConfiguration().getLocales().get(0),
     92                     suppliedMessage, suspendedAppLabel);
     93         }
     94 
     95         final AlertController.AlertParams ap = mAlertParams;
     96         ap.mTitle = getString(R.string.app_suspended_title);
     97         ap.mMessage = dialogMessage;
     98         ap.mPositiveButtonText = getString(android.R.string.ok);
     99         mMoreDetailsIntent = getMoreDetailsActivity(suspendingPackage, suspendedPackage, mUserId);
    100         if (mMoreDetailsIntent != null) {
    101             ap.mNeutralButtonText = getString(R.string.app_suspended_more_details);
    102         }
    103         ap.mPositiveButtonListener = ap.mNeutralButtonListener = this;
    104         setupAlert();
    105     }
    106 
    107     @Override
    108     public void onClick(DialogInterface dialog, int which) {
    109         switch (which) {
    110             case AlertDialog.BUTTON_NEUTRAL:
    111                 startActivityAsUser(mMoreDetailsIntent, UserHandle.of(mUserId));
    112                 Slog.i(TAG, "Started more details activity");
    113                 break;
    114         }
    115         finish();
    116     }
    117 
    118     public static Intent createSuspendedAppInterceptIntent(String suspendedPackage,
    119             String suspendingPackage, String dialogMessage, int userId) {
    120         return new Intent()
    121                 .setClassName("android", SuspendedAppActivity.class.getName())
    122                 .putExtra(EXTRA_SUSPENDED_PACKAGE, suspendedPackage)
    123                 .putExtra(EXTRA_DIALOG_MESSAGE, dialogMessage)
    124                 .putExtra(EXTRA_SUSPENDING_PACKAGE, suspendingPackage)
    125                 .putExtra(Intent.EXTRA_USER_ID, userId)
    126                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
    127                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    128     }
    129 }
    130