• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 com.android.settings.R;
20 import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
21 
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.preference.CheckBoxPreference;
25 import android.preference.Preference;
26 import android.preference.PreferenceActivity;
27 import android.preference.PreferenceGroup;
28 import android.text.TextUtils;
29 import android.util.Log;
30 
31 /**
32  * ConnectSpecificProfilesActivity presents the user with all of the profiles
33  * for a particular device, and allows him to choose which should be connected
34  * (or disconnected).
35  */
36 public class ConnectSpecificProfilesActivity extends PreferenceActivity
37         implements LocalBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
38     private static final String TAG = "ConnectSpecificProfilesActivity";
39 
40     private static final String KEY_ONLINE_MODE = "online_mode";
41     private static final String KEY_TITLE = "title";
42     private static final String KEY_PROFILE_CONTAINER = "profile_container";
43 
44     public static final String EXTRA_ADDRESS = "address";
45 
46     private LocalBluetoothManager mManager;
47     private LocalBluetoothDevice mDevice;
48 
49     private PreferenceGroup mProfileContainer;
50     private CheckBoxPreference mOnlineModePreference;
51 
52     /**
53      * The current mode of this activity and its checkboxes (either online mode
54      * or offline mode). In online mode, user interactions with the profile
55      * checkboxes will also toggle the profile's connectivity. In offline mode,
56      * they will not, and only the preferred state will be saved for the
57      * profile.
58      */
59     private boolean mOnlineMode;
60 
61     @Override
onCreate(Bundle savedInstanceState)62     protected void onCreate(Bundle savedInstanceState) {
63         super.onCreate(savedInstanceState);
64 
65         String address;
66         if (savedInstanceState != null) {
67             address = savedInstanceState.getString(EXTRA_ADDRESS);
68         } else {
69             Intent intent = getIntent();
70             address = intent.getStringExtra(EXTRA_ADDRESS);
71         }
72 
73         if (TextUtils.isEmpty(address)) {
74             Log.w(TAG, "Activity started without address");
75             finish();
76         }
77 
78         mManager = LocalBluetoothManager.getInstance(this);
79         mDevice = mManager.getLocalDeviceManager().findDevice(address);
80         if (mDevice == null) {
81             Log.w(TAG, "Device not found, cannot connect to it");
82             finish();
83         }
84 
85         addPreferencesFromResource(R.xml.bluetooth_device_advanced);
86         mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
87 
88         // Set the title of the screen
89         findPreference(KEY_TITLE).setTitle(
90                 getString(R.string.bluetooth_device_advanced_title, mDevice.getName()));
91 
92         // Listen for check/uncheck of the online mode checkbox
93         mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE);
94         mOnlineModePreference.setOnPreferenceChangeListener(this);
95 
96         // Add a preference for each profile
97         addPreferencesForProfiles();
98     }
99 
100     @Override
onSaveInstanceState(Bundle outState)101     protected void onSaveInstanceState(Bundle outState) {
102         super.onSaveInstanceState(outState);
103 
104         outState.putString(EXTRA_ADDRESS, mDevice.getAddress());
105     }
106 
107     @Override
onResume()108     protected void onResume() {
109         super.onResume();
110 
111         mManager.setForegroundActivity(this);
112         mDevice.registerCallback(this);
113 
114         refresh();
115     }
116 
117     @Override
onPause()118     protected void onPause() {
119         super.onPause();
120 
121         mDevice.unregisterCallback(this);
122         mManager.setForegroundActivity(null);
123     }
124 
addPreferencesForProfiles()125     private void addPreferencesForProfiles() {
126         for (Profile profile : mDevice.getProfiles()) {
127             Preference pref = createProfilePreference(profile);
128             mProfileContainer.addPreference(pref);
129         }
130     }
131 
132     /**
133      * Creates a checkbox preference for the particular profile. The key will be
134      * the profile's name.
135      *
136      * @param profile The profile for which the preference controls.
137      * @return A preference that allows the user to choose whether this profile
138      *         will be connected to.
139      */
createProfilePreference(Profile profile)140     private CheckBoxPreference createProfilePreference(Profile profile) {
141         CheckBoxPreference pref = new CheckBoxPreference(this);
142         pref.setKey(profile.toString());
143         pref.setTitle(profile.localizedString);
144         pref.setPersistent(false);
145         pref.setOnPreferenceChangeListener(this);
146 
147         refreshProfilePreference(pref, profile);
148 
149         return pref;
150     }
151 
onPreferenceChange(Preference preference, Object newValue)152     public boolean onPreferenceChange(Preference preference, Object newValue) {
153         String key = preference.getKey();
154         if (TextUtils.isEmpty(key) || newValue == null) return true;
155 
156         if (key.equals(KEY_ONLINE_MODE)) {
157             onOnlineModeCheckedStateChanged((Boolean) newValue);
158 
159         } else {
160             Profile profile = getProfileOf(preference);
161             if (profile == null) return false;
162             onProfileCheckedStateChanged(profile, (Boolean) newValue);
163         }
164 
165         return true;
166     }
167 
onOnlineModeCheckedStateChanged(boolean checked)168     private void onOnlineModeCheckedStateChanged(boolean checked) {
169         setOnlineMode(checked, true);
170     }
171 
onProfileCheckedStateChanged(Profile profile, boolean checked)172     private void onProfileCheckedStateChanged(Profile profile, boolean checked) {
173         if (mOnlineMode) {
174             if (checked) {
175                 mDevice.connect(profile);
176             } else {
177                 mDevice.disconnect(profile);
178             }
179         }
180 
181         LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
182                 .getProfileManager(mManager, profile);
183         profileManager.setPreferred(mDevice.getAddress(), checked);
184     }
185 
onDeviceAttributesChanged(LocalBluetoothDevice device)186     public void onDeviceAttributesChanged(LocalBluetoothDevice device) {
187         refresh();
188     }
189 
refresh()190     private void refresh() {
191         // We are in 'online mode' if we are connected, connecting, or disconnecting
192         setOnlineMode(mDevice.isConnected() || mDevice.isBusy(), false);
193         refreshProfiles();
194     }
195 
196     /**
197      * Switches between online/offline mode.
198      *
199      * @param onlineMode Whether to be in online mode, or offline mode.
200      * @param takeAction Whether to take action (i.e., connect or disconnect)
201      *            based on the new online mode.
202      */
setOnlineMode(boolean onlineMode, boolean takeAction)203     private void setOnlineMode(boolean onlineMode, boolean takeAction) {
204         mOnlineMode = onlineMode;
205 
206         if (takeAction) {
207             if (onlineMode) {
208                 mDevice.connect();
209             } else {
210                 mDevice.disconnect();
211             }
212         }
213 
214         refreshOnlineModePreference();
215     }
216 
refreshOnlineModePreference()217     private void refreshOnlineModePreference() {
218         mOnlineModePreference.setChecked(mOnlineMode);
219 
220         /* Gray out checkbox while connecting and disconnecting */
221         mOnlineModePreference.setEnabled(!mDevice.isBusy());
222 
223         /**
224          * If the device is online, show status. Otherwise, show a summary that
225          * describes what the checkbox does.
226          */
227         mOnlineModePreference.setSummary(mOnlineMode ? mDevice.getSummary()
228                 : R.string.bluetooth_device_advanced_online_mode_summary);
229     }
230 
refreshProfiles()231     private void refreshProfiles() {
232         for (Profile profile : mDevice.getProfiles()) {
233             CheckBoxPreference profilePref =
234                     (CheckBoxPreference) findPreference(profile.toString());
235             if (profilePref == null) {
236                 profilePref = createProfilePreference(profile);
237                 mProfileContainer.addPreference(profilePref);
238             } else {
239                 refreshProfilePreference(profilePref, profile);
240             }
241         }
242     }
243 
refreshProfilePreference(CheckBoxPreference profilePref, Profile profile)244     private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) {
245         String address = mDevice.getAddress();
246         LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
247                 .getProfileManager(mManager, profile);
248 
249         int connectionStatus = profileManager.getConnectionStatus(address);
250 
251         /* Gray out checkbox while connecting and disconnecting */
252         profilePref.setEnabled(!mDevice.isBusy());
253 
254         profilePref.setSummary(getProfileSummary(profileManager, profile, address,
255                 connectionStatus, mOnlineMode));
256 
257         profilePref.setChecked(profileManager.isPreferred(address));
258     }
259 
getProfileOf(Preference pref)260     private Profile getProfileOf(Preference pref) {
261         if (!(pref instanceof CheckBoxPreference)) return null;
262         String key = pref.getKey();
263         if (TextUtils.isEmpty(key)) return null;
264 
265         try {
266             return Profile.valueOf(pref.getKey());
267         } catch (IllegalArgumentException e) {
268             return null;
269         }
270     }
271 
getProfileSummary(LocalBluetoothProfileManager profileManager, Profile profile, String address, int connectionStatus, boolean onlineMode)272     private static int getProfileSummary(LocalBluetoothProfileManager profileManager,
273             Profile profile, String address, int connectionStatus, boolean onlineMode) {
274         if (!onlineMode || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
275             return getProfileSummaryForSettingPreference(profile);
276         } else {
277             return profileManager.getSummary(address);
278         }
279     }
280 
281     /**
282      * Gets the summary that describes when checked, it will become a preferred profile.
283      *
284      * @param profile The profile to get the summary for.
285      * @return The summary.
286      */
getProfileSummaryForSettingPreference(Profile profile)287     private static final int getProfileSummaryForSettingPreference(Profile profile) {
288         switch (profile) {
289             case A2DP:
290                 return R.string.bluetooth_a2dp_profile_summary_use_for;
291             case HEADSET:
292                 return R.string.bluetooth_headset_profile_summary_use_for;
293             default:
294                 return 0;
295         }
296     }
297 
298 }
299