1 /* 2 * Copyright (C) 2013 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 import static android.provider.Settings.System.TEXT_AUTO_CAPS; 20 21 import android.app.AppOpsManager; 22 import android.app.Instrumentation; 23 import android.content.ContentResolver; 24 import android.content.Context; 25 import android.provider.Settings; 26 import android.text.cts.R; 27 import android.text.method.KeyListener; 28 import android.util.Log; 29 import android.view.KeyEvent; 30 import android.view.View; 31 import android.widget.EditText; 32 33 import androidx.test.InstrumentationRegistry; 34 import androidx.test.rule.ActivityTestRule; 35 36 import com.android.compatibility.common.util.CtsKeyEventUtil; 37 import com.android.compatibility.common.util.PollingCheck; 38 import com.android.compatibility.common.util.SystemUtil; 39 40 import org.junit.Before; 41 import org.junit.Rule; 42 43 import java.io.IOException; 44 45 /** 46 * Base class for various KeyListener tests. 47 */ 48 public abstract class KeyListenerTestCase { 49 private static final String TAG = "KeyListenerTestCase"; 50 51 protected KeyListenerCtsActivity mActivity; 52 protected Instrumentation mInstrumentation; 53 private Context mContext; 54 private CtsKeyEventUtil mCtsKeyEventUtil; 55 protected EditText mTextView; 56 private int mAutoCapSetting; 57 58 @Rule 59 public ActivityTestRule<KeyListenerCtsActivity> mActivityRule = 60 new ActivityTestRule<>(KeyListenerCtsActivity.class); 61 62 @Before setup()63 public void setup() throws IOException { 64 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 65 mContext = mInstrumentation.getTargetContext(); 66 mCtsKeyEventUtil = new CtsKeyEventUtil(mContext); 67 mActivity = mActivityRule.getActivity(); 68 mTextView = mActivity.findViewById(R.id.keylistener_textview); 69 70 PollingCheck.waitFor(10000, mActivity::hasWindowFocus); 71 } 72 enableAutoCapSettings()73 protected void enableAutoCapSettings() throws IOException { 74 grantWriteSettingsPermission(); 75 final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); 76 final Context context = instrumentation.getContext(); 77 instrumentation.runOnMainSync(() -> { 78 final ContentResolver resolver = context.getContentResolver(); 79 mAutoCapSetting = Settings.System.getInt(resolver, TEXT_AUTO_CAPS, 1); 80 try { 81 Settings.System.putInt(resolver, TEXT_AUTO_CAPS, 1); 82 } catch (SecurityException e) { 83 Log.e(TAG, "Cannot set TEXT_AUTO_CAPS to 1", e); 84 // ignore 85 } 86 }); 87 instrumentation.waitForIdleSync(); 88 } 89 resetAutoCapSettings()90 protected void resetAutoCapSettings() throws IOException { 91 grantWriteSettingsPermission(); 92 final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); 93 final Context context = instrumentation.getContext(); 94 instrumentation.runOnMainSync(() -> { 95 final ContentResolver resolver = context.getContentResolver(); 96 try { 97 Settings.System.putInt(resolver, TEXT_AUTO_CAPS, mAutoCapSetting); 98 } catch (SecurityException e) { 99 Log.e(TAG, "Cannot set TEXT_AUTO_CAPS to previous value", e); 100 // ignore 101 } 102 }); 103 instrumentation.waitForIdleSync(); 104 } 105 106 /** 107 * Synchronously sets mTextView's key listener on the UI thread. 108 */ setKeyListenerSync(final KeyListener keyListener)109 protected void setKeyListenerSync(final KeyListener keyListener) { 110 mInstrumentation.runOnMainSync(() -> mTextView.setKeyListener(keyListener)); 111 mInstrumentation.waitForIdleSync(); 112 } 113 getKey(int keycode, int metaState)114 protected static KeyEvent getKey(int keycode, int metaState) { 115 long currentTime = System.currentTimeMillis(); 116 return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode, 117 0 /* repeat */, metaState); 118 } 119 grantWriteSettingsPermission()120 private void grantWriteSettingsPermission() throws IOException { 121 SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), 122 "appops set --user " + mContext.getUser().getIdentifier() 123 + " " + mActivity.getPackageName() 124 + " " + AppOpsManager.OPSTR_WRITE_SETTINGS + " allow"); 125 } 126 sendKeys(View targetView, int...keys)127 protected final void sendKeys(View targetView, int...keys) { 128 mCtsKeyEventUtil.sendKeys(mInstrumentation, targetView, keys); 129 } 130 sendKeys(View targetView, String keysSequence)131 protected final void sendKeys(View targetView, String keysSequence) { 132 mCtsKeyEventUtil.sendKeys(mInstrumentation, targetView, keysSequence); 133 } 134 sendKey(View targetView, KeyEvent event)135 protected final void sendKey(View targetView, KeyEvent event) { 136 mCtsKeyEventUtil.sendKey(mInstrumentation, targetView, event); 137 } 138 sendKeyDownUp(View targetView, int key)139 protected final void sendKeyDownUp(View targetView, int key) { 140 mCtsKeyEventUtil.sendKeyDownUp(mInstrumentation, targetView, key); 141 } 142 sendKeyWhileHoldingModifier(View targetView, int keyCodeToSend, int modifierKeyCodeToHold)143 protected void sendKeyWhileHoldingModifier(View targetView, int keyCodeToSend, 144 int modifierKeyCodeToHold) { 145 mCtsKeyEventUtil.sendKeyWhileHoldingModifier(mInstrumentation, targetView, keyCodeToSend, 146 modifierKeyCodeToHold); 147 } 148 sendString(View targetView, String text)149 protected final void sendString(View targetView, String text) { 150 mCtsKeyEventUtil.sendString(mInstrumentation, targetView, text); 151 } 152 } 153