Home | History | Annotate | Download | only in ui
      1 package com.android.packageinstaller.permission.ui;
      2 
      3 import android.app.AlertDialog;
      4 import android.app.Dialog;
      5 import android.content.Context;
      6 import android.content.DialogInterface;
      7 import android.content.res.TypedArray;
      8 import android.graphics.drawable.Drawable;
      9 import android.graphics.drawable.Icon;
     10 import android.graphics.PixelFormat;
     11 import android.graphics.PorterDuff;
     12 import android.os.Bundle;
     13 import android.support.wearable.view.AcceptDenyDialog;
     14 import android.support.wearable.view.WearableDialogHelper;
     15 import android.text.SpannableStringBuilder;
     16 import android.text.Spanned;
     17 import android.text.style.ImageSpan;
     18 import android.text.style.TextAppearanceSpan;
     19 import android.text.TextUtils;
     20 import android.util.Log;
     21 import android.view.LayoutInflater;
     22 import android.view.View;
     23 import android.view.WindowManager;
     24 import android.widget.Space;
     25 
     26 import com.android.packageinstaller.R;
     27 
     28 /**
     29  * Watch-specific view handler for the grant permissions activity.
     30  */
     31 final class GrantPermissionsWatchViewHandler implements GrantPermissionsViewHandler,
     32         DialogInterface.OnClickListener {
     33     private static final String TAG = "GrantPermsWatchViewH";
     34 
     35     private static final String WATCH_HANDLER_BUNDLE = "watch_handler_bundle";
     36     private static final String DIALOG_BUNDLE = "dialog_bundle";
     37     private static final String GROUP_NAME = "group_name";
     38     private static final String SHOW_DO_NOT_ASK = "show_do_not_ask";
     39     private static final String ICON = "icon";
     40     private static final String MESSAGE = "message";
     41     private static final String CURRENT_PAGE_TEXT = "current_page_text";
     42 
     43     private final Context mContext;
     44 
     45     private ResultListener mResultListener;
     46 
     47     private Dialog mDialog;
     48 
     49     private String mGroupName;
     50     private boolean mShowDoNotAsk;
     51 
     52     private CharSequence mMessage;
     53     private String mCurrentPageText;
     54     private Icon mIcon;
     55 
     56     GrantPermissionsWatchViewHandler(Context context) {
     57         mContext = context;
     58     }
     59 
     60     @Override
     61     public GrantPermissionsWatchViewHandler setResultListener(ResultListener listener) {
     62         mResultListener = listener;
     63         return this;
     64     }
     65 
     66     @Override
     67     public View createView() {
     68         return new Space(mContext);
     69     }
     70 
     71     @Override
     72     public void updateWindowAttributes(WindowManager.LayoutParams outLayoutParams) {
     73         outLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
     74         outLayoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
     75         outLayoutParams.format = PixelFormat.OPAQUE;
     76         outLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
     77         outLayoutParams.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
     78     }
     79 
     80     @Override
     81     public void updateUi(String groupName, int groupCount, int groupIndex, Icon icon,
     82             CharSequence message, boolean showDoNotAsk) {
     83         if (Log.isLoggable(TAG, Log.DEBUG)) {
     84             Log.d(TAG, "updateUi() - groupName: " + groupName
     85                             + ", groupCount: " + groupCount
     86                             + ", groupIndex: " + groupIndex
     87                             + ", icon: " + icon
     88                             + ", message: " + message
     89                             + ", showDoNotAsk: " + showDoNotAsk);
     90         }
     91 
     92         mGroupName = groupName;
     93         mShowDoNotAsk = showDoNotAsk;
     94         mMessage = message;
     95         mIcon = icon;
     96         mCurrentPageText = groupCount > 1
     97                 ? mContext.getString(R.string.current_permission_template,
     98                         groupIndex + 1, groupCount)
     99                 : null;
    100         showDialog(null);
    101     }
    102 
    103     private void showDialog(Bundle savedInstanceState) {
    104         TypedArray a = mContext.obtainStyledAttributes(
    105                 new int[] { android.R.attr.textColorPrimary });
    106         int color = a.getColor(0, mContext.getColor(android.R.color.white));
    107         a.recycle();
    108         Drawable drawable = mIcon == null ? null : mIcon.setTint(color).loadDrawable(mContext);
    109 
    110         SpannableStringBuilder ssb = new SpannableStringBuilder();
    111         if (!TextUtils.isEmpty(mCurrentPageText)) {
    112             ssb.append(mCurrentPageText, new TextAppearanceSpan(mContext, R.style.BreadcrumbText),
    113                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    114             ssb.append('\n');
    115         }
    116         if (!TextUtils.isEmpty(mMessage)) {
    117             ssb.append(mMessage, new TextAppearanceSpan(mContext, R.style.TitleText),
    118                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    119         }
    120 
    121         if (mDialog != null) {
    122             mDialog.dismiss();
    123             mDialog = null;
    124         }
    125 
    126         if (mShowDoNotAsk) {
    127             AlertDialog alertDialog = new WearableDialogHelper.DialogBuilder(mContext)
    128                     .setPositiveIcon(R.drawable.confirm_button)
    129                     .setNeutralIcon(R.drawable.cancel_button)
    130                     .setNegativeIcon(R.drawable.deny_button)
    131                     .setTitle(ssb)
    132                     .setIcon(drawable)
    133                     .setPositiveButton(R.string.grant_dialog_button_allow, this)
    134                     .setNeutralButton(R.string.grant_dialog_button_deny, this)
    135                     .setNegativeButton(R.string.grant_dialog_button_deny_dont_ask_again, this)
    136                     .show();
    137             alertDialog.getButton(DialogInterface.BUTTON_POSITIVE)
    138                     .setId(R.id.permission_allow_button);
    139             alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL)
    140                     .setId(R.id.permission_deny_button);
    141             alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE)
    142                     .setId(R.id.permission_deny_dont_ask_again_button);
    143 
    144             mDialog = alertDialog;
    145         } else {
    146             AcceptDenyDialog acceptDenyDialog = new AcceptDenyDialog(mContext);
    147             acceptDenyDialog.setTitle(ssb);
    148             acceptDenyDialog.setIcon(drawable);
    149             acceptDenyDialog.setPositiveButton(this);
    150             acceptDenyDialog.setNegativeButton(this);
    151             acceptDenyDialog.show();
    152             acceptDenyDialog.getButton(DialogInterface.BUTTON_POSITIVE)
    153                     .setId(R.id.permission_allow_button);
    154             acceptDenyDialog.getButton(DialogInterface.BUTTON_NEGATIVE)
    155                     .setId(R.id.permission_deny_button);
    156 
    157             mDialog = acceptDenyDialog;
    158         }
    159         mDialog.setCancelable(false);
    160 
    161         if (savedInstanceState != null) {
    162             mDialog.onRestoreInstanceState(savedInstanceState);
    163         }
    164     }
    165 
    166     @Override
    167     public void saveInstanceState(Bundle outState) {
    168         Bundle b = new Bundle();
    169         b.putByte(SHOW_DO_NOT_ASK, (byte) (mShowDoNotAsk ? 1 : 0));
    170         b.putString(GROUP_NAME, mGroupName);
    171         b.putBundle(DIALOG_BUNDLE, mDialog.onSaveInstanceState());
    172 
    173         outState.putBundle(WATCH_HANDLER_BUNDLE, b);
    174     }
    175 
    176     @Override
    177     public void loadInstanceState(Bundle savedInstanceState) {
    178         Bundle b = savedInstanceState.getBundle(WATCH_HANDLER_BUNDLE);
    179         mShowDoNotAsk = b.getByte(SHOW_DO_NOT_ASK) == 1;
    180         mGroupName = b.getString(GROUP_NAME);
    181         showDialog(b.getBundle(DIALOG_BUNDLE));
    182     }
    183 
    184     @Override
    185     public void onBackPressed() {
    186         notifyListener(false, false);
    187     }
    188 
    189     @Override
    190     public void onClick(DialogInterface dialog, int which) {
    191         switch (which) {
    192             case DialogInterface.BUTTON_POSITIVE:
    193                 notifyListener(true, false);
    194                 break;
    195             case DialogInterface.BUTTON_NEUTRAL:
    196                 notifyListener(false, false);
    197                 break;
    198             case DialogInterface.BUTTON_NEGATIVE:
    199                 notifyListener(false,
    200                         /* In AlertDialog, the negative button is also a don't ask again button. */
    201                         dialog instanceof AlertDialog);
    202                 break;
    203         }
    204     }
    205 
    206     private void notifyListener(boolean granted, boolean doNotAskAgain) {
    207         if (mResultListener != null) {
    208             mResultListener.onPermissionGrantResult(mGroupName, granted, doNotAskAgain);
    209         }
    210     }
    211 }
    212