OSDN Git Service

DO NOT MERGE. ActivityPicker shouldn't grant permissions. am: 94e678c188 am: e38a7f42...
[android-x86/packages-apps-Settings.git] / src / com / android / settings / bluetooth / RequestPermissionActivity.java
1 /*
2  * Copyright (C) 2009 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.bluetooth;
18
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.bluetooth.BluetoothAdapter;
22 import android.bluetooth.BluetoothDevice;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.os.Bundle;
29 import android.util.Log;
30
31 import com.android.settings.R;
32 import com.android.settingslib.bluetooth.BluetoothDiscoverableTimeoutReceiver;
33 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
34 import com.android.settingslib.bluetooth.LocalBluetoothManager;
35
36 /**
37  * RequestPermissionActivity asks the user whether to enable discovery. This is
38  * usually started by an application wanted to start bluetooth and or discovery
39  */
40 public class RequestPermissionActivity extends Activity implements
41         DialogInterface.OnClickListener {
42     // Command line to test this
43     // adb shell am start -a android.bluetooth.adapter.action.REQUEST_ENABLE
44     // adb shell am start -a android.bluetooth.adapter.action.REQUEST_DISCOVERABLE
45
46     private static final String TAG = "RequestPermissionActivity";
47
48     private static final int MAX_DISCOVERABLE_TIMEOUT = 3600; // 1 hr
49
50     // Non-error return code: BT is starting or has started successfully. Used
51     // by this Activity and RequestPermissionHelperActivity
52     /* package */ static final int RESULT_BT_STARTING_OR_STARTED = -1000;
53
54     private static final int REQUEST_CODE_START_BT = 1;
55
56     private LocalBluetoothAdapter mLocalAdapter;
57
58     private int mTimeout = BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT;
59
60     /*
61      * True if bluetooth wasn't enabled and RequestPermissionHelperActivity was
62      * started to ask the user and start bt.
63      *
64      * If/when that activity returns successfully, display please wait msg then
65      * go away when bt has started and discovery mode has been enabled.
66      */
67     private boolean mNeededToEnableBluetooth;
68
69     // True if requesting BT to be turned on
70     // False if requesting BT to be turned on + discoverable mode
71     private boolean mEnableOnly;
72
73     private boolean mUserConfirmed;
74
75     private AlertDialog mDialog;
76
77     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
78
79         @Override
80         public void onReceive(Context context, Intent intent) {
81             if (intent == null) {
82                 return;
83             }
84             if (mNeededToEnableBluetooth
85                     && BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
86                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothDevice.ERROR);
87                 if (state == BluetoothAdapter.STATE_ON) {
88                     if (mUserConfirmed) {
89                         proceedAndFinish();
90                     }
91                 }
92             }
93         }
94     };
95
96     @Override
97     protected void onCreate(Bundle savedInstanceState) {
98         super.onCreate(savedInstanceState);
99
100         // Note: initializes mLocalAdapter and returns true on error
101         if (parseIntent()) {
102             finish();
103             return;
104         }
105
106         int btState = mLocalAdapter.getState();
107
108         switch (btState) {
109             case BluetoothAdapter.STATE_OFF:
110             case BluetoothAdapter.STATE_TURNING_OFF:
111             case BluetoothAdapter.STATE_TURNING_ON:
112                 /*
113                  * Strictly speaking STATE_TURNING_ON belong with STATE_ON;
114                  * however, BT may not be ready when the user clicks yes and we
115                  * would fail to turn on discovery mode. By kicking this to the
116                  * RequestPermissionHelperActivity, this class will handle that
117                  * case via the broadcast receiver.
118                  */
119
120                 /*
121                  * Start the helper activity to:
122                  * 1) ask the user about enabling bt AND discovery
123                  * 2) enable BT upon confirmation
124                  */
125                 registerReceiver(mReceiver,
126                         new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
127                 Intent intent = new Intent();
128                 intent.setClass(this, RequestPermissionHelperActivity.class);
129                 if (mEnableOnly) {
130                     intent.setAction(RequestPermissionHelperActivity.ACTION_INTERNAL_REQUEST_BT_ON);
131                 } else {
132                     intent.setAction(RequestPermissionHelperActivity.
133                             ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE);
134                     intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, mTimeout);
135                 }
136                 startActivityForResult(intent, REQUEST_CODE_START_BT);
137                 mNeededToEnableBluetooth = true;
138                 break;
139             case BluetoothAdapter.STATE_ON:
140                 if (mEnableOnly) {
141                     // Nothing to do. Already enabled.
142                     proceedAndFinish();
143                 } else {
144                     // Ask the user about enabling discovery mode
145                     createDialog();
146                 }
147                 break;
148             default:
149                 Log.e(TAG, "Unknown adapter state: " + btState);
150         }
151     }
152
153     private void createDialog() {
154         AlertDialog.Builder builder = new AlertDialog.Builder(this);
155
156         if (mNeededToEnableBluetooth) {
157             // RequestPermissionHelperActivity has gotten confirmation from user
158             // to turn on BT
159             builder.setMessage(getString(R.string.bluetooth_turning_on));
160             builder.setCancelable(false);
161         } else {
162             // Ask the user whether to turn on discovery mode or not
163             // For lasting discoverable mode there is a different message
164             if (mTimeout == BluetoothDiscoverableEnabler.DISCOVERABLE_TIMEOUT_NEVER) {
165                 builder.setMessage(
166                         getString(R.string.bluetooth_ask_lasting_discovery));
167             } else {
168                 builder.setMessage(
169                         getString(R.string.bluetooth_ask_discovery, mTimeout));
170             }
171             builder.setPositiveButton(getString(R.string.allow), this);
172             builder.setNegativeButton(getString(R.string.deny), this);
173         }
174
175         mDialog = builder.create();
176         mDialog.show();
177
178         if (getResources().getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog) == true) {
179             // dismiss dialog immediately if settings say so
180             onClick(null, DialogInterface.BUTTON_POSITIVE);
181         }
182     }
183
184     @Override
185     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
186         if (requestCode != REQUEST_CODE_START_BT) {
187             Log.e(TAG, "Unexpected onActivityResult " + requestCode + ' ' + resultCode);
188             setResult(RESULT_CANCELED);
189             finish();
190             return;
191         }
192         if (resultCode != RESULT_BT_STARTING_OR_STARTED) {
193             setResult(resultCode);
194             finish();
195             return;
196         }
197
198         // Back from RequestPermissionHelperActivity. User confirmed to enable
199         // BT and discoverable mode.
200         mUserConfirmed = true;
201
202         if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
203             proceedAndFinish();
204         } else {
205             // If BT is not up yet, show "Turning on Bluetooth..."
206             createDialog();
207         }
208     }
209
210     public void onClick(DialogInterface dialog, int which) {
211         switch (which) {
212             case DialogInterface.BUTTON_POSITIVE:
213                 proceedAndFinish();
214                 break;
215
216             case DialogInterface.BUTTON_NEGATIVE:
217                 setResult(RESULT_CANCELED);
218                 finish();
219                 break;
220         }
221     }
222
223     private void proceedAndFinish() {
224         int returnCode;
225
226         if (mEnableOnly) {
227             // BT enabled. Done
228             returnCode = RESULT_OK;
229         } else if (mLocalAdapter.setScanMode(
230                 BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, mTimeout)) {
231             // If already in discoverable mode, this will extend the timeout.
232             long endTime = System.currentTimeMillis() + (long) mTimeout * 1000;
233             LocalBluetoothPreferences.persistDiscoverableEndTimestamp(
234                     this, endTime);
235             if (0 < mTimeout) {
236                BluetoothDiscoverableTimeoutReceiver.setDiscoverableAlarm(this, endTime);
237             }
238             returnCode = mTimeout;
239             // Activity.RESULT_FIRST_USER should be 1
240             if (returnCode < RESULT_FIRST_USER) {
241                 returnCode = RESULT_FIRST_USER;
242             }
243         } else {
244             returnCode = RESULT_CANCELED;
245         }
246
247         if (mDialog != null) {
248             mDialog.dismiss();
249         }
250
251         setResult(returnCode);
252         finish();
253     }
254
255     /**
256      * Parse the received Intent and initialize mLocalBluetoothAdapter.
257      * @return true if an error occurred; false otherwise
258      */
259     private boolean parseIntent() {
260         Intent intent = getIntent();
261         if (intent != null && intent.getAction().equals(BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
262             mEnableOnly = true;
263         } else if (intent != null
264                 && intent.getAction().equals(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)) {
265             mTimeout = intent.getIntExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
266                     BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT);
267
268             Log.d(TAG, "Setting Bluetooth Discoverable Timeout = " + mTimeout);
269
270             if (mTimeout < 1 || mTimeout > MAX_DISCOVERABLE_TIMEOUT) {
271                 mTimeout = BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT;
272             }
273         } else {
274             Log.e(TAG, "Error: this activity may be started only with intent "
275                     + BluetoothAdapter.ACTION_REQUEST_ENABLE + " or "
276                     + BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
277             setResult(RESULT_CANCELED);
278             return true;
279         }
280
281         LocalBluetoothManager manager = Utils.getLocalBtManager(this);
282         if (manager == null) {
283             Log.e(TAG, "Error: there's a problem starting Bluetooth");
284             setResult(RESULT_CANCELED);
285             return true;
286         }
287         mLocalAdapter = manager.getBluetoothAdapter();
288
289         return false;
290     }
291
292     @Override
293     protected void onDestroy() {
294         super.onDestroy();
295         if (mNeededToEnableBluetooth) {
296             unregisterReceiver(mReceiver);
297         }
298     }
299
300     @Override
301     public void onBackPressed() {
302         setResult(RESULT_CANCELED);
303         super.onBackPressed();
304     }
305 }