From 4e2894ffb2d6dbdd5cc6f1b0e0e526daaaed4a35 Mon Sep 17 00:00:00 2001 From: codeskyblue Date: Sun, 12 May 2024 08:35:20 +0800 Subject: [PATCH] add requestIgnoreBatteryOptimizations, checkAccessibilityService --- .../stub/AutomatorServiceImpl.java | 10 +-- .../com/github/uiautomator/stub/Stub.java | 35 +++++------ .../com/github/uiautomator/MainActivity.java | 63 ++++++++++++++++++- app/src/main/res/layout/activity_main.xml | 22 +++++++ 4 files changed, 102 insertions(+), 28 deletions(-) diff --git a/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java b/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java index 7fc1265..0b9cec2 100644 --- a/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java +++ b/app/src/androidTest/java/com/github/uiautomator/stub/AutomatorServiceImpl.java @@ -36,6 +36,8 @@ import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; +import android.view.KeyEvent; +import android.view.MotionEvent; import androidx.core.accessibilityservice.AccessibilityServiceInfoCompat; import androidx.test.platform.app.InstrumentationRegistry; @@ -50,9 +52,6 @@ import androidx.test.uiautomator.UiScrollable; import androidx.test.uiautomator.UiSelector; import androidx.test.uiautomator.Until; -import android.view.KeyEvent; -import android.view.MotionEvent; - import com.github.uiautomator.ToastHelper; import com.github.uiautomator.exceptions.NotImplementedException; @@ -309,11 +308,6 @@ public String dumpWindowHierarchy(boolean compressed) { device.setCompressedLayoutHierarchy(compressed); ByteArrayOutputStream os = new ByteArrayOutputStream(); try { - try { - uiAutomation.clearCache(); - } catch (NoSuchMethodError e) { - // ignore - } device.dumpWindowHierarchy(os); return os.toString("UTF-8"); } catch (IOException e) { diff --git a/app/src/androidTest/java/com/github/uiautomator/stub/Stub.java b/app/src/androidTest/java/com/github/uiautomator/stub/Stub.java index 61eab6e..e26f437 100644 --- a/app/src/androidTest/java/com/github/uiautomator/stub/Stub.java +++ b/app/src/androidTest/java/com/github/uiautomator/stub/Stub.java @@ -61,7 +61,6 @@ @RunWith(AndroidJUnit4.class) @SdkSuppress(minSdkVersion = 19) public class Stub { - private final String TAG = "UIAUTOMATOR"; private static final int LAUNCH_TIMEOUT = 5000; // http://www.jsonrpc.org/specification#error_object private static final int CUSTOM_ERROR_CODE = -32001; @@ -71,7 +70,9 @@ public class Stub { @Before public void setUp() throws Exception { - //launchService(); + UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + device.wakeUp(); + JsonRpcServer jrs = new JsonRpcServer(new ObjectMapper(), new AutomatorServiceImpl(), AutomatorService.class); jrs.setShouldLogInvocationErrors(true); jrs.setErrorResolver(new ErrorResolver() { @@ -104,7 +105,7 @@ private void launchPackage(String packageName) { device.pressHome(); } - private void launchService() throws RemoteException { + private void launchTestApp() throws RemoteException { UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); device.wakeUp(); @@ -117,8 +118,6 @@ private void launchService() throws RemoteException { } Log.d("Launch service"); - // Context context = InstrumentationRegistry.getInstrumentation().getContext(); - //startMonitorService(context); } private void startMonitorService(Context context) { @@ -134,26 +133,26 @@ public void tearDown() { //stopMonitorService(context); } - private void stopMonitorService(Context context) { - Intent intent = new Intent("com.github.uiautomator.ACTION_STOP"); - intent.setPackage("com.github.uiautomator"); - context.startService(intent); + private boolean checkAccessibilityQuery() throws InterruptedException { + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + // check if app_process still alive + for (int i = 3; i > 0; i--) { + AccessibilityNodeInfo nodeInfo = instrumentation.getUiAutomation().getRootInActiveWindow(); + if (nodeInfo != null) { + return true; + } + if (i > 1) Thread.sleep(1000); + } + return false; } @Test @LargeTest public void testUIAutomatorStub() throws InterruptedException { + // stop the server with "am force-stop com.github.uiautomator" Log.i("server started"); - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - int nullCount = 0; while (server.isAlive()) { - AccessibilityNodeInfo nodeInfo = instrumentation.getUiAutomation().getRootInActiveWindow(); - if (nodeInfo == null) { - nullCount += 1; - } else { - nullCount = 0; - } - if (nullCount >= 3) { + if (!checkAccessibilityQuery()) { Log.e("uiAutomation.getRootInActiveWindow() always return null, okhttpd server quit"); return; } diff --git a/app/src/main/java/com/github/uiautomator/MainActivity.java b/app/src/main/java/com/github/uiautomator/MainActivity.java index e3296fa..f45f6e6 100644 --- a/app/src/main/java/com/github/uiautomator/MainActivity.java +++ b/app/src/main/java/com/github/uiautomator/MainActivity.java @@ -5,18 +5,24 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.graphics.Color; import android.net.wifi.WifiManager; import android.os.Build; import android.os.Bundle; +import android.os.PowerManager; import android.provider.Settings; -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import android.text.format.Formatter; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + import com.android.permission.FloatWindowManager; import com.github.uiautomator.util.MemoryManager; import com.github.uiautomator.util.Permissons4App; @@ -24,6 +30,7 @@ public class MainActivity extends Activity { private final String TAG = "ATXMainActivity"; + private static final int REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = 1001; private TextView tvInStorage; private TextView textViewIP; @@ -71,6 +78,19 @@ protected void onCreate(Bundle savedInstanceState) { Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_SMS}; Permissons4App.initPermissions(this, permissions); + + TextView viewVersion = (TextView) findViewById(R.id.app_version); + viewVersion.setText("version: " + getAppVersionName()); + } + + private String getAppVersionName() { + try { + PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + return packageInfo.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return null; + } } @Override @@ -84,6 +104,45 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis Permissons4App.handleRequestPermissionsResult(requestCode, permissions, grantResults); } + public void requestIgnoreBatteryOptimizations(View view){ + Intent intent = new Intent(); + intent.setAction(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + intent.setData(android.net.Uri.parse("package:" + getPackageName())); + startActivityForResult(intent, REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) { + // Check if the user granted the request or not + Log.d(TAG, "requestIgnoreBatteryOptimizations resultCode: " + resultCode); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (isIgnoringBatteryOptimizations()) { + // User granted the request + showToast("requestIgnoreBatteryOptimizations success"); + } else { + showToast("requestIgnoreBatteryOptimizations failure"); + // User didn't grant the request + } + } + } + } + + @RequiresApi(api=Build.VERSION_CODES.M) + private boolean isIgnoringBatteryOptimizations() { + boolean isIgnoring = false; + PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); + if (powerManager != null) { + isIgnoring = powerManager.isIgnoringBatteryOptimizations(getPackageName()); + } + return isIgnoring; + } + + private void showToast(String message) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show(); + } + public void showFloatWindow(View view) { boolean floatEnabled = FloatWindowManager.getInstance().checkFloatPermission(MainActivity.this); if (!floatEnabled) { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 696b01b..76371a3 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -104,6 +104,27 @@ android:text="关闭悬浮窗" /> + + +