• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.systemui.qs.tiles.dialog;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.graphics.drawable.Drawable;
22 import android.text.Html;
23 import android.text.TextUtils;
24 import android.util.Log;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.view.WindowManager;
29 import android.widget.ImageView;
30 import android.widget.LinearLayout;
31 import android.widget.TextView;
32 
33 import androidx.annotation.NonNull;
34 import androidx.annotation.Nullable;
35 import androidx.recyclerview.widget.RecyclerView;
36 
37 import com.android.internal.annotations.VisibleForTesting;
38 import com.android.settingslib.Utils;
39 import com.android.settingslib.wifi.WifiUtils;
40 import com.android.systemui.res.R;
41 import com.android.wifi.flags.Flags;
42 import com.android.wifitrackerlib.WifiEntry;
43 
44 import kotlinx.coroutines.CoroutineScope;
45 import kotlinx.coroutines.Job;
46 
47 import java.util.List;
48 import java.util.concurrent.atomic.AtomicReference;
49 
50 /**
51  * Adapter for showing Wi-Fi networks.
52  */
53 public class InternetAdapter extends RecyclerView.Adapter<InternetAdapter.InternetViewHolder> {
54 
55     private static final String TAG = "InternetAdapter";
56 
57     private final InternetDetailsContentController mInternetDetailsContentController;
58     private final CoroutineScope mCoroutineScope;
59     @Nullable
60     private List<WifiEntry> mWifiEntries;
61     @VisibleForTesting
62     protected int mWifiEntriesCount;
63     @VisibleForTesting
64     protected int mMaxEntriesCount = InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT;
65 
66     protected View mHolderView;
67     protected Context mContext;
68 
InternetAdapter(InternetDetailsContentController controller, CoroutineScope coroutineScope)69     public InternetAdapter(InternetDetailsContentController controller,
70             CoroutineScope coroutineScope) {
71         mInternetDetailsContentController = controller;
72         mCoroutineScope = coroutineScope;
73     }
74 
75     @Override
onCreateViewHolder(@onNull ViewGroup viewGroup, int viewType)76     public InternetViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
77             int viewType) {
78         mContext = viewGroup.getContext();
79         mHolderView = LayoutInflater.from(mContext).inflate(R.layout.internet_list_item,
80                 viewGroup, false);
81         return new InternetViewHolder(mHolderView, mInternetDetailsContentController,
82                 mCoroutineScope);
83     }
84 
85     @Override
onBindViewHolder(@onNull InternetViewHolder viewHolder, int position)86     public void onBindViewHolder(@NonNull InternetViewHolder viewHolder, int position) {
87         if (mWifiEntries == null || position >= mWifiEntriesCount) {
88             return;
89         }
90         viewHolder.onBind(mWifiEntries.get(position));
91     }
92 
93     /**
94      * Updates the Wi-Fi networks.
95      *
96      * @param wifiEntries the updated Wi-Fi entries.
97      * @param wifiEntriesCount the total number of Wi-Fi entries.
98      */
setWifiEntries(@ullable List<WifiEntry> wifiEntries, int wifiEntriesCount)99     public void setWifiEntries(@Nullable List<WifiEntry> wifiEntries, int wifiEntriesCount) {
100         mWifiEntries = wifiEntries;
101         mWifiEntriesCount =
102                 (wifiEntriesCount < mMaxEntriesCount) ? wifiEntriesCount : mMaxEntriesCount;
103     }
104 
105     /**
106      * Gets the total number of Wi-Fi networks.
107      *
108      * @return The total number of Wi-Fi entries.
109      */
110     @Override
getItemCount()111     public int getItemCount() {
112         return mWifiEntriesCount;
113     }
114 
115     /**
116      * Sets the maximum number of Wi-Fi networks.
117      */
setMaxEntriesCount(int count)118     public void setMaxEntriesCount(int count) {
119         if (count < 0 || mMaxEntriesCount == count) {
120             return;
121         }
122         mMaxEntriesCount = count;
123         if (mWifiEntriesCount > count) {
124             mWifiEntriesCount = count;
125             notifyDataSetChanged();
126         }
127     }
128 
129     /**
130      * ViewHolder for binding Wi-Fi view.
131      */
132     static class InternetViewHolder extends RecyclerView.ViewHolder {
133 
134         final LinearLayout mContainerLayout;
135         final LinearLayout mWifiListLayout;
136         final LinearLayout mWifiNetworkLayout;
137         final ImageView mWifiIcon;
138         final TextView mWifiTitleText;
139         final TextView mWifiSummaryText;
140         final ImageView mWifiEndIcon;
141         final Context mContext;
142         final InternetDetailsContentController mInternetDetailsContentController;
143         final CoroutineScope mCoroutineScope;
144         @Nullable
145         private Job mJob;
146 
InternetViewHolder(View view, InternetDetailsContentController internetDetailsContentController, CoroutineScope coroutineScope)147         InternetViewHolder(View view,
148                 InternetDetailsContentController internetDetailsContentController,
149                 CoroutineScope coroutineScope) {
150             super(view);
151             mContext = view.getContext();
152             mInternetDetailsContentController = internetDetailsContentController;
153             mCoroutineScope = coroutineScope;
154             mContainerLayout = view.requireViewById(R.id.internet_container);
155             mWifiListLayout = view.requireViewById(R.id.wifi_list);
156             mWifiNetworkLayout = view.requireViewById(R.id.wifi_network_layout);
157             mWifiIcon = view.requireViewById(R.id.wifi_icon);
158             mWifiTitleText = view.requireViewById(R.id.wifi_title);
159             mWifiSummaryText = view.requireViewById(R.id.wifi_summary);
160             mWifiEndIcon = view.requireViewById(R.id.wifi_end_icon);
161         }
162 
onBind(@onNull WifiEntry wifiEntry)163         void onBind(@NonNull WifiEntry wifiEntry) {
164             mWifiIcon.setImageDrawable(getWifiDrawable(wifiEntry));
165             setWifiNetworkLayout(wifiEntry.getTitle(),
166                     Html.fromHtml(wifiEntry.getSummary(false), Html.FROM_HTML_MODE_LEGACY));
167 
168             final int connectedState = wifiEntry.getConnectedState();
169             final int security = wifiEntry.getSecurity();
170             updateEndIcon(connectedState, security);
171 
172             mWifiListLayout.setEnabled(shouldEnabled(wifiEntry));
173             if (connectedState != WifiEntry.CONNECTED_STATE_DISCONNECTED) {
174                 mWifiListLayout.setOnClickListener(
175                         v -> mInternetDetailsContentController.launchWifiDetailsSetting(
176                                 wifiEntry.getKey(), v));
177                 return;
178             }
179             mWifiListLayout.setOnClickListener(v -> onWifiClick(wifiEntry, v));
180         }
181 
shouldEnabled(@onNull WifiEntry wifiEntry)182         boolean shouldEnabled(@NonNull WifiEntry wifiEntry) {
183             if (wifiEntry.canConnect()) {
184                 return true;
185             }
186             // If Wi-Fi is connected or saved network, leave it enabled to disconnect or configure.
187             if (wifiEntry.canDisconnect() || wifiEntry.isSaved()) {
188                 return true;
189             }
190             return false;
191         }
192 
onWifiClick(@onNull WifiEntry wifiEntry, @NonNull View view)193         void onWifiClick(@NonNull WifiEntry wifiEntry, @NonNull View view) {
194             if (Flags.androidVWifiApi() && wifiEntry.getSecurityTypes().contains(
195                     WifiEntry.SECURITY_WEP)) {
196                 if (mJob == null) {
197                     mJob = WifiUtils.checkWepAllowed(mContext, mCoroutineScope, wifiEntry.getSsid(),
198                             WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, intent -> {
199                                 mInternetDetailsContentController
200                                         .startActivityForDialog(intent);
201                                 return null;
202                             }, () -> {
203                                 wifiConnect(wifiEntry, view);
204                                 return null;
205                             }, intent -> {
206                                 mInternetDetailsContentController
207                                         .startActivityForDialogDismissDialogFirst(intent, view);
208                                 return null;
209                             });
210                 }
211                 return;
212             }
213             wifiConnect(wifiEntry, view);
214         }
215 
wifiConnect(@onNull WifiEntry wifiEntry, @NonNull View view)216         void wifiConnect(@NonNull WifiEntry wifiEntry, @NonNull View view) {
217             if (wifiEntry.shouldEditBeforeConnect()) {
218                 final Intent intent = WifiUtils.getWifiDialogIntent(wifiEntry.getKey(),
219                         true /* connectForCaller */);
220                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
221                 intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
222                 mInternetDetailsContentController.startActivityForDialog(intent);
223                 return;
224             }
225 
226             if (wifiEntry.canConnect()) {
227                 mInternetDetailsContentController.connect(wifiEntry);
228                 return;
229             }
230 
231             if (wifiEntry.isSaved()) {
232                 Log.w(TAG, "The saved Wi-Fi network does not allow to connect. SSID:"
233                         + wifiEntry.getSsid());
234                 mInternetDetailsContentController.launchWifiDetailsSetting(wifiEntry.getKey(),
235                         view);
236             }
237         }
238 
setWifiNetworkLayout(CharSequence title, CharSequence summary)239         void setWifiNetworkLayout(CharSequence title, CharSequence summary) {
240             mWifiTitleText.setText(title);
241             if (TextUtils.isEmpty(summary)) {
242                 mWifiSummaryText.setVisibility(View.GONE);
243                 return;
244             }
245             mWifiSummaryText.setVisibility(View.VISIBLE);
246             mWifiSummaryText.setText(summary);
247         }
248 
249         @Nullable
getWifiDrawable(@onNull WifiEntry wifiEntry)250         Drawable getWifiDrawable(@NonNull WifiEntry wifiEntry) {
251             Drawable drawable = mInternetDetailsContentController.getWifiDrawable(wifiEntry);
252             if (drawable == null) {
253                 return null;
254             }
255             drawable.setTint(
256                     Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorTertiary));
257             final AtomicReference<Drawable> shared = new AtomicReference<>();
258             shared.set(drawable);
259             return shared.get();
260         }
261 
updateEndIcon(int connectedState, int security)262         void updateEndIcon(int connectedState, int security) {
263             Drawable drawable = null;
264             if (connectedState != WifiEntry.CONNECTED_STATE_DISCONNECTED) {
265                 drawable = mContext.getDrawable(R.drawable.ic_settings_24dp);
266             } else if (security != WifiEntry.SECURITY_NONE && security != WifiEntry.SECURITY_OWE) {
267                 drawable = mContext.getDrawable(R.drawable.ic_friction_lock_closed);
268             }
269             if (drawable == null) {
270                 mWifiEndIcon.setVisibility(View.GONE);
271                 return;
272             }
273             mWifiEndIcon.setVisibility(View.VISIBLE);
274             mWifiEndIcon.setImageDrawable(drawable);
275         }
276     }
277 }
278