1 /*
2  * Copyright (C) 2019 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.wifi.savedaccesspoints2;
18 
19 import android.content.Context;
20 import android.text.TextUtils;
21 
22 import androidx.annotation.VisibleForTesting;
23 import androidx.preference.Preference;
24 import androidx.preference.PreferenceGroup;
25 import androidx.preference.PreferenceScreen;
26 
27 import com.android.settings.core.BasePreferenceController;
28 import com.android.settings.wifi.WifiEntryPreference;
29 import com.android.wifitrackerlib.WifiEntry;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 
34 /**
35  * Controller that manages a PreferenceGroup, which contains a list of saved access points.
36  */
37 public class SavedAccessPointsPreferenceController2 extends BasePreferenceController implements
38         Preference.OnPreferenceClickListener {
39 
40     private PreferenceGroup mPreferenceGroup;
41     private SavedAccessPointsWifiSettings2 mHost;
42     @VisibleForTesting
43     List<WifiEntry> mWifiEntries = new ArrayList<>();
44 
SavedAccessPointsPreferenceController2(Context context, String preferenceKey)45     public SavedAccessPointsPreferenceController2(Context context, String preferenceKey) {
46         super(context, preferenceKey);
47     }
48 
49     /**
50      * Set {@link SavedAccessPointsWifiSettings2} for click callback action.
51      */
setHost(SavedAccessPointsWifiSettings2 host)52     public SavedAccessPointsPreferenceController2 setHost(SavedAccessPointsWifiSettings2 host) {
53         mHost = host;
54         return this;
55     }
56 
57     @Override
getAvailabilityStatus()58     public int getAvailabilityStatus() {
59         return mWifiEntries.size() > 0 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
60     }
61 
62     @Override
displayPreference(PreferenceScreen screen)63     public void displayPreference(PreferenceScreen screen) {
64         mPreferenceGroup = screen.findPreference(getPreferenceKey());
65         updatePreference();
66         super.displayPreference(screen);
67     }
68 
69     @VisibleForTesting
displayPreference(PreferenceScreen screen, List<WifiEntry> wifiEntries)70     void displayPreference(PreferenceScreen screen, List<WifiEntry> wifiEntries) {
71         if (wifiEntries == null || wifiEntries.isEmpty()) {
72             mWifiEntries.clear();
73         } else {
74             mWifiEntries = wifiEntries;
75         }
76 
77         displayPreference(screen);
78     }
79 
80     @Override
onPreferenceClick(Preference preference)81     public boolean onPreferenceClick(Preference preference) {
82         if (mHost != null) {
83             mHost.showWifiPage(preference.getKey(), preference.getTitle());
84         }
85         return false;
86     }
87 
88     /**
89      * mPreferenceGroup is not in a RecyclerView. To keep TalkBack focus, this method should not
90      * mPreferenceGroup.removeAll() then mPreferenceGroup.addPreference for mWifiEntries.
91      */
updatePreference()92     private void updatePreference() {
93         // Update WifiEntry to existing preference and find out which WifiEntry was removed by key.
94         List<String> removedKeys = new ArrayList<>();
95         int preferenceCount = mPreferenceGroup.getPreferenceCount();
96         for (int i = 0; i < preferenceCount; i++) {
97             WifiEntryPreference pref = (WifiEntryPreference) mPreferenceGroup.getPreference(i);
98             WifiEntry wifiEntry = mWifiEntries.stream()
99                     .filter(entry -> TextUtils.equals(pref.getKey(), entry.getKey()))
100                     .findFirst()
101                     .orElse(null);
102             if (wifiEntry != null) {
103                 pref.setWifiEntry(wifiEntry);
104             } else {
105                 removedKeys.add(pref.getKey());
106             }
107         }
108         // Remove preference by WifiEntry's key.
109         for (String removedKey : removedKeys) {
110             mPreferenceGroup.removePreference(mPreferenceGroup.findPreference(removedKey));
111         }
112 
113         // Add the Preference of new added WifiEntry.
114         for (WifiEntry wifiEntry : mWifiEntries) {
115             if (mPreferenceGroup.findPreference(wifiEntry.getKey()) == null) {
116                 WifiEntryPreference preference = new WifiEntryPreference(mContext, wifiEntry);
117                 preference.setKey(wifiEntry.getKey());
118                 preference.setOnPreferenceClickListener(this);
119                 mPreferenceGroup.addPreference(preference);
120             }
121         }
122     }
123 }
124