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