• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 package com.android.settings.connecteddevice;
17 
18 import android.bluetooth.BluetoothAdapter;
19 import android.bluetooth.BluetoothDevice;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.pm.PackageManager;
25 import android.util.Log;
26 
27 import androidx.annotation.VisibleForTesting;
28 import androidx.preference.Preference;
29 import androidx.preference.PreferenceGroup;
30 import androidx.preference.PreferenceScreen;
31 
32 import com.android.settings.R;
33 import com.android.settings.bluetooth.BluetoothDevicePreference;
34 import com.android.settings.bluetooth.BluetoothDeviceUpdater;
35 import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater;
36 import com.android.settings.connecteddevice.dock.DockUpdater;
37 import com.android.settings.core.BasePreferenceController;
38 import com.android.settings.dashboard.DashboardFragment;
39 import com.android.settings.overlay.FeatureFactory;
40 import com.android.settingslib.core.lifecycle.LifecycleObserver;
41 import com.android.settingslib.core.lifecycle.events.OnStart;
42 import com.android.settingslib.core.lifecycle.events.OnStop;
43 
44 import java.util.ArrayList;
45 import java.util.List;
46 
47 public class PreviouslyConnectedDevicePreferenceController extends BasePreferenceController
48         implements LifecycleObserver, OnStart, OnStop, DevicePreferenceCallback {
49 
50     private static final String TAG = "PreviouslyDevicePreController";
51     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
52 
53     private static final int MAX_DEVICE_NUM = 3;
54     private static final int DOCK_DEVICE_INDEX = 9;
55     private static final String KEY_SEE_ALL = "previously_connected_devices_see_all";
56 
57     private final List<Preference> mDevicesList = new ArrayList<>();
58     private final List<Preference> mDockDevicesList = new ArrayList<>();
59 
60     private PreferenceGroup mPreferenceGroup;
61     private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
62     private DockUpdater mSavedDockUpdater;
63     private BluetoothAdapter mBluetoothAdapter;
64 
65     @VisibleForTesting
66     Preference mSeeAllPreference;
67     @VisibleForTesting
68     IntentFilter mIntentFilter;
69 
70     @VisibleForTesting
71     BroadcastReceiver mReceiver = new BroadcastReceiver() {
72         @Override
73         public void onReceive(Context context, Intent intent) {
74             updatePreferenceVisibility();
75         }
76     };
77 
PreviouslyConnectedDevicePreferenceController(Context context, String preferenceKey)78     public PreviouslyConnectedDevicePreferenceController(Context context, String preferenceKey) {
79         super(context, preferenceKey);
80 
81         mSavedDockUpdater = FeatureFactory.getFactory(
82                 context).getDockUpdaterFeatureProvider().getSavedDockUpdater(context, this);
83         mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
84         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
85     }
86 
87     @Override
getAvailabilityStatus()88     public int getAvailabilityStatus() {
89         return (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
90                 || mSavedDockUpdater != null)
91                 ? AVAILABLE
92                 : CONDITIONALLY_UNAVAILABLE;
93     }
94 
95     @Override
displayPreference(PreferenceScreen screen)96     public void displayPreference(PreferenceScreen screen) {
97         super.displayPreference(screen);
98         mPreferenceGroup = screen.findPreference(getPreferenceKey());
99         mSeeAllPreference = mPreferenceGroup.findPreference(KEY_SEE_ALL);
100         updatePreferenceVisibility();
101 
102         if (isAvailable()) {
103             final Context context = screen.getContext();
104             mBluetoothDeviceUpdater.setPrefContext(context);
105             mSavedDockUpdater.setPreferenceContext(context);
106         }
107     }
108 
109     @Override
onStart()110     public void onStart() {
111         mBluetoothDeviceUpdater.registerCallback();
112         mSavedDockUpdater.registerCallback();
113         mContext.registerReceiver(mReceiver, mIntentFilter);
114     }
115 
116     @Override
onStop()117     public void onStop() {
118         mBluetoothDeviceUpdater.unregisterCallback();
119         mSavedDockUpdater.unregisterCallback();
120         mContext.unregisterReceiver(mReceiver);
121     }
122 
init(DashboardFragment fragment)123     public void init(DashboardFragment fragment) {
124         mBluetoothDeviceUpdater = new SavedBluetoothDeviceUpdater(fragment.getContext(),
125                 fragment, PreviouslyConnectedDevicePreferenceController.this);
126     }
127 
128     @Override
onDeviceAdded(Preference preference)129     public void onDeviceAdded(Preference preference) {
130         final List<BluetoothDevice> bluetoothDevices =
131                 mBluetoothAdapter.getMostRecentlyConnectedDevices();
132         final int index = preference instanceof BluetoothDevicePreference
133                 ? bluetoothDevices.indexOf(((BluetoothDevicePreference) preference)
134                 .getBluetoothDevice().getDevice()) : DOCK_DEVICE_INDEX;
135         if (DEBUG) {
136             Log.d(TAG, "onDeviceAdded() " + preference.getTitle() + ", index of : " + index);
137             for (BluetoothDevice device : bluetoothDevices) {
138                 Log.d(TAG, "onDeviceAdded() most recently device : " + device.getName());
139             }
140         }
141         addPreference(index, preference);
142         updatePreferenceVisibility();
143     }
144 
addPreference(int index, Preference preference)145     private void addPreference(int index, Preference preference) {
146         if (preference instanceof BluetoothDevicePreference) {
147             if (mDevicesList.size() >= index) {
148                 mDevicesList.add(index, preference);
149             } else {
150                 mDevicesList.add(preference);
151             }
152         } else {
153             mDockDevicesList.add(preference);
154         }
155         addPreference();
156     }
157 
addPreference()158     private void addPreference() {
159         mPreferenceGroup.removeAll();
160         mPreferenceGroup.addPreference(mSeeAllPreference);
161         final int size = getDeviceListSize();
162         for (int i = 0; i < size; i++) {
163             if (DEBUG) {
164                 Log.d(TAG, "addPreference() add device : " + mDevicesList.get(i).getTitle());
165             }
166             mDevicesList.get(i).setOrder(i);
167             mPreferenceGroup.addPreference(mDevicesList.get(i));
168         }
169         if (mDockDevicesList.size() > 0) {
170             for (int i = 0; i < getDockDeviceListSize(MAX_DEVICE_NUM - size); i++) {
171                 if (DEBUG) {
172                     Log.d(TAG, "addPreference() add dock device : "
173                             + mDockDevicesList.get(i).getTitle());
174                 }
175                 mDockDevicesList.get(i).setOrder(DOCK_DEVICE_INDEX);
176                 mPreferenceGroup.addPreference(mDockDevicesList.get(i));
177             }
178         }
179     }
180 
getDeviceListSize()181     private int getDeviceListSize() {
182         return mDevicesList.size() >= MAX_DEVICE_NUM
183                 ? MAX_DEVICE_NUM : mDevicesList.size();
184     }
185 
getDockDeviceListSize(int availableSize)186     private int getDockDeviceListSize(int availableSize) {
187         return mDockDevicesList.size() >= availableSize
188                 ? availableSize : mDockDevicesList.size();
189     }
190 
191     @Override
onDeviceRemoved(Preference preference)192     public void onDeviceRemoved(Preference preference) {
193         if (preference instanceof BluetoothDevicePreference) {
194             mDevicesList.remove(preference);
195         } else {
196             mDockDevicesList.remove(preference);
197         }
198 
199         addPreference();
200         updatePreferenceVisibility();
201     }
202 
203     @VisibleForTesting
setBluetoothDeviceUpdater(BluetoothDeviceUpdater bluetoothDeviceUpdater)204     void setBluetoothDeviceUpdater(BluetoothDeviceUpdater bluetoothDeviceUpdater) {
205         mBluetoothDeviceUpdater = bluetoothDeviceUpdater;
206     }
207 
208     @VisibleForTesting
setSavedDockUpdater(DockUpdater savedDockUpdater)209     void setSavedDockUpdater(DockUpdater savedDockUpdater) {
210         mSavedDockUpdater = savedDockUpdater;
211     }
212 
213     @VisibleForTesting
setPreferenceGroup(PreferenceGroup preferenceGroup)214     void setPreferenceGroup(PreferenceGroup preferenceGroup) {
215         mPreferenceGroup = preferenceGroup;
216     }
217 
218     @VisibleForTesting
updatePreferenceVisibility()219     void updatePreferenceVisibility() {
220         if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
221             mSeeAllPreference.setSummary("");
222         } else {
223             mSeeAllPreference.setSummary(
224                     mContext.getString(R.string.connected_device_see_all_summary));
225         }
226     }
227 }
228