1c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka/*
2c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * Copyright (C) 2012 The Android Open Source Project
3c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka *
4c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * Licensed under the Apache License, Version 2.0 (the "License");
5c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * you may not use this file except in compliance with the License.
6c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * You may obtain a copy of the License at
7c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka *
8c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka *      http://www.apache.org/licenses/LICENSE-2.0
9c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka *
10c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * Unless required by applicable law or agreed to in writing, software
11c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * distributed under the License is distributed on an "AS IS" BASIS,
12c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * See the License for the specific language governing permissions and
14c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * limitations under the License.
15c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka */
16c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
17c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkapackage com.android.settings;
18c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
19c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.app.AlertDialog;
20c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.appwidget.AppWidgetManager;
21c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.content.ComponentName;
22c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.content.Context;
23c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.content.DialogInterface;
24c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.content.Intent;
25c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.content.pm.ApplicationInfo;
26c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.content.pm.PackageManager;
27c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.os.Bundle;
28c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganovimport android.os.UserHandle;
29c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.util.Log;
30c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.view.LayoutInflater;
31c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport android.widget.CheckBox;
32c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
33c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport com.android.internal.app.AlertActivity;
34c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkaimport com.android.internal.app.AlertController;
35c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
36c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka/**
37c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * This activity is displayed when an app launches the BIND_APPWIDGET intent. This allows apps
38c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka * that don't have the BIND_APPWIDGET permission to bind specific widgets.
39c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka */
40c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurkapublic class AllowBindAppWidgetActivity extends AlertActivity implements
41c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        DialogInterface.OnClickListener {
42c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
43c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    private CheckBox mAlwaysUse;
44c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    private int mAppWidgetId;
45e78499d6db2bbd11e92efb23294e8ef1e2538847Sunny Goyal    private Bundle mBindOptions;
46c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov    private UserHandle mProfile;
47c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    private ComponentName mComponentName;
48c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    private String mCallingPackage;
49c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    private AppWidgetManager mAppWidgetManager;
50c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
51c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    // Indicates whether this activity was closed because of a click
52c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    private boolean mClicked;
53c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
54c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    public void onClick(DialogInterface dialog, int which) {
55bd5729b7dc34882403512885b7ef69e8bf7ace0eMikhail Malakhov        mClicked = true;
56c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        if (which == AlertDialog.BUTTON_POSITIVE) {
57c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka            if (mAppWidgetId != -1 && mComponentName != null && mCallingPackage != null) {
58c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                try {
59c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                    final boolean bound = mAppWidgetManager.bindAppWidgetIdIfAllowed(mAppWidgetId,
60e78499d6db2bbd11e92efb23294e8ef1e2538847Sunny Goyal                            mProfile, mComponentName, mBindOptions);
61c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                    if (bound) {
62c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                        Intent result = new Intent();
63c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                        result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
64c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                        setResult(RESULT_OK, result);
65c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                    }
66c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                } catch (Exception e) {
67c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                    Log.v("BIND_APPWIDGET", "Error binding widget with id "
68c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                            + mAppWidgetId + " and component " + mComponentName);
69c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                }
70c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov
71c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                final boolean alwaysAllowBind = mAlwaysUse.isChecked();
72c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                if (alwaysAllowBind != mAppWidgetManager.hasBindAppWidgetPermission(
73c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                        mCallingPackage)) {
74c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                    mAppWidgetManager.setBindAppWidgetPermission(mCallingPackage,
75c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                            alwaysAllowBind);
76c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                }
77c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka            }
78c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        }
79c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        finish();
80c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    }
81c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
82bd5729b7dc34882403512885b7ef69e8bf7ace0eMikhail Malakhov    @Override
83c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov    protected void onPause() {
84bd5729b7dc34882403512885b7ef69e8bf7ace0eMikhail Malakhov        if (!mClicked) { // RESULT_CANCELED
85bd5729b7dc34882403512885b7ef69e8bf7ace0eMikhail Malakhov            finish();
86c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        }
87bd5729b7dc34882403512885b7ef69e8bf7ace0eMikhail Malakhov        super.onPause();
88c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    }
89c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
90bd5729b7dc34882403512885b7ef69e8bf7ace0eMikhail Malakhov    @Override
91c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    protected void onCreate(Bundle savedInstanceState) {
92c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        super.onCreate(savedInstanceState);
93bd5729b7dc34882403512885b7ef69e8bf7ace0eMikhail Malakhov        setResult(RESULT_CANCELED); // By default, set the result to cancelled
94c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        Intent intent = getIntent();
95c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        CharSequence label = "";
96c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        if (intent != null) {
97c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka            try {
98c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
99c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                mProfile = intent.getParcelableExtra(
100c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                        AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);
101c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                if (mProfile == null) {
102c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                    mProfile = android.os.Process.myUserHandle();
103c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                }
104c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                mComponentName =
105c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                        intent.getParcelableExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER);
106e78499d6db2bbd11e92efb23294e8ef1e2538847Sunny Goyal                mBindOptions =
107e78499d6db2bbd11e92efb23294e8ef1e2538847Sunny Goyal                        intent.getParcelableExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
108c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                mCallingPackage = getCallingPackage();
109c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                PackageManager pm = getPackageManager();
110c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                ApplicationInfo ai = pm.getApplicationInfo(mCallingPackage, 0);
111c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                label = pm.getApplicationLabel(ai);
112c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka            } catch (Exception e) {
113c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                mAppWidgetId = -1;
114c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                mComponentName = null;
115c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                mCallingPackage = null;
116c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                Log.v("BIND_APPWIDGET", "Error getting parameters");
117c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                finish();
118c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                return;
119c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka            }
120c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        }
121c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        AlertController.AlertParams ap = mAlertParams;
122c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        ap.mTitle = getString(R.string.allow_bind_app_widget_activity_allow_bind_title);
123c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        ap.mMessage = getString(R.string.allow_bind_app_widget_activity_allow_bind, label);
124c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        ap.mPositiveButtonText = getString(R.string.create);
125c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        ap.mNegativeButtonText = getString(android.R.string.cancel);
126c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        ap.mPositiveButtonListener = this;
127c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        ap.mNegativeButtonListener = this;
128c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        LayoutInflater inflater =
129c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
130c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
131c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        mAlwaysUse = (CheckBox) ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
132c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        mAlwaysUse.setText(getString(R.string.allow_bind_app_widget_activity_always_allow_bind, label));
133c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
134c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        mAlwaysUse.setPadding(mAlwaysUse.getPaddingLeft(),
135c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                mAlwaysUse.getPaddingTop(),
136c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                mAlwaysUse.getPaddingRight(),
137c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                (int) (mAlwaysUse.getPaddingBottom() +
138c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka                        getResources().getDimension(R.dimen.bind_app_widget_dialog_checkbox_bottom_padding)));
139c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
140c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        mAppWidgetManager = AppWidgetManager.getInstance(this);
141c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov        mAlwaysUse.setChecked(mAppWidgetManager.hasBindAppWidgetPermission(mCallingPackage,
142c15c0c078e65dfd8c10cf646fcd556cc26a6f62dSvet Ganov                mProfile.getIdentifier()));
143c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka
144c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka        setupAlert();
145c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka    }
146c9029d99a36d78331b109b64c1f61812db7cedd9Michael Jurka}
147