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
17package com.android.settings.bluetooth;
18
19import android.bluetooth.BluetoothAdapter;
20import android.content.DialogInterface;
21import android.content.Intent;
22import android.os.Bundle;
23import android.util.Log;
24
25import com.android.internal.app.AlertActivity;
26import com.android.internal.app.AlertController;
27import com.android.settings.R;
28import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
29import com.android.settingslib.bluetooth.LocalBluetoothManager;
30
31/**
32 * RequestPermissionHelperActivity asks the user whether to enable discovery.
33 * This is usually started by RequestPermissionActivity.
34 */
35public class RequestPermissionHelperActivity extends AlertActivity implements
36        DialogInterface.OnClickListener {
37    private static final String TAG = "RequestPermissionHelperActivity";
38
39    public static final String ACTION_INTERNAL_REQUEST_BT_ON =
40        "com.android.settings.bluetooth.ACTION_INTERNAL_REQUEST_BT_ON";
41
42    public static final String ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE =
43        "com.android.settings.bluetooth.ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE";
44
45    private LocalBluetoothAdapter mLocalAdapter;
46
47    private int mTimeout;
48
49    // True if requesting BT to be turned on
50    // False if requesting BT to be turned on + discoverable mode
51    private boolean mEnableOnly;
52
53    @Override
54    protected void onCreate(Bundle savedInstanceState) {
55        super.onCreate(savedInstanceState);
56
57        // Note: initializes mLocalAdapter and returns true on error
58        if (parseIntent()) {
59            finish();
60            return;
61        }
62
63        createDialog();
64
65        if (getResources().getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog) == true) {
66            // dismiss dialog immediately if settings say so
67            onClick(null, BUTTON_POSITIVE);
68            dismiss();
69        }
70    }
71
72    void createDialog() {
73        final AlertController.AlertParams p = mAlertParams;
74
75        if (mEnableOnly) {
76            p.mMessage = getString(R.string.bluetooth_ask_enablement);
77        } else {
78            if (mTimeout == BluetoothDiscoverableEnabler.DISCOVERABLE_TIMEOUT_NEVER) {
79                p.mMessage = getString(R.string.bluetooth_ask_enablement_and_lasting_discovery);
80            } else {
81                p.mMessage = getString(R.string.bluetooth_ask_enablement_and_discovery, mTimeout);
82            }
83        }
84
85        p.mPositiveButtonText = getString(R.string.allow);
86        p.mPositiveButtonListener = this;
87        p.mNegativeButtonText = getString(R.string.deny);
88        p.mNegativeButtonListener = this;
89
90        setupAlert();
91    }
92
93    public void onClick(DialogInterface dialog, int which) {
94        int returnCode;
95        // FIXME: fix this ugly switch logic!
96        switch (which) {
97            case BUTTON_POSITIVE:
98                int btState = 0;
99
100                try {
101                    // TODO There's a better way.
102                    int retryCount = 30;
103                    do {
104                        btState = mLocalAdapter.getBluetoothState();
105                        Thread.sleep(100);
106                    } while (btState == BluetoothAdapter.STATE_TURNING_OFF && --retryCount > 0);
107                } catch (InterruptedException ignored) {
108                    // don't care
109                }
110
111                if (btState == BluetoothAdapter.STATE_TURNING_ON
112                        || btState == BluetoothAdapter.STATE_ON
113                        || mLocalAdapter.enable()) {
114                    returnCode = RequestPermissionActivity.RESULT_BT_STARTING_OR_STARTED;
115                } else {
116                    returnCode = RESULT_CANCELED;
117                }
118                break;
119
120            case BUTTON_NEGATIVE:
121                returnCode = RESULT_CANCELED;
122                break;
123            default:
124                return;
125        }
126        setResult(returnCode);
127    }
128
129    /**
130     * Parse the received Intent and initialize mLocalBluetoothAdapter.
131     * @return true if an error occurred; false otherwise
132     */
133    private boolean parseIntent() {
134        Intent intent = getIntent();
135        if (intent != null && intent.getAction().equals(ACTION_INTERNAL_REQUEST_BT_ON)) {
136            mEnableOnly = true;
137        } else if (intent != null
138                && intent.getAction().equals(ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE)) {
139            mEnableOnly = false;
140            // Value used for display purposes. Not range checking.
141            mTimeout = intent.getIntExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
142                    BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT);
143        } else {
144            setResult(RESULT_CANCELED);
145            return true;
146        }
147
148        LocalBluetoothManager manager = Utils.getLocalBtManager(this);
149        if (manager == null) {
150            Log.e(TAG, "Error: there's a problem starting Bluetooth");
151            setResult(RESULT_CANCELED);
152            return true;
153        }
154        mLocalAdapter = manager.getBluetoothAdapter();
155
156        return false;
157    }
158
159    @Override
160    public void onBackPressed() {
161        setResult(RESULT_CANCELED);
162        super.onBackPressed();
163    }
164}
165