1 /* 2 * Copyright (C) 2014 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.tv.settings.connectivity.setup; 18 19 import com.android.tv.settings.R; 20 import com.android.tv.settings.connectivity.WifiSecurity; 21 import com.android.tv.settings.util.AccessibilityHelper; 22 import com.android.tv.settings.widget.ScrollAdapterView; 23 import com.android.tv.settings.widget.ScrollArrayAdapter; 24 25 import android.app.Activity; 26 import android.app.Fragment; 27 import android.content.Context; 28 import android.net.wifi.ScanResult; 29 import android.net.wifi.WifiManager; 30 import android.os.Bundle; 31 import android.os.Handler; 32 import android.os.Parcel; 33 import android.os.Parcelable; 34 import android.text.TextUtils; 35 import android.util.Log; 36 import android.view.KeyEvent; 37 import android.view.LayoutInflater; 38 import android.view.View; 39 import android.view.ViewGroup; 40 import android.view.inputmethod.InputMethodManager; 41 import android.widget.AdapterView; 42 import android.widget.EditText; 43 import android.widget.FrameLayout; 44 import android.widget.ImageView; 45 import android.widget.TextView; 46 47 import java.util.ArrayList; 48 import java.util.Comparator; 49 50 /** 51 * Displays a UI for selecting a wifi network from a list in the "wizard" style. 52 */ 53 public class SelectFromListWizardFragment extends Fragment { 54 55 private static final String TAG = "SelectFromListWizardFragment"; 56 private static final boolean DEBUG = false; 57 58 public static class ListItemComparator implements Comparator<ListItem> { 59 @Override 60 public int compare(ListItem o1, ListItem o2) { 61 ScanResult o1ScanResult = o1.getScanResult(); 62 ScanResult o2ScanResult = o2.getScanResult(); 63 if (o1ScanResult == null) { 64 if (o2ScanResult == null) { 65 return 0; 66 } else { 67 return 1; 68 } 69 } else { 70 if (o2ScanResult == null) { 71 return -1; 72 } else { 73 int levelDiff = o2ScanResult.level - o1ScanResult.level; 74 if (levelDiff != 0) { 75 return levelDiff; 76 } 77 return o1ScanResult.SSID.compareTo(o2ScanResult.SSID); 78 } 79 } 80 } 81 } 82 83 public static class ListItem implements Parcelable { 84 85 private final String mName; 86 private final int mIconResource; 87 private final int mIconLevel; 88 private final boolean mHasIconLevel; 89 private final ScanResult mScanResult; 90 91 public ListItem(String name, int iconResource) { 92 mName = name; 93 mIconResource = iconResource; 94 mIconLevel = 0; 95 mHasIconLevel = false; 96 mScanResult = null; 97 } 98 99 public ListItem(ScanResult scanResult) { 100 mName = scanResult.SSID; 101 mIconResource = WifiSecurity.isOpen(scanResult) ? R.drawable.setup_wifi_signal_open 102 : R.drawable.setup_wifi_signal_lock; 103 mIconLevel = WifiManager.calculateSignalLevel(scanResult.level, 4); 104 mHasIconLevel = true; 105 mScanResult = scanResult; 106 } 107 108 public String getName() { 109 return mName; 110 } 111 112 int getIconResource() { 113 return mIconResource; 114 } 115 116 int getIconLevel() { 117 return mIconLevel; 118 } 119 120 boolean hasIconLevel() { 121 return mHasIconLevel; 122 } 123 124 ScanResult getScanResult() { 125 return mScanResult; 126 } 127 128 @Override 129 public String toString() { 130 return mName; 131 } 132 133 public static Parcelable.Creator<ListItem> CREATOR = new Parcelable.Creator<ListItem>() { 134 135 @Override 136 public ListItem createFromParcel(Parcel source) { 137 ScanResult scanResult = (ScanResult) source.readParcelable( 138 ScanResult.class.getClassLoader()); 139 if (scanResult == null) { 140 return new ListItem(source.readString(), source.readInt()); 141 } else { 142 return new ListItem(scanResult); 143 } 144 } 145 146 @Override 147 public ListItem[] newArray(int size) { 148 return new ListItem[size]; 149 } 150 }; 151 152 @Override 153 public int describeContents() { 154 return 0; 155 } 156 157 @Override 158 public void writeToParcel(Parcel dest, int flags) { 159 dest.writeParcelable(mScanResult, flags); 160 if (mScanResult == null) { 161 dest.writeString(mName); 162 dest.writeInt(mIconResource); 163 } 164 } 165 166 @Override 167 public boolean equals(Object o) { 168 if (o instanceof ListItem) { 169 ListItem li = (ListItem) o; 170 if (mScanResult == null && li.mScanResult == null) { 171 return mName.equals(li.mName); 172 } 173 return (mScanResult != null && li.mScanResult != null && mName.equals(li.mName) && 174 WifiSecurity.getSecurity(mScanResult) 175 == WifiSecurity.getSecurity(li.mScanResult)); 176 } 177 return false; 178 } 179 } 180 181 public interface Listener { 182 void onListSelectionComplete(ListItem listItem); 183 void onListFocusChanged(ListItem listItem); 184 } 185 186 private static final String EXTRA_TITLE = "title"; 187 private static final String EXTRA_DESCRIPTION = "description"; 188 private static final String EXTRA_LIST_ELEMENTS = "list_elements"; 189 private static final String EXTRA_LAST_SELECTION = "last_selection"; 190 191 public static SelectFromListWizardFragment newInstance(String title, String description, 192 ArrayList<ListItem> listElements, ListItem lastSelection) { 193 SelectFromListWizardFragment fragment = new SelectFromListWizardFragment(); 194 Bundle args = new Bundle(); 195 args.putString(EXTRA_TITLE, title); 196 args.putString(EXTRA_DESCRIPTION, description); 197 args.putParcelableArrayList(EXTRA_LIST_ELEMENTS, listElements); 198 args.putParcelable(EXTRA_LAST_SELECTION, lastSelection); 199 fragment.setArguments(args); 200 return fragment; 201 } 202 203 private Handler mHandler; 204 private View mMainView; 205 private ScrollArrayAdapter<ListItem> mAdapter; 206 private ScrollAdapterView mScrollAdapterView; 207 private ArrayList<ListItem> mListItems; 208 private ListItem mLastSelected; 209 210 public void update(ArrayList<ListItem> listElements) { 211 ListItem lastSelection = mLastSelected; 212 mListItems = listElements; 213 mAdapter.clear(); 214 mAdapter.addAll(listElements); 215 if (lastSelection != null) { 216 for (int i = 0, size = listElements.size(); i < size; i++) { 217 if (lastSelection.equals(listElements.get(i))) { 218 if (DEBUG) { 219 Log.d(TAG, "Found " + lastSelection.getName() + " with ssid " 220 + (mLastSelected.getScanResult() == null ? null 221 : mLastSelected.getScanResult().SSID) 222 + " and bssid " + (mLastSelected.getScanResult() == null ? null 223 : mLastSelected.getScanResult().BSSID)); 224 } 225 mScrollAdapterView.setSelection(i); 226 break; 227 } 228 } 229 } 230 } 231 232 @Override 233 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { 234 mHandler = new Handler(); 235 mMainView = inflater.inflate(R.layout.account_content_area, container, false); 236 View content = inflater.inflate(R.layout.wifi_content, null); 237 mScrollAdapterView = (ScrollAdapterView) inflater.inflate( 238 R.layout.setup_scroll_adapter_view, null); 239 ((ViewGroup) mMainView.findViewById(R.id.description)).addView(content); 240 ((ViewGroup) mMainView.findViewById(R.id.action)).addView(mScrollAdapterView); 241 242 TextView titleText = (TextView) content.findViewById(R.id.title_text); 243 TextView descriptionText = (TextView) content.findViewById(R.id.description_text); 244 245 Bundle args = getArguments(); 246 String title = args.getString(EXTRA_TITLE); 247 String description = args.getString(EXTRA_DESCRIPTION); 248 mListItems = args.getParcelableArrayList(EXTRA_LIST_ELEMENTS); 249 ListItem lastSelection = args.getParcelable(EXTRA_LAST_SELECTION); 250 251 mAdapter = new ScrollArrayAdapter<ListItem>(getActivity(), R.layout.setup_list_item, 252 R.id.list_item_text, mListItems) { 253 @Override 254 public View getView(int position, View convertView, ViewGroup parent) { 255 View v = super.getView(position, convertView, parent); 256 ListItem item = getItem(position); 257 FrameLayout iconHolder = (FrameLayout) v.findViewById(R.id.list_item_icon); 258 iconHolder.removeAllViews(); 259 Activity a = getActivity(); 260 if (a != null) { 261 ImageView icon = new ImageView(a); 262 icon.setImageResource(item.getIconResource()); 263 if (item.hasIconLevel()) { 264 icon.setImageLevel(item.getIconLevel()); 265 } 266 iconHolder.addView(icon); 267 } 268 return v; 269 } 270 }; 271 mScrollAdapterView.setAdapter(mAdapter); 272 273 boolean forceFocusable = AccessibilityHelper.forceFocusableViews(getActivity()); 274 if (title != null) { 275 titleText.setText(title); 276 titleText.setVisibility(View.VISIBLE); 277 if (forceFocusable) { 278 titleText.setFocusable(true); 279 titleText.setFocusableInTouchMode(true); 280 } 281 } else { 282 titleText.setVisibility(View.GONE); 283 } 284 285 if (description != null) { 286 descriptionText.setText(description); 287 descriptionText.setVisibility(View.VISIBLE); 288 if (forceFocusable) { 289 descriptionText.setFocusable(true); 290 descriptionText.setFocusableInTouchMode(true); 291 } 292 } else { 293 descriptionText.setVisibility(View.GONE); 294 } 295 296 if (lastSelection != null) { 297 for (int i = 0, size = mListItems.size(); i < size; i++) { 298 if (lastSelection.equals(mListItems.get(i))) { 299 mScrollAdapterView.setSelection(i); 300 break; 301 } 302 } 303 } 304 305 mScrollAdapterView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 306 @Override 307 public void onItemClick(AdapterView<?> pare, View view, int position, long id) { 308 Activity a = getActivity(); 309 if (a instanceof Listener) { 310 ((Listener) a).onListSelectionComplete(mListItems.get(position)); 311 } 312 } 313 }); 314 315 mScrollAdapterView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 316 @Override 317 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 318 mLastSelected = mListItems.get(position); 319 if (DEBUG) { 320 Log.d(TAG, "Scrolled to " + mLastSelected.getName() + " with ssid " 321 + (mLastSelected.getScanResult() == null ? null 322 : mLastSelected.getScanResult().SSID) + " and bssid " 323 + (mLastSelected.getScanResult() == null ? null 324 : mLastSelected.getScanResult().BSSID)); 325 } 326 Activity a = getActivity(); 327 if (a instanceof Listener) { 328 ((Listener) a).onListFocusChanged(mLastSelected); 329 } 330 } 331 332 @Override 333 public void onNothingSelected(AdapterView<?> parent) { 334 } 335 336 }); 337 338 return mMainView; 339 } 340 341 @Override 342 public void onResume() { 343 super.onResume(); 344 mHandler.post(new Runnable() { 345 @Override 346 public void run() { 347 InputMethodManager inputMethodManager = (InputMethodManager) getActivity() 348 .getSystemService(Context.INPUT_METHOD_SERVICE); 349 inputMethodManager.hideSoftInputFromWindow( 350 mMainView.getApplicationWindowToken(), 0); 351 } 352 }); 353 } 354 } 355