• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GrantPermissionsWatchViewHandler(Context context)56     GrantPermissionsWatchViewHandler(Context context) {
57         mContext = context;
58     }
59 
60     @Override
setResultListener(ResultListener listener)61     public GrantPermissionsWatchViewHandler setResultListener(ResultListener listener) {
62         mResultListener = listener;
63         return this;
64     }
65 
66     @Override
createView()67     public View createView() {
68         return new Space(mContext);
69     }
70 
71     @Override
updateWindowAttributes(WindowManager.LayoutParams outLayoutParams)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
updateUi(String groupName, int groupCount, int groupIndex, Icon icon, CharSequence message, boolean showDoNotAsk)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 
showDialog(Bundle savedInstanceState)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
saveInstanceState(Bundle outState)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
loadInstanceState(Bundle savedInstanceState)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
onBackPressed()185     public void onBackPressed() {
186         notifyListener(false, false);
187     }
188 
189     @Override
onClick(DialogInterface dialog, int which)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 
notifyListener(boolean granted, boolean doNotAskAgain)206     private void notifyListener(boolean granted, boolean doNotAskAgain) {
207         if (mResultListener != null) {
208             mResultListener.onPermissionGrantResult(mGroupName, granted, doNotAskAgain);
209         }
210     }
211 }
212