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 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.BluetoothPan; 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.HashMap; 30 import java.util.List; 31 32 /** 33 * PanProfile handles Bluetooth PAN profile (NAP and PANU). 34 */ 35 public final 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 true; 110 } 111 112 public int getPreferred(BluetoothDevice device) { 113 return -1; 114 } 115 116 public void setPreferred(BluetoothDevice device, boolean preferred) { 117 // ignore: isPreferred is always true for PAN 118 } 119 120 public String toString() { 121 return NAME; 122 } 123 124 public int getOrdinal() { 125 return ORDINAL; 126 } 127 128 public int getNameResource(BluetoothDevice device) { 129 if (isLocalRoleNap(device)) { 130 return R.string.bluetooth_profile_pan_nap; 131 } else { 132 return R.string.bluetooth_profile_pan; 133 } 134 } 135 136 public int getSummaryResourceForDevice(BluetoothDevice device) { 137 int state = getConnectionStatus(device); 138 switch (state) { 139 case BluetoothProfile.STATE_DISCONNECTED: 140 return R.string.bluetooth_pan_profile_summary_use_for; 141 142 case BluetoothProfile.STATE_CONNECTED: 143 if (isLocalRoleNap(device)) { 144 return R.string.bluetooth_pan_nap_profile_summary_connected; 145 } else { 146 return R.string.bluetooth_pan_user_profile_summary_connected; 147 } 148 149 default: 150 return Utils.getConnectionStateSummary(state); 151 } 152 } 153 154 public int getDrawableResource(BluetoothClass btClass) { 155 return R.drawable.ic_bt_network_pan; 156 } 157 158 // Tethering direction determines UI strings. 159 void setLocalRole(BluetoothDevice device, int role) { 160 mDeviceRoleMap.put(device, role); 161 } 162 163 boolean isLocalRoleNap(BluetoothDevice device) { 164 if (mDeviceRoleMap.containsKey(device)) { 165 return mDeviceRoleMap.get(device) == BluetoothPan.LOCAL_NAP_ROLE; 166 } else { 167 return false; 168 } 169 } 170 171 protected void finalize() { 172 if (V) Log.d(TAG, "finalize()"); 173 if (mService != null) { 174 try { 175 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.PAN, mService); 176 mService = null; 177 }catch (Throwable t) { 178 Log.w(TAG, "Error cleaning up PAN proxy", t); 179 } 180 } 181 } 182 } 183