17ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk/* 27ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Copyright (C) 2011 The Android Open Source Project 37ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 47ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 57ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * you may not use this file except in compliance with the License. 67ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * You may obtain a copy of the License at 77ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 87ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 97ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * 107ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * Unless required by applicable law or agreed to in writing, software 117ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 127ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * See the License for the specific language governing permissions and 147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * limitations under the License. 157ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkpackage com.android.settingslib.bluetooth; 187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothAdapter; 207ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothClass; 217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothDevice; 227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothPan; 237ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.bluetooth.BluetoothProfile; 247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.content.Context; 257ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport android.util.Log; 267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport com.android.settingslib.R; 287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport java.util.HashMap; 307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monkimport java.util.List; 317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk/** 337ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk * PanProfile handles Bluetooth PAN profile (NAP and PANU). 347ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk */ 3560598075a0d54dcb4287d77c91b946e6c407a669Andre Eisenbachpublic final class PanProfile implements LocalBluetoothProfile { 367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final String TAG = "PanProfile"; 377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static boolean V = true; 387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 397ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private BluetoothPan mService; 407ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private boolean mIsProfileReady; 417ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Tethering direction for each device 437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final HashMap<BluetoothDevice, Integer> mDeviceRoleMap = 447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk new HashMap<BluetoothDevice, Integer>(); 457ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk static final String NAME = "PAN"; 477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Order of this profile in device profiles list 497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private static final int ORDINAL = 4; 507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 517ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // These callbacks run on the main thread. 527ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk private final class PanServiceListener 537ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk implements BluetoothProfile.ServiceListener { 547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public void onServiceConnected(int profile, BluetoothProfile proxy) { 567ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (V) Log.d(TAG,"Bluetooth service connected"); 577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mService = (BluetoothPan) proxy; 587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mIsProfileReady=true; 597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public void onServiceDisconnected(int profile) { 627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (V) Log.d(TAG,"Bluetooth service disconnected"); 637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mIsProfileReady=false; 647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean isProfileReady() { 687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mIsProfileReady; 697ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 707ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 717ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk PanProfile(Context context) { 727ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 737ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk adapter.getProfileProxy(context, new PanServiceListener(), 747ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothProfile.PAN); 757ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 767ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 777ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean isConnectable() { 787ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return true; 797ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 807ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 817ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean isAutoConnectable() { 827ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return false; 837ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 847ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 857ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean connect(BluetoothDevice device) { 867ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mService == null) return false; 877ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk List<BluetoothDevice> sinks = mService.getConnectedDevices(); 887ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (sinks != null) { 897ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk for (BluetoothDevice sink : sinks) { 907ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mService.disconnect(sink); 917ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 927ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 937ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mService.connect(device); 947ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 957ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 967ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean disconnect(BluetoothDevice device) { 977ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mService == null) return false; 987ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mService.disconnect(device); 997ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1007ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1017ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public int getConnectionStatus(BluetoothDevice device) { 1027ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mService == null) { 1037ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return BluetoothProfile.STATE_DISCONNECTED; 1047ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1057ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mService.getConnectionState(device); 1067ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1077ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1087ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public boolean isPreferred(BluetoothDevice device) { 10960598075a0d54dcb4287d77c91b946e6c407a669Andre Eisenbach return true; 1107ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1117ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1127ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public int getPreferred(BluetoothDevice device) { 1137ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return -1; 1147ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1157ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1167ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public void setPreferred(BluetoothDevice device, boolean preferred) { 1177ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // ignore: isPreferred is always true for PAN 1187ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1197ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1207ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public String toString() { 1217ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return NAME; 1227ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1237ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1247ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public int getOrdinal() { 1257ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return ORDINAL; 1267ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1277ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1287ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public int getNameResource(BluetoothDevice device) { 1297ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (isLocalRoleNap(device)) { 1307ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return R.string.bluetooth_profile_pan_nap; 1317ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else { 1327ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return R.string.bluetooth_profile_pan; 1337ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1347ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1357ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1367ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public int getSummaryResourceForDevice(BluetoothDevice device) { 1377ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk int state = getConnectionStatus(device); 1387ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk switch (state) { 1397ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk case BluetoothProfile.STATE_DISCONNECTED: 1407ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return R.string.bluetooth_pan_profile_summary_use_for; 1417ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1427ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk case BluetoothProfile.STATE_CONNECTED: 1437ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (isLocalRoleNap(device)) { 1447ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return R.string.bluetooth_pan_nap_profile_summary_connected; 1457ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else { 1467ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return R.string.bluetooth_pan_user_profile_summary_connected; 1477ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1487ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1497ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk default: 1507ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return Utils.getConnectionStateSummary(state); 1517ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1527ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1537ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1547ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk public int getDrawableResource(BluetoothClass btClass) { 1557ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return R.drawable.ic_bt_network_pan; 1567ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1577ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1587ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk // Tethering direction determines UI strings. 1597ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk void setLocalRole(BluetoothDevice device, int role) { 1607ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mDeviceRoleMap.put(device, role); 1617ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1627ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1637ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk boolean isLocalRoleNap(BluetoothDevice device) { 1647ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mDeviceRoleMap.containsKey(device)) { 1657ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return mDeviceRoleMap.get(device) == BluetoothPan.LOCAL_NAP_ROLE; 1667ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } else { 1677ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk return false; 1687ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1697ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1707ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk 1717ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk protected void finalize() { 1727ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (V) Log.d(TAG, "finalize()"); 1737ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk if (mService != null) { 1747ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk try { 1757ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.PAN, mService); 1767ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk mService = null; 1777ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk }catch (Throwable t) { 1787ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk Log.w(TAG, "Error cleaning up PAN proxy", t); 1797ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1807ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1817ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk } 1827ce96b9e610de2782ec5f2af806e7bc0f90c8578Jason Monk} 183