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.slice;
18 
19 import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
20 
21 import android.content.Context;
22 import android.net.Uri;
23 import android.net.wifi.WifiManager;
24 import android.text.TextUtils;
25 
26 import androidx.annotation.VisibleForTesting;
27 import androidx.lifecycle.Lifecycle;
28 import androidx.lifecycle.LifecycleOwner;
29 import androidx.lifecycle.LifecycleRegistry;
30 
31 import com.android.settings.slices.SliceBackgroundWorker;
32 import com.android.settings.wifi.WifiPickerTrackerHelper;
33 import com.android.wifitrackerlib.WifiEntry;
34 import com.android.wifitrackerlib.WifiEntry.WifiEntryCallback;
35 import com.android.wifitrackerlib.WifiPickerTracker;
36 
37 import java.util.ArrayList;
38 import java.util.List;
39 
40 /**
41  * {@link SliceBackgroundWorker} for Wi-Fi, used by {@link WifiSlice}.
42  */
43 public class WifiScanWorker extends SliceBackgroundWorker<WifiSliceItem> implements
44         WifiPickerTracker.WifiPickerTrackerCallback, LifecycleOwner, WifiEntryCallback {
45 
46     private static final String TAG = "WifiScanWorker";
47 
48     @VisibleForTesting
49     final LifecycleRegistry mLifecycleRegistry;
50     @VisibleForTesting
51     protected WifiPickerTracker mWifiPickerTracker;
52     protected WifiPickerTrackerHelper mWifiPickerTrackerHelper;
53 
WifiScanWorker(Context context, Uri uri)54     public WifiScanWorker(Context context, Uri uri) {
55         super(context, uri);
56 
57         mLifecycleRegistry = new LifecycleRegistry(this);
58 
59         mWifiPickerTrackerHelper = new WifiPickerTrackerHelper(mLifecycleRegistry, context, this);
60         mWifiPickerTracker = mWifiPickerTrackerHelper.getWifiPickerTracker();
61 
62         mLifecycleRegistry.markState(Lifecycle.State.INITIALIZED);
63         mLifecycleRegistry.markState(Lifecycle.State.CREATED);
64     }
65 
66     @Override
onSlicePinned()67     protected void onSlicePinned() {
68         mLifecycleRegistry.markState(Lifecycle.State.STARTED);
69         mLifecycleRegistry.markState(Lifecycle.State.RESUMED);
70         updateResults();
71     }
72 
73     @Override
onSliceUnpinned()74     protected void onSliceUnpinned() {
75         mLifecycleRegistry.markState(Lifecycle.State.STARTED);
76         mLifecycleRegistry.markState(Lifecycle.State.CREATED);
77     }
78 
79     @Override
close()80     public void close() {
81         mLifecycleRegistry.markState(Lifecycle.State.DESTROYED);
82     }
83 
84     @Override
getLifecycle()85     public Lifecycle getLifecycle() {
86         return mLifecycleRegistry;
87     }
88 
89     /** Called when the state of Wifi has changed. */
90     @Override
onWifiStateChanged()91     public void onWifiStateChanged() {
92         notifySliceChange();
93     }
94 
95     /**
96      * Update the results when data changes
97      */
98     @Override
onWifiEntriesChanged()99     public void onWifiEntriesChanged() {
100         updateResults();
101     }
102 
103     /**
104      * Indicates the state of the WifiEntry has changed and clients may retrieve updates through
105      * the WifiEntry getter methods.
106      */
107     @Override
onUpdated()108     public void onUpdated() {
109         updateResults();
110     }
111 
getApRowCount()112     protected int getApRowCount() {
113         return DEFAULT_EXPANDED_ROW_COUNT;
114     }
115 
116     @Override
onNumSavedSubscriptionsChanged()117     public void onNumSavedSubscriptionsChanged() {
118         // Do nothing.
119     }
120 
121     @Override
onNumSavedNetworksChanged()122     public void onNumSavedNetworksChanged() {
123         // Do nothing.
124     }
125 
126     /**
127      * To get the WifiEntry of key.
128      */
getWifiEntry(String key)129     public WifiEntry getWifiEntry(String key) {
130         // Get specified WifiEntry.
131         WifiEntry keyWifiEntry = null;
132         final WifiEntry connectedWifiEntry = mWifiPickerTracker.getConnectedWifiEntry();
133         if (connectedWifiEntry != null && TextUtils.equals(key, connectedWifiEntry.getKey())) {
134             keyWifiEntry = connectedWifiEntry;
135         } else {
136             for (WifiEntry wifiEntry : mWifiPickerTracker.getWifiEntries()) {
137                 if (TextUtils.equals(key, wifiEntry.getKey())) {
138                     keyWifiEntry = wifiEntry;
139                     break;
140                 }
141             }
142         }
143         return keyWifiEntry;
144     }
145 
146     @VisibleForTesting
updateResults()147     void updateResults() {
148         if (mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED
149                 || mLifecycleRegistry.getCurrentState() != Lifecycle.State.RESUMED) {
150             super.updateResults(null);
151             return;
152         }
153 
154         final List<WifiSliceItem> resultList = new ArrayList<>();
155         final WifiEntry connectedWifiEntry = mWifiPickerTracker.getConnectedWifiEntry();
156         if (connectedWifiEntry != null) {
157             connectedWifiEntry.setListener(this);
158             resultList.add(new WifiSliceItem(getContext(), connectedWifiEntry));
159         }
160         for (WifiEntry wifiEntry : mWifiPickerTracker.getWifiEntries()) {
161             if (resultList.size() >= getApRowCount()) {
162                 break;
163             }
164             if (wifiEntry.getLevel() != WifiEntry.WIFI_LEVEL_UNREACHABLE) {
165                 wifiEntry.setListener(this);
166                 resultList.add(new WifiSliceItem(getContext(), wifiEntry));
167             }
168         }
169         super.updateResults(resultList);
170     }
171 
172     /** Enables/disables the carrier network if the carrier network provision disabled */
setCarrierNetworkEnabledIfNeeded(boolean enabled, int subId)173     public void setCarrierNetworkEnabledIfNeeded(boolean enabled, int subId) {
174         if (!mWifiPickerTrackerHelper.isCarrierNetworkProvisionEnabled(subId)) {
175             mWifiPickerTrackerHelper.setCarrierNetworkEnabled(enabled);
176         }
177     }
178 
179     /** Connect to the carrier network */
connectCarrierNetwork()180     public void connectCarrierNetwork() {
181         mWifiPickerTrackerHelper.connectCarrierNetwork(null /* ConnectCallback */);
182     }
183 }
184