1 /* 2 * Copyright (C) 2017 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.car.settings.wifi; 17 18 import android.annotation.NonNull; 19 import android.content.Context; 20 import android.graphics.drawable.Drawable; 21 import android.graphics.drawable.StateListDrawable; 22 import android.net.wifi.WifiManager; 23 import android.support.v7.widget.RecyclerView; 24 import android.view.LayoutInflater; 25 import android.view.View; 26 import android.view.View.OnClickListener; 27 import android.view.ViewGroup; 28 import android.widget.ImageView; 29 import android.widget.TextView; 30 import android.widget.Toast; 31 32 import androidx.car.widget.PagedListView; 33 34 import com.android.car.settings.R; 35 import com.android.car.settings.common.BaseFragment; 36 import com.android.settingslib.wifi.AccessPoint; 37 38 import java.util.List; 39 40 /** 41 * Renders {@link AccessPoint} to a view to be displayed as a row in a list. 42 */ 43 public class AccessPointListAdapter 44 extends RecyclerView.Adapter<AccessPointListAdapter.ViewHolder> 45 implements PagedListView.ItemCap { 46 private static final int NETWORK_ROW_TYPE = 1; 47 private static final int ADD_NETWORK_ROW_TYPE = 2; 48 49 private static final int[] STATE_SECURED = { 50 com.android.settingslib.R.attr.state_encrypted 51 }; 52 private static final int[] STATE_NONE = {}; 53 private static int[] wifi_signal_attributes = {com.android.settingslib.R.attr.wifi_signal}; 54 55 private final StateListDrawable mWifiSld; 56 private final Context mContext; 57 private final BaseFragment.FragmentController mFragmentController; 58 private final CarWifiManager mCarWifiManager; 59 private final WifiManager.ActionListener mConnectionListener; 60 private boolean mShowAddNetworkRow; 61 62 private List<AccessPoint> mAccessPoints; 63 AccessPointListAdapter( @onNull Context context, CarWifiManager carWifiManager, @NonNull List<AccessPoint> accesssPoints, BaseFragment.FragmentController fragmentController)64 public AccessPointListAdapter( 65 @NonNull Context context, 66 CarWifiManager carWifiManager, 67 @NonNull List<AccessPoint> accesssPoints, 68 BaseFragment.FragmentController fragmentController) { 69 mContext = context; 70 mFragmentController = fragmentController; 71 mCarWifiManager = carWifiManager; 72 mAccessPoints = accesssPoints; 73 mWifiSld = (StateListDrawable) context.getTheme() 74 .obtainStyledAttributes(wifi_signal_attributes).getDrawable(0); 75 76 mConnectionListener = new WifiManager.ActionListener() { 77 @Override 78 public void onSuccess() { 79 } 80 @Override 81 public void onFailure(int reason) { 82 Toast.makeText(mContext, 83 R.string.wifi_failed_connect_message, 84 Toast.LENGTH_SHORT).show(); 85 } 86 }; 87 } 88 89 /** 90 * Toggles the row that links to add a new network. 91 */ showAddNetworkRow(boolean show)92 public AccessPointListAdapter showAddNetworkRow(boolean show) { 93 mShowAddNetworkRow = show; 94 return this; 95 } 96 updateAccessPoints(@onNull List<AccessPoint> accesssPoints)97 public void updateAccessPoints(@NonNull List<AccessPoint> accesssPoints) { 98 mAccessPoints = accesssPoints; 99 notifyDataSetChanged(); 100 } 101 isEmpty()102 public boolean isEmpty() { 103 return mAccessPoints.isEmpty(); 104 } 105 106 public class ViewHolder extends RecyclerView.ViewHolder { 107 private final ImageView mIcon; 108 private final ImageView mRightChevron; 109 private final TextView mWifiName; 110 private final TextView mWifiDesc; 111 ViewHolder(View view)112 public ViewHolder(View view) { 113 super(view); 114 mWifiName = (TextView) view.findViewById(R.id.title); 115 mWifiDesc = (TextView) view.findViewById(R.id.desc); 116 mIcon = (ImageView) view.findViewById(R.id.icon); 117 mRightChevron = (ImageView) view.findViewById(R.id.right_chevron); 118 } 119 } 120 121 private class AccessPointClickListener implements OnClickListener { 122 private final AccessPoint mAccessPoint; 123 AccessPointClickListener(AccessPoint accessPoint)124 public AccessPointClickListener(AccessPoint accessPoint) { 125 mAccessPoint = accessPoint; 126 } 127 128 @Override onClick(View v)129 public void onClick(View v) { 130 // for new open unsecuried wifi network, connect to it right away 131 if (mAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE && 132 !mAccessPoint.isSaved() && !mAccessPoint.isActive()) { 133 mCarWifiManager.connectToPublicWifi(mAccessPoint, mConnectionListener); 134 } else if (mAccessPoint.isSaved()) { 135 mFragmentController.launchFragment(WifiDetailFragment.getInstance(mAccessPoint)); 136 } else { 137 mFragmentController.launchFragment(AddWifiFragment.getInstance(mAccessPoint)); 138 } 139 } 140 }; 141 142 @Override getItemViewType(int position)143 public int getItemViewType(int position) { 144 // the last row is the add device row 145 if (position == mAccessPoints.size()) { 146 return ADD_NETWORK_ROW_TYPE; 147 } 148 return NETWORK_ROW_TYPE; 149 } 150 151 @Override onCreateViewHolder(ViewGroup parent, int viewType)152 public AccessPointListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 153 int viewType) { 154 ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(parent.getContext()) 155 .inflate(R.layout.icon_text_line_item, parent, false)); 156 if (viewType == ADD_NETWORK_ROW_TYPE) { 157 viewHolder.mIcon.setImageResource(R.drawable.ic_add); 158 viewHolder.mWifiDesc.setVisibility(View.GONE); 159 viewHolder.mWifiName.setText(R.string.wifi_setup_add_network); 160 viewHolder.itemView.setOnClickListener(v -> { 161 mFragmentController.launchFragment(AddWifiFragment.getInstance(null)); 162 }); 163 } 164 return viewHolder; 165 } 166 167 @Override onBindViewHolder(ViewHolder holder, int position)168 public void onBindViewHolder(ViewHolder holder, int position) { 169 // for the last row, it's the "add network button", no more binding needed. 170 if (position >= mAccessPoints.size()) { 171 return; 172 } 173 AccessPoint accessPoint = mAccessPoints.get(position); 174 holder.itemView.setOnClickListener(new AccessPointClickListener(accessPoint)); 175 holder.mWifiName.setText(accessPoint.getConfigName()); 176 holder.mIcon.setImageDrawable(getIcon(accessPoint)); 177 String summary = accessPoint.getSummary(); 178 if (summary != null && !summary.isEmpty()) { 179 holder.mWifiDesc.setText(summary); 180 holder.mWifiDesc.setVisibility(View.VISIBLE); 181 } else { 182 holder.mWifiDesc.setVisibility(View.GONE); 183 } 184 if (accessPoint.getSecurity() == accessPoint.SECURITY_NONE && 185 !accessPoint.isSaved() && !accessPoint.isActive()) { 186 holder.mRightChevron.setVisibility(View.GONE); 187 } else { 188 holder.mRightChevron.setVisibility(View.VISIBLE); 189 } 190 } 191 192 @Override getItemCount()193 public int getItemCount() { 194 // number of rows include one per device and a row for add network. 195 return mShowAddNetworkRow ? mAccessPoints.size() + 1 : mAccessPoints.size(); 196 } 197 198 @Override setMaxItems(int maxItems)199 public void setMaxItems(int maxItems) { 200 // no limit in this list. 201 } 202 getIcon(AccessPoint accessPoint)203 private Drawable getIcon(AccessPoint accessPoint) { 204 mWifiSld.setState((accessPoint.getSecurity() != AccessPoint.SECURITY_NONE) 205 ? STATE_SECURED 206 : STATE_NONE); 207 Drawable drawable = mWifiSld.getCurrent(); 208 drawable.setLevel(accessPoint.getLevel()); 209 drawable.invalidateSelf(); 210 return drawable; 211 } 212 } 213