Home | History | Annotate | Download | only in accessories
      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 
     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
     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
    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
    136     public void onPause() {
    137         unregisterReceiver(mBroadcastReceiver);
    138         super.onPause();
    139     }
    140 
    141     @Override
    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
    170     protected Object getInitialState() {
    171         return ActionType.BLUETOOTH_DEVICE_OVERVIEW;
    172     }
    173 
    174     @Override
    175     protected void goBack() {
    176         if (!mDone) {
    177             super.goBack();
    178         }
    179     }
    180 
    181     @Override
    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
    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 
    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
    247     protected void setProperty(boolean enable) {
    248     }
    249 }
    250