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.view.LayoutInflater; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import android.widget.ImageView; 28 import android.widget.LinearLayout; 29 import android.widget.TextView; 30 31 import androidx.annotation.NonNull; 32 import androidx.annotation.Nullable; 33 import androidx.recyclerview.widget.RecyclerView; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 import com.android.settingslib.Utils; 37 import com.android.settingslib.wifi.WifiUtils; 38 import com.android.systemui.R; 39 import com.android.wifitrackerlib.WifiEntry; 40 41 import java.util.List; 42 import java.util.concurrent.atomic.AtomicReference; 43 44 /** 45 * Adapter for showing Wi-Fi networks. 46 */ 47 public class InternetAdapter extends RecyclerView.Adapter<InternetAdapter.InternetViewHolder> { 48 49 private static final String TAG = "InternetAdapter"; 50 private static final String ACTION_WIFI_DIALOG = "com.android.settings.WIFI_DIALOG"; 51 private static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key"; 52 private static final String EXTRA_CONNECT_FOR_CALLER = "connect_for_caller"; 53 54 private final InternetDialogController mInternetDialogController; 55 private List<WifiEntry> mWifiEntries; 56 @VisibleForTesting 57 protected int mWifiEntriesCount; 58 @VisibleForTesting 59 protected int mMaxEntriesCount = InternetDialogController.MAX_WIFI_ENTRY_COUNT; 60 61 protected View mHolderView; 62 protected Context mContext; 63 InternetAdapter(InternetDialogController controller)64 public InternetAdapter(InternetDialogController controller) { 65 mInternetDialogController = controller; 66 } 67 68 @Override onCreateViewHolder(@onNull ViewGroup viewGroup, int viewType)69 public InternetViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, 70 int viewType) { 71 mContext = viewGroup.getContext(); 72 mHolderView = LayoutInflater.from(mContext).inflate(R.layout.internet_list_item, 73 viewGroup, false); 74 return new InternetViewHolder(mHolderView, mInternetDialogController); 75 } 76 77 @Override onBindViewHolder(@onNull InternetViewHolder viewHolder, int position)78 public void onBindViewHolder(@NonNull InternetViewHolder viewHolder, int position) { 79 if (mWifiEntries == null || position >= mWifiEntriesCount) { 80 return; 81 } 82 viewHolder.onBind(mWifiEntries.get(position)); 83 } 84 85 /** 86 * Updates the Wi-Fi networks. 87 * 88 * @param wifiEntries the updated Wi-Fi entries. 89 * @param wifiEntriesCount the total number of Wi-Fi entries. 90 */ setWifiEntries(@ullable List<WifiEntry> wifiEntries, int wifiEntriesCount)91 public void setWifiEntries(@Nullable List<WifiEntry> wifiEntries, int wifiEntriesCount) { 92 mWifiEntries = wifiEntries; 93 mWifiEntriesCount = 94 (wifiEntriesCount < mMaxEntriesCount) ? wifiEntriesCount : mMaxEntriesCount; 95 } 96 97 /** 98 * Gets the total number of Wi-Fi networks. 99 * 100 * @return The total number of Wi-Fi entries. 101 */ 102 @Override getItemCount()103 public int getItemCount() { 104 return mWifiEntriesCount; 105 } 106 107 /** 108 * Sets the maximum number of Wi-Fi networks. 109 */ setMaxEntriesCount(int count)110 public void setMaxEntriesCount(int count) { 111 if (count < 0 || mMaxEntriesCount == count) { 112 return; 113 } 114 mMaxEntriesCount = count; 115 if (mWifiEntriesCount > count) { 116 mWifiEntriesCount = count; 117 notifyDataSetChanged(); 118 } 119 } 120 121 /** 122 * ViewHolder for binding Wi-Fi view. 123 */ 124 static class InternetViewHolder extends RecyclerView.ViewHolder { 125 126 final LinearLayout mContainerLayout; 127 final LinearLayout mWifiListLayout; 128 final LinearLayout mWifiNetworkLayout; 129 final ImageView mWifiIcon; 130 final TextView mWifiTitleText; 131 final TextView mWifiSummaryText; 132 final ImageView mWifiEndIcon; 133 final Context mContext; 134 final InternetDialogController mInternetDialogController; 135 136 @VisibleForTesting 137 protected WifiUtils.InternetIconInjector mWifiIconInjector; 138 InternetViewHolder(View view, InternetDialogController internetDialogController)139 InternetViewHolder(View view, InternetDialogController internetDialogController) { 140 super(view); 141 mContext = view.getContext(); 142 mInternetDialogController = internetDialogController; 143 mContainerLayout = view.requireViewById(R.id.internet_container); 144 mWifiListLayout = view.requireViewById(R.id.wifi_list); 145 mWifiNetworkLayout = view.requireViewById(R.id.wifi_network_layout); 146 mWifiIcon = view.requireViewById(R.id.wifi_icon); 147 mWifiTitleText = view.requireViewById(R.id.wifi_title); 148 mWifiSummaryText = view.requireViewById(R.id.wifi_summary); 149 mWifiEndIcon = view.requireViewById(R.id.wifi_end_icon); 150 mWifiIconInjector = mInternetDialogController.getWifiIconInjector(); 151 } 152 onBind(@onNull WifiEntry wifiEntry)153 void onBind(@NonNull WifiEntry wifiEntry) { 154 mWifiIcon.setImageDrawable( 155 getWifiDrawable(wifiEntry.getLevel(), wifiEntry.shouldShowXLevelIcon())); 156 setWifiNetworkLayout(wifiEntry.getTitle(), 157 Html.fromHtml(wifiEntry.getSummary(false), Html.FROM_HTML_MODE_LEGACY)); 158 159 final int connectedState = wifiEntry.getConnectedState(); 160 final int security = wifiEntry.getSecurity(); 161 updateEndIcon(connectedState, security); 162 163 if (connectedState != WifiEntry.CONNECTED_STATE_DISCONNECTED) { 164 mWifiListLayout.setOnClickListener( 165 v -> mInternetDialogController.launchWifiNetworkDetailsSetting( 166 wifiEntry.getKey())); 167 return; 168 } 169 mWifiListLayout.setOnClickListener(v -> { 170 if (wifiEntry.shouldEditBeforeConnect()) { 171 final Intent intent = new Intent(ACTION_WIFI_DIALOG); 172 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 173 intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 174 intent.putExtra(EXTRA_CHOSEN_WIFI_ENTRY_KEY, wifiEntry.getKey()); 175 intent.putExtra(EXTRA_CONNECT_FOR_CALLER, false); 176 mContext.startActivity(intent); 177 } 178 mInternetDialogController.connect(wifiEntry); 179 }); 180 } 181 setWifiNetworkLayout(CharSequence title, CharSequence summary)182 void setWifiNetworkLayout(CharSequence title, CharSequence summary) { 183 mWifiTitleText.setText(title); 184 if (TextUtils.isEmpty(summary)) { 185 mWifiSummaryText.setVisibility(View.GONE); 186 return; 187 } 188 mWifiSummaryText.setVisibility(View.VISIBLE); 189 mWifiSummaryText.setText(summary); 190 } 191 getWifiDrawable(int level, boolean hasNoInternet)192 Drawable getWifiDrawable(int level, boolean hasNoInternet) { 193 // If the Wi-Fi level is equal to WIFI_LEVEL_UNREACHABLE(-1), then a null drawable 194 // will be returned. 195 if (level == WifiEntry.WIFI_LEVEL_UNREACHABLE) { 196 return null; 197 } 198 final Drawable drawable = mWifiIconInjector.getIcon(hasNoInternet, level); 199 if (drawable == null) { 200 return null; 201 } 202 drawable.setTint( 203 Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorTertiary)); 204 final AtomicReference<Drawable> shared = new AtomicReference<>(); 205 shared.set(drawable); 206 return shared.get(); 207 } 208 updateEndIcon(int connectedState, int security)209 void updateEndIcon(int connectedState, int security) { 210 Drawable drawable = null; 211 if (connectedState != WifiEntry.CONNECTED_STATE_DISCONNECTED) { 212 drawable = mContext.getDrawable(R.drawable.ic_settings_24dp); 213 } else if (security != WifiEntry.SECURITY_NONE && security != WifiEntry.SECURITY_OWE) { 214 drawable = mContext.getDrawable(R.drawable.ic_friction_lock_closed); 215 } 216 if (drawable == null) { 217 mWifiEndIcon.setVisibility(View.GONE); 218 return; 219 } 220 mWifiEndIcon.setVisibility(View.VISIBLE); 221 mWifiEndIcon.setImageDrawable(drawable); 222 } 223 } 224 } 225