1 /* 2 * Copyright (C) 2012 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.settings; 18 19 import android.appwidget.AppWidgetManager; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.DialogInterface; 23 import android.content.Intent; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.PackageManager; 26 import android.os.Bundle; 27 import android.os.UserHandle; 28 import android.util.Log; 29 import android.view.LayoutInflater; 30 import android.widget.CheckBox; 31 32 import androidx.appcompat.app.AlertDialog; 33 34 import com.android.internal.app.AlertActivity; 35 import com.android.internal.app.AlertController; 36 37 /** 38 * This activity is displayed when an app launches the BIND_APPWIDGET intent. This allows apps 39 * that don't have the BIND_APPWIDGET permission to bind specific widgets. 40 */ 41 public class AllowBindAppWidgetActivity extends AlertActivity implements 42 DialogInterface.OnClickListener { 43 44 private CheckBox mAlwaysUse; 45 private int mAppWidgetId; 46 private Bundle mBindOptions; 47 private UserHandle mProfile; 48 private ComponentName mComponentName; 49 private String mCallingPackage; 50 private AppWidgetManager mAppWidgetManager; 51 52 // Indicates whether this activity was closed because of a click 53 private boolean mClicked; 54 onClick(DialogInterface dialog, int which)55 public void onClick(DialogInterface dialog, int which) { 56 mClicked = true; 57 if (which == AlertDialog.BUTTON_POSITIVE) { 58 if (mAppWidgetId != -1 && mComponentName != null && mCallingPackage != null) { 59 try { 60 final boolean bound = mAppWidgetManager.bindAppWidgetIdIfAllowed(mAppWidgetId, 61 mProfile, mComponentName, mBindOptions); 62 if (bound) { 63 Intent result = new Intent(); 64 result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); 65 setResult(RESULT_OK, result); 66 } 67 } catch (Exception e) { 68 Log.v("BIND_APPWIDGET", "Error binding widget with id " 69 + mAppWidgetId + " and component " + mComponentName); 70 } 71 72 final boolean alwaysAllowBind = mAlwaysUse.isChecked(); 73 if (alwaysAllowBind != mAppWidgetManager.hasBindAppWidgetPermission( 74 mCallingPackage)) { 75 mAppWidgetManager.setBindAppWidgetPermission(mCallingPackage, 76 alwaysAllowBind); 77 } 78 } 79 } 80 finish(); 81 } 82 83 @Override onPause()84 protected void onPause() { 85 if (!mClicked) { // RESULT_CANCELED 86 finish(); 87 } 88 super.onPause(); 89 } 90 91 @Override onCreate(Bundle savedInstanceState)92 protected void onCreate(Bundle savedInstanceState) { 93 super.onCreate(savedInstanceState); 94 setResult(RESULT_CANCELED); // By default, set the result to cancelled 95 Intent intent = getIntent(); 96 CharSequence label = ""; 97 if (intent != null) { 98 try { 99 mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); 100 mProfile = intent.getParcelableExtra( 101 AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE); 102 if (mProfile == null) { 103 mProfile = android.os.Process.myUserHandle(); 104 } 105 mComponentName = 106 intent.getParcelableExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER); 107 mBindOptions = 108 intent.getParcelableExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS); 109 mCallingPackage = getCallingPackage(); 110 PackageManager pm = getPackageManager(); 111 ApplicationInfo ai = pm.getApplicationInfo(mCallingPackage, 0); 112 label = pm.getApplicationLabel(ai); 113 } catch (Exception e) { 114 mAppWidgetId = -1; 115 mComponentName = null; 116 mCallingPackage = null; 117 Log.v("BIND_APPWIDGET", "Error getting parameters"); 118 finish(); 119 return; 120 } 121 } 122 AlertController.AlertParams ap = mAlertParams; 123 ap.mTitle = getString(R.string.allow_bind_app_widget_activity_allow_bind_title); 124 ap.mMessage = getString(R.string.allow_bind_app_widget_activity_allow_bind, label); 125 ap.mPositiveButtonText = getString(R.string.create); 126 ap.mNegativeButtonText = getString(android.R.string.cancel); 127 ap.mPositiveButtonListener = this; 128 ap.mNegativeButtonListener = this; 129 LayoutInflater inflater = 130 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 131 ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null); 132 mAlwaysUse = (CheckBox) ap.mView.findViewById(com.android.internal.R.id.alwaysUse); 133 mAlwaysUse.setText(getString(R.string.allow_bind_app_widget_activity_always_allow_bind, label)); 134 135 mAlwaysUse.setPadding(mAlwaysUse.getPaddingLeft(), 136 mAlwaysUse.getPaddingTop(), 137 mAlwaysUse.getPaddingRight(), 138 (int) (mAlwaysUse.getPaddingBottom() + 139 getResources().getDimension(R.dimen.bind_app_widget_dialog_checkbox_bottom_padding))); 140 141 mAppWidgetManager = AppWidgetManager.getInstance(this); 142 mAlwaysUse.setChecked(mAppWidgetManager.hasBindAppWidgetPermission(mCallingPackage, 143 mProfile.getIdentifier())); 144 145 setupAlert(); 146 } 147 } 148