• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 android.text.method.cts;
18 
19 
20 import android.cts.util.PollingCheck;
21 import android.graphics.Rect;
22 import android.provider.Settings.SettingNotFoundException;
23 import android.provider.Settings.System;
24 import android.test.ActivityInstrumentationTestCase2;
25 import android.text.Editable;
26 import android.text.method.PasswordTransformationMethod;
27 import android.view.KeyCharacterMap;
28 import android.view.View;
29 import android.widget.Button;
30 import android.widget.EditText;
31 import android.widget.LinearLayout;
32 import android.widget.LinearLayout.LayoutParams;
33 
34 /**
35  * Test {@link PasswordTransformationMethod}.
36  */
37 public class PasswordTransformationMethodTest extends
38         ActivityInstrumentationTestCase2<StubActivity> {
39     private static final int EDIT_TXT_ID = 1;
40 
41     /** original text */
42     private static final String TEST_CONTENT = "test content";
43 
44     /** text after transformation: ************(12 dots) */
45     private static final String TEST_CONTENT_TRANSFORMED =
46         "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
47 
48     private int mPasswordPrefBackUp;
49 
50     private boolean isPasswordPrefSaved;
51 
52     private StubActivity mActicity;
53 
54     private MockPasswordTransformationMethod mMethod;
55 
56     private EditText mEditText;
57 
58     private CharSequence mTransformedText;
59 
PasswordTransformationMethodTest()60     public PasswordTransformationMethodTest() {
61         super("com.android.cts.stub", StubActivity.class);
62     }
63 
64     @Override
setUp()65     protected void setUp() throws Exception {
66         super.setUp();
67         mActicity = getActivity();
68         mMethod = new MockPasswordTransformationMethod();
69         try {
70             runTestOnUiThread(new Runnable() {
71                 public void run() {
72                     EditText editText = new EditText(mActicity);
73                     editText.setId(EDIT_TXT_ID);
74                     editText.setTransformationMethod(mMethod);
75                     Button button = new Button(mActicity);
76                     LinearLayout layout = new LinearLayout(mActicity);
77                     layout.setOrientation(LinearLayout.VERTICAL);
78                     layout.addView(editText, new LayoutParams(LayoutParams.MATCH_PARENT,
79                             LayoutParams.WRAP_CONTENT));
80                     layout.addView(button, new LayoutParams(LayoutParams.MATCH_PARENT,
81                             LayoutParams.WRAP_CONTENT));
82                     mActicity.setContentView(layout);
83                     editText.requestFocus();
84                 }
85             });
86         } catch (Throwable e) {
87             fail("Exception thrown is UI thread:" + e.getMessage());
88         }
89         getInstrumentation().waitForIdleSync();
90 
91         mEditText = (EditText) getActivity().findViewById(EDIT_TXT_ID);
92         assertTrue(mEditText.isFocused());
93 
94         savePasswordPref();
95         switchShowPassword(true);
96     }
97 
98     @Override
tearDown()99     protected void tearDown() throws Exception {
100         resumePasswordPref();
101         super.tearDown();
102     }
103 
testConstructor()104     public void testConstructor() {
105         new PasswordTransformationMethod();
106     }
107 
testTextChangedCallBacks()108     public void testTextChangedCallBacks() throws Throwable {
109         runTestOnUiThread(new Runnable() {
110             public void run() {
111                 mTransformedText = mMethod.getTransformation(mEditText.getText(), mEditText);
112             }
113         });
114 
115         mMethod.reset();
116         // 12-key support
117         KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
118         if (keymap.getKeyboardType() == KeyCharacterMap.NUMERIC) {
119             // "HELLO" in case of 12-key(NUMERIC) keyboard
120             sendKeys("6*4 6*3 7*5 DPAD_RIGHT 7*5 7*6 DPAD_RIGHT");
121         }
122         else {
123             sendKeys("H E 2*L O");
124         }
125         assertTrue(mMethod.hasCalledBeforeTextChanged());
126         assertTrue(mMethod.hasCalledOnTextChanged());
127         assertTrue(mMethod.hasCalledAfterTextChanged());
128 
129         mMethod.reset();
130 
131         runTestOnUiThread(new Runnable() {
132             public void run() {
133                 mEditText.append(" ");
134             }
135         });
136 
137         // the appended string will not get transformed immediately
138         // "***** "
139         assertEquals("\u2022\u2022\u2022\u2022\u2022 ", mTransformedText.toString());
140         assertTrue(mMethod.hasCalledBeforeTextChanged());
141         assertTrue(mMethod.hasCalledOnTextChanged());
142         assertTrue(mMethod.hasCalledAfterTextChanged());
143 
144         // it will get transformed after a while
145         new PollingCheck() {
146             @Override
147             protected boolean check() {
148                 // "******"
149                 return mTransformedText.toString()
150                         .equals("\u2022\u2022\u2022\u2022\u2022\u2022");
151             }
152         }.run();
153     }
154 
testGetTransformation()155     public void testGetTransformation() {
156         PasswordTransformationMethod method = new PasswordTransformationMethod();
157 
158         assertEquals(TEST_CONTENT_TRANSFORMED,
159                 method.getTransformation(TEST_CONTENT, null).toString());
160 
161         CharSequence transformed = method.getTransformation(null, mEditText);
162         assertNotNull(transformed);
163         try {
164             transformed.toString();
165             fail("Should throw NullPointerException if the source is null.");
166         } catch (NullPointerException e) {
167             // expected
168         }
169     }
170 
testGetInstance()171     public void testGetInstance() {
172         PasswordTransformationMethod method0 = PasswordTransformationMethod.getInstance();
173         assertNotNull(method0);
174 
175         PasswordTransformationMethod method1 = PasswordTransformationMethod.getInstance();
176         assertNotNull(method1);
177         assertSame(method0, method1);
178     }
179 
testOnFocusChanged()180     public void testOnFocusChanged() {
181         // lose focus
182         mMethod.reset();
183         assertTrue(mEditText.isFocused());
184         sendKeys("DPAD_DOWN");
185         assertFalse(mEditText.isFocused());
186         assertTrue(mMethod.hasCalledOnFocusChanged());
187 
188         // gain focus
189         mMethod.reset();
190         assertFalse(mEditText.isFocused());
191         sendKeys("DPAD_UP");
192         assertTrue(mEditText.isFocused());
193         assertTrue(mMethod.hasCalledOnFocusChanged());
194     }
195 
savePasswordPref()196     private void savePasswordPref() {
197         try {
198             mPasswordPrefBackUp = System.getInt(mActicity.getContentResolver(),
199                     System.TEXT_SHOW_PASSWORD);
200             isPasswordPrefSaved = true;
201         } catch (SettingNotFoundException e) {
202             isPasswordPrefSaved = false;
203         }
204     }
205 
resumePasswordPref()206     private void resumePasswordPref() {
207         if (isPasswordPrefSaved) {
208             System.putInt(mActicity.getContentResolver(), System.TEXT_SHOW_PASSWORD,
209                     mPasswordPrefBackUp);
210         }
211     }
212 
switchShowPassword(boolean on)213     private void switchShowPassword(boolean on) {
214         System.putInt(mActicity.getContentResolver(), System.TEXT_SHOW_PASSWORD,
215                 on ? 1 : 0);
216     }
217 
218     private static class MockPasswordTransformationMethod extends PasswordTransformationMethod {
219         private boolean mHasCalledBeforeTextChanged;
220 
221         private boolean mHasCalledOnTextChanged;
222 
223         private boolean mHasCalledAfterTextChanged;
224 
225         private boolean mHasCalledOnFocusChanged;
226 
227         @Override
afterTextChanged(Editable s)228         public void afterTextChanged(Editable s) {
229             super.afterTextChanged(s);
230             mHasCalledAfterTextChanged = true;
231         }
232 
233         @Override
beforeTextChanged(CharSequence s, int start, int count, int after)234         public void beforeTextChanged(CharSequence s, int start, int count, int after) {
235             super.beforeTextChanged(s, start, count, after);
236             mHasCalledBeforeTextChanged = true;
237         }
238 
239         @Override
onFocusChanged(View view, CharSequence sourceText, boolean focused, int direction, Rect previouslyFocusedRect)240         public void onFocusChanged(View view, CharSequence sourceText, boolean focused,
241                 int direction, Rect previouslyFocusedRect) {
242             super.onFocusChanged(view, sourceText, focused, direction, previouslyFocusedRect);
243             mHasCalledOnFocusChanged = true;
244         }
245 
246         @Override
onTextChanged(CharSequence s, int start, int before, int count)247         public void onTextChanged(CharSequence s, int start, int before, int count) {
248             super.onTextChanged(s, start, before, count);
249             mHasCalledOnTextChanged = true;
250         }
251 
hasCalledBeforeTextChanged()252         public boolean hasCalledBeforeTextChanged() {
253             return mHasCalledBeforeTextChanged;
254         }
255 
hasCalledOnTextChanged()256         public boolean hasCalledOnTextChanged() {
257             return mHasCalledOnTextChanged;
258         }
259 
hasCalledAfterTextChanged()260         public boolean hasCalledAfterTextChanged() {
261             return mHasCalledAfterTextChanged;
262         }
263 
hasCalledOnFocusChanged()264         public boolean hasCalledOnFocusChanged() {
265             return mHasCalledOnFocusChanged;
266         }
267 
reset()268         public void reset() {
269             mHasCalledBeforeTextChanged = false;
270             mHasCalledOnTextChanged = false;
271             mHasCalledAfterTextChanged = false;
272             mHasCalledOnFocusChanged = false;
273         }
274     }
275 }
276