Home | History | Annotate | Download | only in bluetooth
      1 /*
      2  * Copyright (C) 2012 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.settingslib.bluetooth;
     18 
     19 import android.bluetooth.BluetoothAdapter;
     20 import android.bluetooth.BluetoothClass;
     21 import android.bluetooth.BluetoothDevice;
     22 import android.bluetooth.BluetoothHidHost;
     23 import android.bluetooth.BluetoothProfile;
     24 import android.content.Context;
     25 import android.util.Log;
     26 
     27 import com.android.settingslib.R;
     28 
     29 import java.util.List;
     30 
     31 /**
     32  * HidProfile handles Bluetooth HID Host role.
     33  */
     34 public class HidProfile implements LocalBluetoothProfile {
     35     private static final String TAG = "HidProfile";
     36 
     37     private BluetoothHidHost mService;
     38     private boolean mIsProfileReady;
     39 
     40     private final CachedBluetoothDeviceManager mDeviceManager;
     41     private final LocalBluetoothProfileManager mProfileManager;
     42 
     43     static final String NAME = "HID";
     44 
     45     // Order of this profile in device profiles list
     46     private static final int ORDINAL = 3;
     47 
     48     // These callbacks run on the main thread.
     49     private final class HidHostServiceListener
     50             implements BluetoothProfile.ServiceListener {
     51 
     52         public void onServiceConnected(int profile, BluetoothProfile proxy) {
     53             mService = (BluetoothHidHost) proxy;
     54             // We just bound to the service, so refresh the UI for any connected HID devices.
     55             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
     56             while (!deviceList.isEmpty()) {
     57                 BluetoothDevice nextDevice = deviceList.remove(0);
     58                 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
     59                 // we may add a new device here, but generally this should not happen
     60                 if (device == null) {
     61                     Log.w(TAG, "HidProfile found new device: " + nextDevice);
     62                     device = mDeviceManager.addDevice(nextDevice);
     63                 }
     64                 device.onProfileStateChanged(HidProfile.this, BluetoothProfile.STATE_CONNECTED);
     65                 device.refresh();
     66             }
     67             mIsProfileReady=true;
     68         }
     69 
     70         public void onServiceDisconnected(int profile) {
     71             mIsProfileReady=false;
     72         }
     73     }
     74 
     75     public boolean isProfileReady() {
     76         return mIsProfileReady;
     77     }
     78 
     79     @Override
     80     public int getProfileId() {
     81         return BluetoothProfile.HID_HOST;
     82     }
     83 
     84     HidProfile(Context context,
     85         CachedBluetoothDeviceManager deviceManager,
     86         LocalBluetoothProfileManager profileManager) {
     87         mDeviceManager = deviceManager;
     88         mProfileManager = profileManager;
     89         BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, new HidHostServiceListener(),
     90                 BluetoothProfile.HID_HOST);
     91     }
     92 
     93     public boolean accessProfileEnabled() {
     94         return true;
     95     }
     96 
     97     public boolean isAutoConnectable() {
     98         return true;
     99     }
    100 
    101     public boolean connect(BluetoothDevice device) {
    102         if (mService == null) return false;
    103         return mService.connect(device);
    104     }
    105 
    106     public boolean disconnect(BluetoothDevice device) {
    107         if (mService == null) return false;
    108         return mService.disconnect(device);
    109     }
    110 
    111     public int getConnectionStatus(BluetoothDevice device) {
    112         if (mService == null) {
    113             return BluetoothProfile.STATE_DISCONNECTED;
    114         }
    115         return mService.getConnectionState(device);
    116     }
    117 
    118     public boolean isPreferred(BluetoothDevice device) {
    119         if (mService == null) return false;
    120         return mService.getPriority(device) != BluetoothProfile.PRIORITY_OFF;
    121     }
    122 
    123     public int getPreferred(BluetoothDevice device) {
    124         if (mService == null) return BluetoothProfile.PRIORITY_OFF;
    125         return mService.getPriority(device);
    126     }
    127 
    128     public void setPreferred(BluetoothDevice device, boolean preferred) {
    129         if (mService == null) return;
    130         if (preferred) {
    131             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
    132                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
    133             }
    134         } else {
    135             mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
    136         }
    137     }
    138 
    139     public String toString() {
    140         return NAME;
    141     }
    142 
    143     public int getOrdinal() {
    144         return ORDINAL;
    145     }
    146 
    147     public int getNameResource(BluetoothDevice device) {
    148         // TODO: distinguish between keyboard and mouse?
    149         return R.string.bluetooth_profile_hid;
    150     }
    151 
    152     public int getSummaryResourceForDevice(BluetoothDevice device) {
    153         int state = getConnectionStatus(device);
    154         switch (state) {
    155             case BluetoothProfile.STATE_DISCONNECTED:
    156                 return R.string.bluetooth_hid_profile_summary_use_for;
    157 
    158             case BluetoothProfile.STATE_CONNECTED:
    159                 return R.string.bluetooth_hid_profile_summary_connected;
    160 
    161             default:
    162                 return BluetoothUtils.getConnectionStateSummary(state);
    163         }
    164     }
    165 
    166     public int getDrawableResource(BluetoothClass btClass) {
    167         if (btClass == null) {
    168             return com.android.internal.R.drawable.ic_lockscreen_ime;
    169         }
    170         return getHidClassDrawable(btClass);
    171     }
    172 
    173     public static int getHidClassDrawable(BluetoothClass btClass) {
    174         switch (btClass.getDeviceClass()) {
    175             case BluetoothClass.Device.PERIPHERAL_KEYBOARD:
    176             case BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING:
    177                 return com.android.internal.R.drawable.ic_lockscreen_ime;
    178             case BluetoothClass.Device.PERIPHERAL_POINTING:
    179                 return com.android.internal.R.drawable.ic_bt_pointing_hid;
    180             default:
    181                 return com.android.internal.R.drawable.ic_bt_misc_hid;
    182         }
    183     }
    184 
    185     protected void finalize() {
    186         Log.d(TAG, "finalize()");
    187         if (mService != null) {
    188             try {
    189                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HID_HOST,
    190                                                                        mService);
    191                 mService = null;
    192             }catch (Throwable t) {
    193                 Log.w(TAG, "Error cleaning up HID proxy", t);
    194             }
    195         }
    196     }
    197 }
    198