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