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.settings.bluetooth;
     18 
     19 import android.bluetooth.BluetoothAdapter;
     20 import android.bluetooth.BluetoothClass;
     21 import android.bluetooth.BluetoothDevice;
     22 import android.bluetooth.BluetoothMap;
     23 import android.bluetooth.BluetoothProfile;
     24 import android.bluetooth.BluetoothUuid;
     25 import android.content.Context;
     26 import android.os.ParcelUuid;
     27 import android.util.Log;
     28 
     29 import com.android.settings.R;
     30 
     31 import java.util.ArrayList;
     32 import java.util.List;
     33 
     34 /**
     35  * MapProfile handles Bluetooth MAP profile.
     36  */
     37 final class MapProfile implements LocalBluetoothProfile {
     38     private static final String TAG = "MapProfile";
     39     private static boolean V = true;
     40 
     41     private BluetoothMap mService;
     42     private boolean mIsProfileReady;
     43 
     44     private final LocalBluetoothAdapter mLocalAdapter;
     45     private final CachedBluetoothDeviceManager mDeviceManager;
     46     private final LocalBluetoothProfileManager mProfileManager;
     47 
     48     static final ParcelUuid[] UUIDS = {
     49         BluetoothUuid.MAP,
     50         BluetoothUuid.MNS,
     51         BluetoothUuid.MAS,
     52     };
     53 
     54     static final String NAME = "MAP";
     55 
     56     // Order of this profile in device profiles list
     57 
     58     // These callbacks run on the main thread.
     59     private final class MapServiceListener
     60             implements BluetoothProfile.ServiceListener {
     61 
     62         public void onServiceConnected(int profile, BluetoothProfile proxy) {
     63             if (V) Log.d(TAG,"Bluetooth service connected");
     64             mService = (BluetoothMap) proxy;
     65             // We just bound to the service, so refresh the UI for any connected MAP devices.
     66             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
     67             while (!deviceList.isEmpty()) {
     68                 BluetoothDevice nextDevice = deviceList.remove(0);
     69                 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
     70                 // we may add a new device here, but generally this should not happen
     71                 if (device == null) {
     72                     Log.w(TAG, "MapProfile found new device: " + nextDevice);
     73                     device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
     74                 }
     75                 device.onProfileStateChanged(MapProfile.this,
     76                         BluetoothProfile.STATE_CONNECTED);
     77                 device.refresh();
     78             }
     79 
     80             mProfileManager.callServiceConnectedListeners();
     81             mIsProfileReady=true;
     82         }
     83 
     84         public void onServiceDisconnected(int profile) {
     85             if (V) Log.d(TAG,"Bluetooth service disconnected");
     86             mProfileManager.callServiceDisconnectedListeners();
     87             mIsProfileReady=false;
     88         }
     89     }
     90 
     91     public boolean isProfileReady() {
     92         if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady);
     93         return mIsProfileReady;
     94     }
     95 
     96     MapProfile(Context context, LocalBluetoothAdapter adapter,
     97             CachedBluetoothDeviceManager deviceManager,
     98             LocalBluetoothProfileManager profileManager) {
     99         mLocalAdapter = adapter;
    100         mDeviceManager = deviceManager;
    101         mProfileManager = profileManager;
    102         mLocalAdapter.getProfileProxy(context, new MapServiceListener(),
    103                 BluetoothProfile.MAP);
    104     }
    105 
    106     public boolean isConnectable() {
    107         return true;
    108     }
    109 
    110     public boolean isAutoConnectable() {
    111         return true;
    112     }
    113 
    114     public boolean connect(BluetoothDevice device) {
    115         if(V)Log.d(TAG,"connect() - should not get called");
    116         return true; // MAP never connects out
    117     }
    118 
    119     public boolean disconnect(BluetoothDevice device) {
    120         if (mService == null) return false;
    121         List<BluetoothDevice> deviceList = mService.getConnectedDevices();
    122         if (!deviceList.isEmpty() && deviceList.get(0).equals(device)) {
    123             if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
    124                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
    125             }
    126             return mService.disconnect(device);
    127         } else {
    128             return false;
    129         }
    130     }
    131 
    132     public int getConnectionStatus(BluetoothDevice device) {
    133         if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
    134         List<BluetoothDevice> deviceList = mService.getConnectedDevices();
    135         if(V) Log.d(TAG,"getConnectionStatus: status is: "+ mService.getConnectionState(device));
    136 
    137         return !deviceList.isEmpty() && deviceList.get(0).equals(device)
    138                 ? mService.getConnectionState(device)
    139                 : BluetoothProfile.STATE_DISCONNECTED;
    140     }
    141 
    142     public boolean isPreferred(BluetoothDevice device) {
    143         if (mService == null) return false;
    144         return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
    145     }
    146 
    147     public int getPreferred(BluetoothDevice device) {
    148         if (mService == null) return BluetoothProfile.PRIORITY_OFF;
    149         return mService.getPriority(device);
    150     }
    151 
    152     public void setPreferred(BluetoothDevice device, boolean preferred) {
    153         if (mService == null) return;
    154         if (preferred) {
    155             if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
    156                 mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
    157             }
    158         } else {
    159             mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
    160         }
    161     }
    162 
    163     public List<BluetoothDevice> getConnectedDevices() {
    164         if (mService == null) return new ArrayList<BluetoothDevice>(0);
    165         return mService.getDevicesMatchingConnectionStates(
    166               new int[] {BluetoothProfile.STATE_CONNECTED,
    167                          BluetoothProfile.STATE_CONNECTING,
    168                          BluetoothProfile.STATE_DISCONNECTING});
    169     }
    170 
    171     public String toString() {
    172         return NAME;
    173     }
    174 
    175     public int getOrdinal() {
    176         return BluetoothProfile.MAP;
    177     }
    178 
    179     public int getNameResource(BluetoothDevice device) {
    180         return R.string.bluetooth_profile_map;
    181     }
    182 
    183     public int getSummaryResourceForDevice(BluetoothDevice device) {
    184         int state = getConnectionStatus(device);
    185         switch (state) {
    186             case BluetoothProfile.STATE_DISCONNECTED:
    187                 return R.string.bluetooth_map_profile_summary_use_for;
    188 
    189             case BluetoothProfile.STATE_CONNECTED:
    190                 return R.string.bluetooth_map_profile_summary_connected;
    191 
    192             default:
    193                 return Utils.getConnectionStateSummary(state);
    194         }
    195     }
    196 
    197     public int getDrawableResource(BluetoothClass btClass) {
    198         return R.drawable.ic_bt_cellphone;
    199     }
    200 
    201     protected void finalize() {
    202         if (V) Log.d(TAG, "finalize()");
    203         if (mService != null) {
    204             try {
    205                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP,
    206                                                                        mService);
    207                 mService = null;
    208             }catch (Throwable t) {
    209                 Log.w(TAG, "Error cleaning up MAP proxy", t);
    210             }
    211         }
    212     }
    213 }
    214