1/* 2 * Copyright (C) 2011 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.bluetooth.BluetoothClass; 21import android.bluetooth.BluetoothDevice; 22import android.bluetooth.BluetoothPan; 23import android.bluetooth.BluetoothProfile; 24import android.content.Context; 25import android.util.Log; 26 27import com.android.settings.R; 28 29import java.util.HashMap; 30import java.util.List; 31 32/** 33 * PanProfile handles Bluetooth PAN profile (NAP and PANU). 34 */ 35final class PanProfile implements LocalBluetoothProfile { 36 private static final String TAG = "PanProfile"; 37 private static boolean V = true; 38 39 private BluetoothPan mService; 40 private boolean mIsProfileReady; 41 42 // Tethering direction for each device 43 private final HashMap<BluetoothDevice, Integer> mDeviceRoleMap = 44 new HashMap<BluetoothDevice, Integer>(); 45 46 static final String NAME = "PAN"; 47 48 // Order of this profile in device profiles list 49 private static final int ORDINAL = 4; 50 51 // These callbacks run on the main thread. 52 private final class PanServiceListener 53 implements BluetoothProfile.ServiceListener { 54 55 public void onServiceConnected(int profile, BluetoothProfile proxy) { 56 if (V) Log.d(TAG,"Bluetooth service connected"); 57 mService = (BluetoothPan) proxy; 58 mIsProfileReady=true; 59 } 60 61 public void onServiceDisconnected(int profile) { 62 if (V) Log.d(TAG,"Bluetooth service disconnected"); 63 mIsProfileReady=false; 64 } 65 } 66 67 public boolean isProfileReady() { 68 return mIsProfileReady; 69 } 70 71 PanProfile(Context context) { 72 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 73 adapter.getProfileProxy(context, new PanServiceListener(), 74 BluetoothProfile.PAN); 75 } 76 77 public boolean isConnectable() { 78 return true; 79 } 80 81 public boolean isAutoConnectable() { 82 return false; 83 } 84 85 public boolean connect(BluetoothDevice device) { 86 if (mService == null) return false; 87 List<BluetoothDevice> sinks = mService.getConnectedDevices(); 88 if (sinks != null) { 89 for (BluetoothDevice sink : sinks) { 90 mService.disconnect(sink); 91 } 92 } 93 return mService.connect(device); 94 } 95 96 public boolean disconnect(BluetoothDevice device) { 97 if (mService == null) return false; 98 return mService.disconnect(device); 99 } 100 101 public int getConnectionStatus(BluetoothDevice device) { 102 if (mService == null) { 103 return BluetoothProfile.STATE_DISCONNECTED; 104 } 105 return mService.getConnectionState(device); 106 } 107 108 public boolean isPreferred(BluetoothDevice device) { 109 // return current connection status so profile checkbox is set correctly 110 return getConnectionStatus(device) == BluetoothProfile.STATE_CONNECTED; 111 } 112 113 public int getPreferred(BluetoothDevice device) { 114 return -1; 115 } 116 117 public void setPreferred(BluetoothDevice device, boolean preferred) { 118 // ignore: isPreferred is always true for PAN 119 } 120 121 public String toString() { 122 return NAME; 123 } 124 125 public int getOrdinal() { 126 return ORDINAL; 127 } 128 129 public int getNameResource(BluetoothDevice device) { 130 if (isLocalRoleNap(device)) { 131 return R.string.bluetooth_profile_pan_nap; 132 } else { 133 return R.string.bluetooth_profile_pan; 134 } 135 } 136 137 public int getSummaryResourceForDevice(BluetoothDevice device) { 138 int state = getConnectionStatus(device); 139 switch (state) { 140 case BluetoothProfile.STATE_DISCONNECTED: 141 return R.string.bluetooth_pan_profile_summary_use_for; 142 143 case BluetoothProfile.STATE_CONNECTED: 144 if (isLocalRoleNap(device)) { 145 return R.string.bluetooth_pan_nap_profile_summary_connected; 146 } else { 147 return R.string.bluetooth_pan_user_profile_summary_connected; 148 } 149 150 default: 151 return Utils.getConnectionStateSummary(state); 152 } 153 } 154 155 public int getDrawableResource(BluetoothClass btClass) { 156 return R.drawable.ic_bt_network_pan; 157 } 158 159 // Tethering direction determines UI strings. 160 void setLocalRole(BluetoothDevice device, int role) { 161 mDeviceRoleMap.put(device, role); 162 } 163 164 boolean isLocalRoleNap(BluetoothDevice device) { 165 if (mDeviceRoleMap.containsKey(device)) { 166 return mDeviceRoleMap.get(device) == BluetoothPan.LOCAL_NAP_ROLE; 167 } else { 168 return false; 169 } 170 } 171 172 protected void finalize() { 173 if (V) Log.d(TAG, "finalize()"); 174 if (mService != null) { 175 try { 176 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.PAN, mService); 177 mService = null; 178 }catch (Throwable t) { 179 Log.w(TAG, "Error cleaning up PAN proxy", t); 180 } 181 } 182 } 183} 184