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.os.Bundle;
23 import android.os.Handler;
24 import android.text.InputType;
25 import android.view.KeyEvent;
26 import android.view.LayoutInflater;
27 import android.view.View;
28 import android.view.View.OnClickListener;
29 import android.view.ViewGroup;
30 import android.view.inputmethod.InputMethodManager;
31 import android.widget.CheckBox;
32 import android.widget.EditText;
33 import android.widget.TextView;
34 
35 import com.android.tv.settings.R;
36 
37 /**
38  * Displays a UI for text input in the "wizard" style.
39  * TODO: Merge with EditTextFragment
40  */
41 public class PasswordInputWizardFragment extends Fragment {
42 
43     public interface Listener {
44         /**
45          * Called when text input is complete.
46          *
47          * @param text the text that was input.
48          * @param obfuscate whether the input was obfuscated or not.
49          * @return true if the text is acceptable; false if not.
50          */
onPasswordInputComplete(String text, boolean obfuscate)51         boolean onPasswordInputComplete(String text, boolean obfuscate);
52     }
53 
54     private static final String EXTRA_TITLE = "title";
55     private static final String EXTRA_DESCRIPTION = "description";
56     private static final String EXTRA_PREFILL = "prefill";
57     private static final String EXTRA_OBFUSCATE = "obfuscate";
58 
59     public static final String OPTION_OBFUSCATE = "option_obfuscate";
60 
newInstance( String title, String description, String prefill, boolean obfuscate)61     public static PasswordInputWizardFragment newInstance(
62             String title, String description, String prefill, boolean obfuscate) {
63         PasswordInputWizardFragment fragment = new PasswordInputWizardFragment();
64         Bundle args = new Bundle();
65         args.putString(EXTRA_TITLE, title);
66         args.putString(EXTRA_DESCRIPTION, description);
67         args.putString(EXTRA_PREFILL, prefill);
68         args.putBoolean(EXTRA_OBFUSCATE, obfuscate);
69         fragment.setArguments(args);
70         return fragment;
71     }
72 
73     private Handler mHandler;
74     private EditText mTextInput;
75     private CheckBox mTextObfuscationToggle;
76 
77     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle)78     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) {
79         mHandler = new Handler();
80         final View view = inflater.inflate(R.layout.account_content_area, container, false);
81 
82         final ViewGroup descriptionArea = (ViewGroup) view.findViewById(R.id.description);
83         final View content = inflater.inflate(R.layout.wifi_content, descriptionArea, false);
84         descriptionArea.addView(content);
85 
86         final ViewGroup actionArea = (ViewGroup) view.findViewById(R.id.action);
87         final View action = inflater.inflate(R.layout.password_text_input, actionArea, false);
88         actionArea.addView(action);
89 
90         TextView titleText = (TextView) content.findViewById(R.id.title_text);
91         TextView descriptionText = (TextView) content.findViewById(R.id.description_text);
92         mTextInput = (EditText) action.findViewById(R.id.text_input);
93         mTextObfuscationToggle = (CheckBox) action.findViewById(R.id.text_obfuscation_toggle);
94 
95         final Bundle args = getArguments();
96         final String title = args.getString(EXTRA_TITLE);
97         final String description = args.getString(EXTRA_DESCRIPTION);
98         final String prefill = args.getString(EXTRA_PREFILL);
99         final boolean obfuscate = args.getBoolean(EXTRA_OBFUSCATE);
100 
101         if (title != null) {
102             titleText.setText(title);
103             titleText.setVisibility(View.VISIBLE);
104         } else {
105             titleText.setVisibility(View.GONE);
106         }
107 
108         if (description != null) {
109             descriptionText.setText(description);
110             descriptionText.setVisibility(View.VISIBLE);
111         } else {
112             descriptionText.setVisibility(View.GONE);
113         }
114 
115         mTextObfuscationToggle.setOnClickListener(new OnClickListener() {
116             @Override
117             public void onClick(View v) {
118                 updatePasswordInputObfuscation();
119                 showSoftInput();
120             }
121         });
122         mTextObfuscationToggle.setChecked(obfuscate);
123         updatePasswordInputObfuscation();
124 
125         if (prefill != null) {
126             mTextInput.setText(prefill);
127             mTextInput.setSelection(mTextInput.getText().length(), mTextInput.getText().length());
128         }
129 
130         mTextInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
131             @Override
132             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
133                 if (event == null || event.getAction() == KeyEvent.ACTION_UP) {
134                     Activity a = getActivity();
135                     if (a instanceof Listener) {
136                         boolean inputValid =
137                                 ((Listener) a)
138                                         .onPasswordInputComplete(v.getText().toString(),
139                                                 mTextObfuscationToggle.isChecked());
140                         if (inputValid) {
141                             hideSoftInput();
142                         }
143                     }
144                 }
145                 return true;  // If we don't return true on ACTION_DOWN, we don't get the ACTION_UP.
146             }
147         });
148 
149         return view;
150     }
151 
152     @Override
onResume()153     public void onResume() {
154         super.onResume();
155         if (mTextInput == null) return;
156         showSoftInput();
157     }
158 
showSoftInput()159     private void showSoftInput() {
160         mHandler.post(new Runnable() {
161             @Override
162             public void run() {
163                 Activity a = getActivity();
164                 if (a != null) {
165                     InputMethodManager inputMethodManager =
166                             (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
167                     mTextInput.requestFocus();
168                     mTextInput.setSelection(mTextInput.getText().length());
169                     inputMethodManager.viewClicked(mTextInput);
170                     inputMethodManager.showSoftInput(mTextInput, 0);
171                 }
172             }
173         });
174     }
175 
176     @Override
onPause()177     public void onPause() {
178         if (mTextInput == null) return;
179         hideSoftInput();
180         super.onPause();
181     }
182 
hideSoftInput()183     private void hideSoftInput() {
184         InputMethodManager imm =
185                 (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
186         imm.hideSoftInputFromWindow(mTextInput.getWindowToken(), 0);
187     }
188 
updatePasswordInputObfuscation()189     public void updatePasswordInputObfuscation() {
190         mTextInput.setInputType(InputType.TYPE_CLASS_TEXT |
191                 (mTextObfuscationToggle.isChecked() ?
192                         InputType.TYPE_TEXT_VARIATION_PASSWORD :
193                         InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD));
194     }
195 
196 }
197