修复 控件相关操作报错的问题

This commit is contained in:
hyb1996
2019-01-23 22:08:55 +08:00
parent 3fecfa9ccb
commit 0d88a12cba
6 changed files with 303 additions and 302 deletions

Binary file not shown.

View File

@@ -0,0 +1,23 @@
package org.autojs.autojs.autojs.api.timing
import com.stardust.autojs.execution.ExecutionConfig
import org.autojs.autojs.timing.TimedTask
import org.autojs.autojs.timing.TimedTaskManager
import org.joda.time.LocalDateTime
import org.joda.time.LocalTime
object TimedTasks {
fun daily(path: String, hour: Int, minute: Int) {
TimedTaskManager.getInstance().addTask(TimedTask.dailyTask(LocalTime(hour, minute), path, ExecutionConfig()))
}
fun disposable(path: String, millis: Long) {
TimedTaskManager.getInstance().addTask(TimedTask.disposableTask(LocalDateTime(millis), path, ExecutionConfig()))
}
fun weekly(path: String, millis: Long) {
//TimedTaskManager.getInstance().addTask(TimedTask.weeklyTask(LocalDateTime(millis), path, ExecutionConfig()))
}
}

View File

@@ -1,281 +0,0 @@
package com.stardust.autojs.core.accessibility;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import androidx.annotation.RequiresApi;
import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo;
import com.stardust.autojs.annotation.ScriptInterface;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
import com.stardust.automator.GlobalActionAutomator;
import com.stardust.automator.UiObject;
import com.stardust.automator.simple_action.ActionFactory;
import com.stardust.automator.simple_action.ActionTarget;
import com.stardust.automator.simple_action.SimpleAction;
import com.stardust.util.DeveloperUtils;
import com.stardust.util.ScreenMetrics;
import java.util.List;
/**
* Created by Stardust on 2017/4/2.
*/
public class SimpleActionAutomator {
private static final String TAG = "SimpleActionAutomator";
private AccessibilityBridge mAccessibilityBridge;
private ScriptRuntime mScriptRuntime;
private GlobalActionAutomator mGlobalActionAutomator;
private ScreenMetrics mScreenMetrics;
public SimpleActionAutomator(AccessibilityBridge accessibilityBridge, ScriptRuntime scriptRuntime) {
mAccessibilityBridge = accessibilityBridge;
mScriptRuntime = scriptRuntime;
}
@ScriptInterface
public ActionTarget text(String text, int i) {
return new ActionTarget.TextActionTarget(text, i);
}
@ScriptInterface
public ActionTarget bounds(int left, int top, int right, int bottom) {
return new ActionTarget.BoundsActionTarget(new Rect(left, top, right, bottom));
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@ScriptInterface
public ActionTarget editable(int i) {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
return new ActionTarget.EditableActionTarget(i);
}
@ScriptInterface
public ActionTarget id(String id) {
return new ActionTarget.IdActionTarget(id);
}
@ScriptInterface
public boolean click(ActionTarget target) {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_CLICK));
}
@ScriptInterface
public boolean longClick(ActionTarget target) {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_LONG_CLICK));
}
@ScriptInterface
public boolean scrollUp(ActionTarget target) {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
}
@ScriptInterface
public boolean scrollDown(ActionTarget target) {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
}
@ScriptInterface
public boolean scrollBackward(int i) {
return performAction(ActionFactory.INSTANCE.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, i));
}
@ScriptInterface
public boolean scrollForward(int i) {
return performAction(ActionFactory.INSTANCE.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, i));
}
@ScriptInterface
public boolean scrollMaxBackward() {
return performAction(ActionFactory.INSTANCE.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD));
}
@ScriptInterface
public boolean scrollMaxForward() {
return performAction(ActionFactory.INSTANCE.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD));
}
@ScriptInterface
public boolean focus(ActionTarget target) {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_FOCUS));
}
@ScriptInterface
public boolean select(ActionTarget target) {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT));
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean setText(ActionTarget target, String text) {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text));
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean appendText(ActionTarget target, String text) {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
return performAction(target.createAction(UiObject.Companion.getACTION_APPEND_TEXT(), text));
}
@ScriptInterface
public boolean back() {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
}
@ScriptInterface
public boolean home() {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean powerDialog() {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG);
}
@ScriptInterface
public boolean notifications() {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS);
}
@ScriptInterface
public boolean quickSettings() {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS);
}
@ScriptInterface
public boolean recents() {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean splitScreen() {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean gesture(long start, long duration, int[]... points) {
prepareForGesture();
return mGlobalActionAutomator.gesture(start, duration, points);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public void gestureAsync(long start, long duration, int[]... points) {
prepareForGesture();
mGlobalActionAutomator.gestureAsync(start, duration, points);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean gestures(Object strokes) {
prepareForGesture();
return mGlobalActionAutomator.gestures((GestureDescription.StrokeDescription[]) strokes);
}
//如果这里用GestureDescription.StrokeDescription[]为参数安卓7.0以下会因为找不到这个类而报错
@RequiresApi(api = Build.VERSION_CODES.N)
public void gesturesAsync(Object strokes) {
prepareForGesture();
mGlobalActionAutomator.gesturesAsync((GestureDescription.StrokeDescription[]) strokes);
}
private void prepareForGesture() {
ScriptRuntime.requiresApi(24);
ensureAccessibilityServiceEnabled();
if (mGlobalActionAutomator != null)
return;
mGlobalActionAutomator = new GlobalActionAutomator(new Handler(mScriptRuntime.loopers.getServantLooper()));
mGlobalActionAutomator.setScreenMetrics(mScreenMetrics);
mGlobalActionAutomator.setService(mAccessibilityBridge.getService());
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean click(int x, int y) {
prepareForGesture();
return mGlobalActionAutomator.click(x, y);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean press(int x, int y, int delay) {
prepareForGesture();
return mGlobalActionAutomator.press(x, y, delay);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean longClick(int x, int y) {
prepareForGesture();
return mGlobalActionAutomator.longClick(x, y);
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
public boolean swipe(int x1, int y1, int x2, int y2, int delay) {
prepareForGesture();
return mGlobalActionAutomator.swipe(x1, y1, x2, y2, delay);
}
private boolean performGlobalAction(final int action) {
ensureAccessibilityServiceEnabled();
AccessibilityService service = mAccessibilityBridge.getService();
if (service == null)
return false;
return service.performGlobalAction(action);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@ScriptInterface
public boolean paste(ActionTarget target) {
ScriptRuntime.requiresApi(18);
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_PASTE));
}
private void ensureAccessibilityServiceEnabled() {
mAccessibilityBridge.ensureServiceEnabled();
}
@SuppressWarnings("unchecked")
private boolean performAction(SimpleAction simpleAction) {
ensureAccessibilityServiceEnabled();
if (AccessibilityConfig.isUnintendedGuardEnabled() && isRunningPackageSelf()) {
Log.d(TAG, "performAction: running package is self. return false");
return false;
}
List<AccessibilityNodeInfo> roots = mAccessibilityBridge.windowRoots();
if (roots.isEmpty())
return false;
Log.v(TAG, "performAction: " + simpleAction + " windowRoots = " + roots);
boolean succeed = true;
for (AccessibilityNodeInfo root : roots) {
succeed &= simpleAction.perform(UiObject.Companion.createRoot(root));
}
return succeed;
}
private boolean isRunningPackageSelf() {
return DeveloperUtils.isSelfPackage(mAccessibilityBridge.getInfoProvider().getLatestPackage());
}
public void setScreenMetrics(ScreenMetrics metrics) {
mScreenMetrics = metrics;
if (mGlobalActionAutomator != null)
mGlobalActionAutomator.setScreenMetrics(metrics);
}
}

View File

@@ -0,0 +1,261 @@
package com.stardust.autojs.core.accessibility
import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.graphics.Rect
import android.os.Build
import android.os.Handler
import android.view.accessibility.AccessibilityNodeInfo
import androidx.annotation.RequiresApi
import com.stardust.autojs.annotation.ScriptInterface
import com.stardust.autojs.runtime.ScriptRuntime
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig
import com.stardust.automator.GlobalActionAutomator
import com.stardust.automator.UiObject
import com.stardust.automator.simple_action.ActionFactory
import com.stardust.automator.simple_action.ActionTarget
import com.stardust.automator.simple_action.SimpleAction
import com.stardust.util.DeveloperUtils
import com.stardust.util.ScreenMetrics
/**
* Created by Stardust on 2017/4/2.
*/
class SimpleActionAutomator(private val mAccessibilityBridge: AccessibilityBridge, private val mScriptRuntime: ScriptRuntime) {
private lateinit var mGlobalActionAutomator: GlobalActionAutomator
private var mScreenMetrics: ScreenMetrics? = null
private val isRunningPackageSelf: Boolean
get() = DeveloperUtils.isSelfPackage(mAccessibilityBridge.infoProvider.latestPackage)
@ScriptInterface
fun text(text: String, i: Int): ActionTarget {
return ActionTarget.TextActionTarget(text, i)
}
@ScriptInterface
fun bounds(left: Int, top: Int, right: Int, bottom: Int): ActionTarget {
return ActionTarget.BoundsActionTarget(Rect(left, top, right, bottom))
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@ScriptInterface
fun editable(i: Int): ActionTarget {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
return ActionTarget.EditableActionTarget(i)
}
@ScriptInterface
fun id(id: String): ActionTarget {
return ActionTarget.IdActionTarget(id)
}
@ScriptInterface
fun click(target: ActionTarget): Boolean {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_CLICK))
}
@ScriptInterface
fun longClick(target: ActionTarget): Boolean {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_LONG_CLICK))
}
@ScriptInterface
fun scrollUp(target: ActionTarget): Boolean {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD))
}
@ScriptInterface
fun scrollDown(target: ActionTarget): Boolean {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD))
}
@ScriptInterface
fun scrollBackward(i: Int): Boolean {
return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD, i))
}
@ScriptInterface
fun scrollForward(i: Int): Boolean {
return performAction(ActionFactory.createScrollAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD, i))
}
@ScriptInterface
fun scrollMaxBackward(): Boolean {
return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD))
}
@ScriptInterface
fun scrollMaxForward(): Boolean {
return performAction(ActionFactory.createScrollMaxAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD))
}
@ScriptInterface
fun focus(target: ActionTarget): Boolean {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_FOCUS))
}
@ScriptInterface
fun select(target: ActionTarget): Boolean {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT))
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
fun setText(target: ActionTarget, text: String): Boolean {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text))
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
fun appendText(target: ActionTarget, text: String): Boolean {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
return performAction(target.createAction(UiObject.ACTION_APPEND_TEXT, text))
}
@ScriptInterface
fun back(): Boolean {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
}
@ScriptInterface
fun home(): Boolean {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME)
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
fun powerDialog(): Boolean {
ScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP)
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_POWER_DIALOG)
}
@ScriptInterface
fun notifications(): Boolean {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS)
}
@ScriptInterface
fun quickSettings(): Boolean {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS)
}
@ScriptInterface
fun recents(): Boolean {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS)
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
fun splitScreen(): Boolean {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN)
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
fun gesture(start: Long, duration: Long, vararg points: IntArray): Boolean {
prepareForGesture()
return mGlobalActionAutomator.gesture(start, duration, *points)
}
@RequiresApi(api = Build.VERSION_CODES.N)
fun gestureAsync(start: Long, duration: Long, vararg points: IntArray) {
prepareForGesture()
mGlobalActionAutomator.gestureAsync(start, duration, *points)
}
@RequiresApi(api = Build.VERSION_CODES.N)
fun gestures(strokes: Any): Boolean {
prepareForGesture()
@Suppress("UNCHECKED_CAST")
return mGlobalActionAutomator.gestures(*strokes as Array<GestureDescription.StrokeDescription>)
}
//如果这里用GestureDescription.StrokeDescription[]为参数安卓7.0以下会因为找不到这个类而报错
@RequiresApi(api = Build.VERSION_CODES.N)
fun gesturesAsync(strokes: Any) {
prepareForGesture()
@Suppress("UNCHECKED_CAST")
mGlobalActionAutomator.gesturesAsync(*strokes as Array<GestureDescription.StrokeDescription>)
}
private fun prepareForGesture() {
ScriptRuntime.requiresApi(24)
if (!::mGlobalActionAutomator.isInitialized) {
mGlobalActionAutomator = GlobalActionAutomator(Handler(mScriptRuntime.loopers.servantLooper)) {
ensureAccessibilityServiceEnabled()
return@GlobalActionAutomator mAccessibilityBridge.service!!
}
}
mGlobalActionAutomator.setScreenMetrics(mScreenMetrics)
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
fun click(x: Int, y: Int): Boolean {
prepareForGesture()
return mGlobalActionAutomator.click(x, y)
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
fun press(x: Int, y: Int, delay: Int): Boolean {
prepareForGesture()
return mGlobalActionAutomator.press(x, y, delay)
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
fun longClick(x: Int, y: Int): Boolean {
prepareForGesture()
return mGlobalActionAutomator.longClick(x, y)
}
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.N)
fun swipe(x1: Int, y1: Int, x2: Int, y2: Int, delay: Int): Boolean {
prepareForGesture()
return mGlobalActionAutomator.swipe(x1, y1, x2, y2, delay.toLong())
}
private fun performGlobalAction(action: Int): Boolean {
ensureAccessibilityServiceEnabled()
val service = mAccessibilityBridge.service ?: return false
return service.performGlobalAction(action)
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@ScriptInterface
fun paste(target: ActionTarget): Boolean {
ScriptRuntime.requiresApi(18)
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_PASTE))
}
private fun ensureAccessibilityServiceEnabled() {
mAccessibilityBridge.ensureServiceEnabled()
}
private fun performAction(simpleAction: SimpleAction): Boolean {
ensureAccessibilityServiceEnabled()
if (AccessibilityConfig.isUnintendedGuardEnabled() && isRunningPackageSelf) {
return false
}
val roots = mAccessibilityBridge.windowRoots().filter { it != null }
if (roots.isEmpty())
return false
var succeed = true
for (root in roots) {
succeed = succeed and simpleAction.perform(UiObject.createRoot(root))
}
return succeed
}
fun setScreenMetrics(metrics: ScreenMetrics) {
mScreenMetrics = metrics
}
}

View File

@@ -105,6 +105,9 @@ public class UiSelector extends UiGlobalSelector {
}
List<UiObject> result = new ArrayList<>();
for (AccessibilityNodeInfo root : roots) {
if (root == null) {
continue;
}
if (root.getPackageName() != null && mAccessibilityBridge.getConfig().whiteListContains(root.getPackageName().toString())) {
Log.d(TAG, "package in white list, return null");
return UiObjectCollection.Companion.getEMPTY();

View File

@@ -17,16 +17,14 @@ import com.stardust.util.ScreenMetrics
* Created by Stardust on 2017/5/16.
*/
class GlobalActionAutomator(private val mHandler: Handler?) {
class GlobalActionAutomator(private val mHandler: Handler?, private val serviceProvider: () -> AccessibilityService) {
private val service: AccessibilityService
get() = serviceProvider()
private var mService: AccessibilityService? = null
private var mScreenMetrics: ScreenMetrics? = null
fun setService(service: AccessibilityService) {
mService = service
}
fun setScreenMetrics(screenMetrics: ScreenMetrics) {
fun setScreenMetrics(screenMetrics: ScreenMetrics?) {
mScreenMetrics = screenMetrics
}
@@ -44,7 +42,7 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
}
private fun performGlobalAction(globalAction: Int): Boolean {
return if (mService == null) false else mService!!.performGlobalAction(globalAction)
return service.performGlobalAction(globalAction)
}
fun notifications(): Boolean {
@@ -88,23 +86,22 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
@RequiresApi(api = Build.VERSION_CODES.N)
fun gestures(vararg strokes: GestureDescription.StrokeDescription): Boolean {
if (mService == null)
return false
val builder = GestureDescription.Builder()
for (stroke in strokes) {
builder.addStroke(stroke)
}
return if (mHandler == null) {
val handler = mHandler
return if (handler == null) {
gesturesWithoutHandler(builder.build())
} else {
gesturesWithHandler(builder.build())
gesturesWithHandler(handler, builder.build())
}
}
@RequiresApi(api = Build.VERSION_CODES.N)
private fun gesturesWithHandler(description: GestureDescription): Boolean {
private fun gesturesWithHandler(handler: Handler, description: GestureDescription): Boolean {
val result = VolatileDispose<Boolean>()
mService!!.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
service.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
override fun onCompleted(gestureDescription: GestureDescription) {
result.setAndNotify(true)
}
@@ -112,7 +109,7 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
override fun onCancelled(gestureDescription: GestureDescription) {
result.setAndNotify(false)
}
}, mHandler)
}, handler)
return result.blockedGet()
}
@@ -121,7 +118,7 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
prepareLooperIfNeeded()
val result = VolatileBox(false)
val handler = Handler(Looper.myLooper())
mService!!.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
service.dispatchGesture(description, object : AccessibilityService.GestureResultCallback() {
override fun onCompleted(gestureDescription: GestureDescription) {
result.set(true)
quitLoop()
@@ -138,13 +135,11 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
@RequiresApi(api = Build.VERSION_CODES.N)
fun gesturesAsync(vararg strokes: GestureDescription.StrokeDescription) {
if (mService == null)
return
val builder = GestureDescription.Builder()
for (stroke in strokes) {
builder.addStroke(stroke)
}
mService!!.dispatchGesture(builder.build(), null, null)
service.dispatchGesture(builder.build(), null, null)
}
private fun quitLoop() {
@@ -174,11 +169,11 @@ class GlobalActionAutomator(private val mHandler: Handler?) {
}
private fun scaleX(x: Int): Int {
return if (mScreenMetrics == null) x else mScreenMetrics!!.scaleX(x)
return mScreenMetrics?.scaleX(x) ?: x
}
private fun scaleY(y: Int): Int {
return if (mScreenMetrics == null) y else mScreenMetrics!!.scaleY(y)
return mScreenMetrics?.scaleX(y) ?: y
}
@RequiresApi(api = Build.VERSION_CODES.N)