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; 18 19 import android.app.Fragment; 20 import android.app.FragmentManager; 21 import android.app.FragmentTransaction; 22 import android.content.Context; 23 import android.os.Bundle; 24 import android.text.TextUtils; 25 import android.util.Log; 26 27 import com.android.tv.settings.connectivity.setup.MessageWizardFragment; 28 import com.android.tv.settings.connectivity.setup.PasswordInputWizardFragment; 29 import com.android.tv.settings.connectivity.setup.SelectFromListWizardFragment; 30 import com.android.tv.settings.connectivity.setup.SelectFromListWizardFragment.ListItem; 31 import com.android.tv.settings.connectivity.setup.TextInputWizardFragment; 32 import com.android.tv.settings.form.FormPage; 33 import com.android.tv.settings.form.FormPageResultListener; 34 35 import java.util.ArrayList; 36 37 /** 38 * Displays form pages. 39 */ 40 public class FormPageDisplayer 41 implements TextInputWizardFragment.Listener, SelectFromListWizardFragment.Listener, 42 PasswordInputWizardFragment.Listener { 43 44 public static final int DISPLAY_TYPE_TEXT_INPUT = 1; 45 public static final int DISPLAY_TYPE_LIST_CHOICE = 2; 46 public static final int DISPLAY_TYPE_LOADING = 3; 47 // Minimum 5 characters for WEP, 8 characters for PSK 48 public static final int DISPLAY_TYPE_PSK_INPUT = 4; 49 50 private static final int WEP_MIN_LENGTH = 5; 51 public static final int PSK_MIN_LENGTH = 8; 52 53 public interface FormPageInfo { 54 /** 55 * @return the resource id of the title for this page. 56 */ 57 int getTitleResourceId(); 58 59 /** 60 * @return the resource id of the description for this page. 0 if no description. 61 */ 62 int getDescriptionResourceId(); 63 64 /** 65 * @return the input type for the editable text field for this page. 66 */ 67 int getInputType(); 68 69 /** 70 * @return the way this form page should be displayed. 71 */ 72 int getDisplayType(); 73 74 /** 75 * @return the default value for this input 76 */ 77 int getDefaultPrefillResourceId(); 78 79 /** 80 * @return the set of choices for this form page. 81 */ 82 ArrayList<SelectFromListWizardFragment.ListItem> getChoices(Context context, 83 ArrayList<SelectFromListWizardFragment.ListItem> extraChoices); 84 } 85 86 public interface UserActivityListener { 87 void onUserActivity(); 88 } 89 90 private static final String TAG = "FormPageDisplayer"; 91 private static final boolean DEBUG = false; 92 private static final String RESULT_LIST_ITEM = "result_list_item"; 93 94 private final Context mContext; 95 private final FragmentManager mFragmentManager; 96 private TextInputWizardFragment.Listener mTextInputWizardFragmentListener; 97 private PasswordInputWizardFragment.Listener mPasswordInputWizardFragmentListener; 98 private SelectFromListWizardFragment.Listener mSelectFromListWizardFragmentListener; 99 private final int mContentViewId; 100 101 public FormPageDisplayer(Context context, FragmentManager fragmentManager, int contentViewId) { 102 mContext = context; 103 mFragmentManager = fragmentManager; 104 mContentViewId = contentViewId; 105 } 106 107 @Override 108 public boolean onTextInputComplete(String text) { 109 if (mTextInputWizardFragmentListener != null) { 110 return mTextInputWizardFragmentListener.onTextInputComplete(text); 111 } 112 return true; 113 } 114 115 @Override 116 public boolean onPasswordInputComplete(String text, boolean obfuscate) { 117 if (mPasswordInputWizardFragmentListener != null) { 118 return mPasswordInputWizardFragmentListener.onPasswordInputComplete(text, obfuscate); 119 } 120 return true; 121 } 122 123 @Override 124 public void onListSelectionComplete(ListItem listItem) { 125 if (mSelectFromListWizardFragmentListener != null) { 126 mSelectFromListWizardFragmentListener.onListSelectionComplete(listItem); 127 } 128 } 129 130 @Override 131 public void onListFocusChanged(ListItem listItem) { 132 if (mSelectFromListWizardFragmentListener != null) { 133 mSelectFromListWizardFragmentListener.onListFocusChanged(listItem); 134 } 135 } 136 137 public Fragment displayPage(FormPageInfo formPageInfo, String titleArgument, 138 String descriptionArgument, 139 ArrayList<SelectFromListWizardFragment.ListItem> extraChoices, 140 FormPage previousFormPage, UserActivityListener userActivityListener, 141 boolean showProgress, FormPage currentFormPage, 142 FormPageResultListener formPageResultListener, boolean forward, boolean emptyAllowed) { 143 if (DEBUG) { 144 Log.d(TAG, "Displaying: " + currentFormPage.getTitle()); 145 } 146 switch (formPageInfo.getDisplayType()) { 147 case DISPLAY_TYPE_LIST_CHOICE: 148 return displayList(formPageInfo, titleArgument, descriptionArgument, extraChoices, 149 currentFormPage, formPageResultListener, previousFormPage, 150 userActivityListener, forward); 151 152 case DISPLAY_TYPE_TEXT_INPUT: 153 return displayTextInput(formPageInfo, titleArgument, descriptionArgument, 154 currentFormPage, formPageResultListener, previousFormPage, forward, 155 emptyAllowed); 156 157 case DISPLAY_TYPE_PSK_INPUT: 158 return displayPskInput(formPageInfo, titleArgument, descriptionArgument, 159 currentFormPage, formPageResultListener, previousFormPage, forward); 160 161 case DISPLAY_TYPE_LOADING: 162 return displayLoading(formPageInfo, titleArgument, showProgress, forward); 163 164 default: 165 return null; 166 } 167 } 168 169 public ListItem getListItem(FormPage formPage) { 170 return formPage.getData().getParcelable(RESULT_LIST_ITEM); 171 } 172 173 public void displayFragment(Fragment fragment, boolean forward) { 174 FragmentTransaction transaction = mFragmentManager.beginTransaction(); 175 if (forward) { 176 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 177 } else { 178 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); 179 } 180 transaction.replace(mContentViewId, fragment).commit(); 181 } 182 183 private Fragment displayList(final FormPageInfo formPageInfo, String titleArgument, 184 String descriptionArgument, 185 ArrayList<SelectFromListWizardFragment.ListItem> extraChoices, final FormPage formPage, 186 final FormPageResultListener formPageResultListener, FormPage lastPage, 187 final UserActivityListener userActivityListener, boolean forward) { 188 Fragment fragment = SelectFromListWizardFragment.newInstance( 189 getTitle(formPageInfo, titleArgument), 190 getDescription(formPageInfo, descriptionArgument), 191 formPageInfo.getChoices(mContext, extraChoices), lastPage == null ? null 192 : (ListItem) lastPage.getData().getParcelable(RESULT_LIST_ITEM)); 193 displayFragment(fragment, forward); 194 mSelectFromListWizardFragmentListener = new SelectFromListWizardFragment.Listener() { 195 @Override 196 public void onListSelectionComplete(ListItem selection) { 197 Bundle result = new Bundle(); 198 result.putParcelable(RESULT_LIST_ITEM, selection); 199 result.putString(FormPage.DATA_KEY_SUMMARY_STRING, selection.getName()); 200 formPageResultListener.onBundlePageResult(formPage, result); 201 } 202 203 @Override 204 public void onListFocusChanged(ListItem listItem) { 205 if (userActivityListener != null) { 206 userActivityListener.onUserActivity(); 207 } 208 } 209 }; 210 return fragment; 211 } 212 213 private Fragment displayTextInput(FormPageInfo formPageInfo, String titleArgument, 214 String descriptionArgument, final FormPage formPage, 215 final FormPageResultListener listener, FormPage lastPage, boolean forward, 216 final boolean emptyAllowed) { 217 final String prefill = lastPage != null && !TextUtils.isEmpty(lastPage.getDataSummary()) 218 ? lastPage.getDataSummary() : getDefaultPrefill(formPageInfo); 219 Fragment fragment = TextInputWizardFragment.newInstance( 220 getTitle(formPageInfo, titleArgument), 221 getDescription(formPageInfo, descriptionArgument), 222 formPageInfo.getInputType(), 223 prefill); 224 displayFragment(fragment, forward); 225 226 mTextInputWizardFragmentListener = new TextInputWizardFragment.Listener() { 227 @Override 228 public boolean onTextInputComplete(String text) { 229 if (!TextUtils.isEmpty(text) || emptyAllowed) { 230 Bundle result = new Bundle(); 231 result.putString(FormPage.DATA_KEY_SUMMARY_STRING, text); 232 listener.onBundlePageResult(formPage, result); 233 return true; 234 } 235 return false; 236 } 237 }; 238 return fragment; 239 } 240 241 private Fragment displayPskInput(FormPageInfo formPageInfo, String titleArgument, 242 String descriptionArgument, final FormPage formPage, 243 final FormPageResultListener listener, FormPage lastPage, boolean forward) { 244 boolean obfuscate = lastPage != null 245 ? TextUtils.equals( 246 lastPage.getDataSecondary(), PasswordInputWizardFragment.OPTION_OBFUSCATE) 247 : false; 248 Fragment fragment = 249 PasswordInputWizardFragment.newInstance(getTitle(formPageInfo, titleArgument), 250 getDescription(formPageInfo, descriptionArgument), 251 lastPage == null ? null : lastPage.getDataSummary(), obfuscate); 252 displayFragment(fragment, forward); 253 254 mPasswordInputWizardFragmentListener = new PasswordInputWizardFragment.Listener() { 255 @Override 256 public boolean onPasswordInputComplete(String text, boolean obfuscate) { 257 if (!TextUtils.isEmpty(text) && text.length() >= WEP_MIN_LENGTH) { 258 Bundle result = new Bundle(); 259 result.putString(FormPage.DATA_KEY_SUMMARY_STRING, text); 260 if (obfuscate) { 261 result.putString(FormPage.DATA_KEY_SECONDARY_STRING, 262 PasswordInputWizardFragment.OPTION_OBFUSCATE); 263 } 264 listener.onBundlePageResult(formPage, result); 265 return true; 266 } 267 return false; 268 } 269 }; 270 return fragment; 271 } 272 273 private Fragment displayLoading(FormPageInfo formPageInfo, String argument, 274 boolean showProgress, boolean forward) { 275 Fragment fragment = MessageWizardFragment.newInstance( 276 getTitle(formPageInfo, argument), showProgress); 277 displayFragment(fragment, forward); 278 return fragment; 279 } 280 281 private String getTitle(FormPageInfo formPageInfo, String argument) { 282 return mContext.getString(formPageInfo.getTitleResourceId(), argument); 283 } 284 285 private String getDescription(FormPageInfo formPageInfo, String argument) { 286 int descriptionResourceId = formPageInfo.getDescriptionResourceId(); 287 return (descriptionResourceId != 0) ? mContext.getString(descriptionResourceId, argument) 288 : null; 289 } 290 291 private String getDefaultPrefill(FormPageInfo formPageInfo) { 292 int defaultPrefillResourceId = formPageInfo.getDefaultPrefillResourceId(); 293 return (defaultPrefillResourceId != 0) 294 ? mContext.getString(defaultPrefillResourceId) : null; 295 } 296 } 297