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