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