• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.tv.settings.accessories;
18 
19 import static android.provider.Settings.Secure.TTS_DEFAULT_RATE;
20 
21 import com.android.tv.settings.ActionBehavior;
22 import com.android.tv.settings.ActionKey;
23 import com.android.tv.settings.BaseSettingsActivity;
24 import com.android.tv.settings.R;
25 import com.android.tv.settings.dialog.old.Action;
26 import com.android.tv.settings.dialog.old.ActionAdapter;
27 
28 import android.bluetooth.BluetoothAdapter;
29 import android.bluetooth.BluetoothDevice;
30 import android.content.BroadcastReceiver;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.os.Bundle;
35 import android.os.Handler;
36 import android.os.Message;
37 import android.util.Log;
38 import java.util.Set;
39 
40 public class BluetoothAccessoryActivity extends BaseSettingsActivity
41         implements ActionAdapter.Listener {
42 
43     public static final String EXTRA_ACCESSORY_ADDRESS = "accessory_address";
44     public static final String EXTRA_ACCESSORY_NAME = "accessory_name";
45     public static final String EXTRA_ACCESSORY_ICON_ID = "accessory_icon_res";
46 
47     private static final int MSG_UNPAIR_TIMEOUT = 1;
48 
49     private static final int UNPAIR_TIMEOUT = 5000;
50 
51     private static final String TAG = "aah.BluetoothAccessoryActivity";
52     private static final boolean DEBUG = false;
53 
54     private BluetoothDevice mDevice;
55     protected String mDeviceAddress;
56     protected String mDeviceName;
57     protected int mDeviceImgId;
58     protected boolean mDone;
59 
getIntent(Context context, String deviceAddress, String deviceName, int iconId)60     public static Intent getIntent(Context context, String deviceAddress,
61             String deviceName, int iconId) {
62         Intent i = new Intent(context, BluetoothAccessoryActivity.class);
63         i.putExtra(EXTRA_ACCESSORY_ADDRESS, deviceAddress);
64         i.putExtra(EXTRA_ACCESSORY_NAME, deviceName);
65         i.putExtra(EXTRA_ACCESSORY_ICON_ID, iconId);
66         return i;
67     }
68 
69     // Broadcast Receiver for Bluetooth related events
70     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
71             @Override
72         public void onReceive(Context context, Intent intent) {
73             BluetoothDevice device = intent
74                     .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
75             if (mDone) {
76                 if (mDevice.equals(device)) {
77                     // Done removing device, finish the activity
78                     mMsgHandler.removeMessages(MSG_UNPAIR_TIMEOUT);
79                     finish();
80                 }
81             }
82         }
83     };
84 
85     // Internal message handler
86     private Handler mMsgHandler = new Handler() {
87             @Override
88         public void handleMessage(Message msg) {
89             switch (msg.what) {
90                 case MSG_UNPAIR_TIMEOUT:
91                     finish();
92                     break;
93                 default:
94             }
95         }
96     };
97 
98     @Override
onCreate(Bundle savedInstanceState)99     public void onCreate(Bundle savedInstanceState) {
100         Bundle bundle = getIntent().getExtras();
101         if (bundle != null) {
102             mDeviceAddress = bundle.getString(EXTRA_ACCESSORY_ADDRESS);
103             mDeviceName = bundle.getString(EXTRA_ACCESSORY_NAME);
104             mDeviceImgId = bundle.getInt(EXTRA_ACCESSORY_ICON_ID);
105         } else {
106             mDeviceName = getString(R.string.accessory_options);
107             mDeviceImgId = R.drawable.ic_qs_bluetooth_not_connected;
108         }
109 
110         super.onCreate(savedInstanceState);
111 
112         mDone = false;
113 
114         BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
115         if (btAdapter != null) {
116             Set<BluetoothDevice> bondedDevices = btAdapter.getBondedDevices();
117             for (BluetoothDevice device : bondedDevices) {
118                 if (mDeviceAddress.equals(device.getAddress())) {
119                     mDevice = device;
120                     break;
121                 }
122             }
123         }
124     }
125 
126     @Override
onResume()127     public void onResume() {
128         // Set a broadcast receiver to let us know when the device has been removed
129         IntentFilter adapterIntentFilter = new IntentFilter();
130         adapterIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
131         registerReceiver(mBroadcastReceiver, adapterIntentFilter);
132         super.onResume();
133     }
134 
135     @Override
onPause()136     public void onPause() {
137         unregisterReceiver(mBroadcastReceiver);
138         super.onPause();
139     }
140 
141     @Override
onActionClicked(Action action)142     public void onActionClicked(Action action) {
143         if (mDone) {
144             return;
145         }
146         /*
147          * For regular states
148          */
149         ActionKey<ActionType, ActionBehavior> actionKey = new ActionKey<ActionType, ActionBehavior>(
150                 ActionType.class, ActionBehavior.class, action.getKey());
151         final ActionType type = actionKey.getType();
152         if (type != null) {
153             switch (type) {
154                 case BLUETOOTH_DEVICE_RENAME:
155                     // TODO: Will be implemented in a separate CL
156                     return;
157                 case OK:
158                     unpairDevice();
159                     return;
160                 case CANCEL:
161                     goBack(); // Cancelled request to STOP service
162                     return;
163                 default:
164             }
165         }
166         setState(type, true);
167     }
168 
169     @Override
getInitialState()170     protected Object getInitialState() {
171         return ActionType.BLUETOOTH_DEVICE_OVERVIEW;
172     }
173 
174     @Override
goBack()175     protected void goBack() {
176         if (!mDone) {
177             super.goBack();
178         }
179     }
180 
181     @Override
refreshActionList()182     protected void refreshActionList() {
183         mActions.clear();
184         switch ((ActionType) mState) {
185             case BLUETOOTH_DEVICE_OVERVIEW:
186                 // Disabled for now, until the name input screen is implemented
187                 // mActions.add(ActionType.BLUETOOTH_DEVICE_RENAME.toAction(mResources));
188                 mActions.add(ActionType.BLUETOOTH_DEVICE_UNPAIR.toAction(mResources));
189                 break;
190             case BLUETOOTH_DEVICE_UNPAIR:
191                 mActions.add(ActionType.OK.toAction(mResources));
192                 mActions.add(ActionType.CANCEL.toAction(mResources));
193                 break;
194             default:
195                 break;
196         }
197     }
198 
199     @Override
updateView()200     protected void updateView() {
201         refreshActionList();
202         switch ((ActionType) mState) {
203             case BLUETOOTH_DEVICE_OVERVIEW:
204                 setView(mDeviceName, getString(R.string.header_category_accessories), null,
205                         mDeviceImgId);
206                 break;
207             case BLUETOOTH_DEVICE_UNPAIR:
208                 setView(getString(R.string.accessory_unpair), mDeviceName, null, mDeviceImgId);
209                 break;
210             default:
211                 break;
212         }
213     }
214 
unpairDevice()215     void unpairDevice() {
216         if (mDevice != null) {
217             int state = mDevice.getBondState();
218 
219             if (state == BluetoothDevice.BOND_BONDING) {
220                 mDevice.cancelBondProcess();
221             }
222 
223             if (state != BluetoothDevice.BOND_NONE) {
224                 mDone = true;
225                 // Set a timeout, just in case we don't receive the unpair notification we
226                 // use to finish the activity
227                 mMsgHandler.sendEmptyMessageDelayed(MSG_UNPAIR_TIMEOUT, UNPAIR_TIMEOUT);
228                 final boolean successful = mDevice.removeBond();
229                 if (successful) {
230                     if (DEBUG) {
231                         Log.d(TAG, "Bluetooth device successfully unpaired.");
232                     }
233                     // set the dialog to a waiting state
234                     mActions.clear();
235                     setView(getString(R.string.accessory_unpair), mDeviceName,
236                             getString(R.string.accessory_unpairing), mDeviceImgId);
237                 } else {
238                     Log.e(TAG, "Failed to unpair Bluetooth Device: " + mDevice.getName());
239                 }
240             }
241         } else {
242             Log.e(TAG, "Bluetooth device not found. Address = " + mDeviceAddress);
243         }
244     }
245 
246     @Override
setProperty(boolean enable)247     protected void setProperty(boolean enable) {
248     }
249 }
250