• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
20 import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
21 
22 import android.bluetooth.BluetoothAdapter;
23 import android.bluetooth.BluetoothClass;
24 import android.bluetooth.BluetoothDevice;
25 import android.bluetooth.BluetoothPbapClient;
26 import android.bluetooth.BluetoothProfile;
27 import android.bluetooth.BluetoothUuid;
28 import android.content.Context;
29 import android.os.ParcelUuid;
30 import android.util.Log;
31 
32 import com.android.settingslib.R;
33 
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.List;
37 
38 public final class PbapClientProfile implements LocalBluetoothProfile {
39     private static final String TAG = "PbapClientProfile";
40 
41     private BluetoothPbapClient mService;
42     private boolean mIsProfileReady;
43 
44     private final CachedBluetoothDeviceManager mDeviceManager;
45 
46     static final ParcelUuid[] SRC_UUIDS = {
47         BluetoothUuid.PBAP_PSE,
48     };
49 
50     static final String NAME = "PbapClient";
51     private final LocalBluetoothProfileManager mProfileManager;
52 
53     // Order of this profile in device profiles list
54     private static final int ORDINAL = 6;
55 
56     // These callbacks run on the main thread.
57     private final class PbapClientServiceListener
58             implements BluetoothProfile.ServiceListener {
59 
onServiceConnected(int profile, BluetoothProfile proxy)60         public void onServiceConnected(int profile, BluetoothProfile proxy) {
61             mService = (BluetoothPbapClient) proxy;
62             // We just bound to the service, so refresh the UI for any connected PBAP devices.
63             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
64             while (!deviceList.isEmpty()) {
65                 BluetoothDevice nextDevice = deviceList.remove(0);
66                 CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
67                 // we may add a new device here, but generally this should not happen
68                 if (device == null) {
69                     Log.w(TAG, "PbapClientProfile found new device: " + nextDevice);
70                     device = mDeviceManager.addDevice(nextDevice);
71                 }
72                 device.onProfileStateChanged(PbapClientProfile.this, BluetoothProfile.STATE_CONNECTED);
73                 device.refresh();
74             }
75             mIsProfileReady = true;
76         }
77 
onServiceDisconnected(int profile)78         public void onServiceDisconnected(int profile) {
79             mIsProfileReady = false;
80         }
81     }
82 
refreshProfiles()83     private void refreshProfiles() {
84         Collection<CachedBluetoothDevice> cachedDevices = mDeviceManager.getCachedDevicesCopy();
85         for (CachedBluetoothDevice device : cachedDevices) {
86             device.onUuidChanged();
87         }
88     }
89 
pbapClientExists()90     public boolean pbapClientExists() {
91         return (mService != null);
92     }
93 
isProfileReady()94     public boolean isProfileReady() {
95         return mIsProfileReady;
96     }
97 
98     @Override
getProfileId()99     public int getProfileId() {
100         return BluetoothProfile.PBAP_CLIENT;
101     }
102 
PbapClientProfile(Context context, CachedBluetoothDeviceManager deviceManager, LocalBluetoothProfileManager profileManager)103     PbapClientProfile(Context context, CachedBluetoothDeviceManager deviceManager,
104             LocalBluetoothProfileManager profileManager) {
105         mDeviceManager = deviceManager;
106         mProfileManager = profileManager;
107         BluetoothAdapter.getDefaultAdapter().getProfileProxy(context,
108                 new PbapClientServiceListener(), BluetoothProfile.PBAP_CLIENT);
109     }
110 
accessProfileEnabled()111     public boolean accessProfileEnabled() {
112         return true;
113     }
114 
isAutoConnectable()115     public boolean isAutoConnectable() {
116         return true;
117     }
118 
getConnectedDevices()119     public List<BluetoothDevice> getConnectedDevices() {
120         if (mService == null) {
121             return new ArrayList<BluetoothDevice>(0);
122         }
123         return mService.getDevicesMatchingConnectionStates(
124               new int[] {BluetoothProfile.STATE_CONNECTED,
125                          BluetoothProfile.STATE_CONNECTING,
126                          BluetoothProfile.STATE_DISCONNECTING});
127     }
128 
getConnectionStatus(BluetoothDevice device)129     public int getConnectionStatus(BluetoothDevice device) {
130         if (mService == null) {
131             return BluetoothProfile.STATE_DISCONNECTED;
132         }
133         return mService.getConnectionState(device);
134     }
135 
136     @Override
isEnabled(BluetoothDevice device)137     public boolean isEnabled(BluetoothDevice device) {
138         if (mService == null) {
139             return false;
140         }
141         return mService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN;
142     }
143 
144     @Override
getConnectionPolicy(BluetoothDevice device)145     public int getConnectionPolicy(BluetoothDevice device) {
146         if (mService == null) {
147             return CONNECTION_POLICY_FORBIDDEN;
148         }
149         return mService.getConnectionPolicy(device);
150     }
151 
152     @Override
setEnabled(BluetoothDevice device, boolean enabled)153     public boolean setEnabled(BluetoothDevice device, boolean enabled) {
154         boolean isEnabled = false;
155         if (mService == null) {
156             return false;
157         }
158         if (enabled) {
159             if (mService.getConnectionPolicy(device) < CONNECTION_POLICY_ALLOWED) {
160                 isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED);
161             }
162         } else {
163             isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_FORBIDDEN);
164         }
165 
166         return isEnabled;
167     }
168 
toString()169     public String toString() {
170         return NAME;
171     }
172 
getOrdinal()173     public int getOrdinal() {
174         return ORDINAL;
175     }
176 
getNameResource(BluetoothDevice device)177     public int getNameResource(BluetoothDevice device) {
178         // we need to have same string in UI as the server side.
179         return R.string.bluetooth_profile_pbap;
180     }
181 
getSummaryResourceForDevice(BluetoothDevice device)182     public int getSummaryResourceForDevice(BluetoothDevice device) {
183         return R.string.bluetooth_profile_pbap_summary;
184     }
185 
getDrawableResource(BluetoothClass btClass)186     public int getDrawableResource(BluetoothClass btClass) {
187         return com.android.internal.R.drawable.ic_phone;
188     }
189 
finalize()190     protected void finalize() {
191         Log.d(TAG, "finalize()");
192         if (mService != null) {
193             try {
194                 BluetoothAdapter.getDefaultAdapter().closeProfileProxy(
195                     BluetoothProfile.PBAP_CLIENT,mService);
196                 mService = null;
197             } catch (Throwable t) {
198                 Log.w(TAG, "Error cleaning up PBAP Client proxy", t);
199             }
200         }
201     }
202 }
203