Home | History | Annotate | Download | only in setup
      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