diff options
author | Henrique Silva <jhenrique09.mcz@hotmail.com> | 2019-05-08 11:52:38 -0300 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2021-09-27 21:17:05 +0800 |
commit | d662f25af97a2ad03445cd6cca6b1df2e4de627b (patch) | |
tree | b2a1b5088dfb541a66f8874ca90edcc06315a9b8 | |
parent | 8abff700cb9c045874f3c336e11b2e624ae53886 (diff) |
[ArrowOS][11.0] base: Add three-fingers-swipe to screenshot [1/2]
Squashed commit of the following:
Author: Henrique Silva <jhenrique09.mcz@hotmail.com>
Date: Wed May 8 11:52:38 2019 -0300
base: SwipeToScreenshot: Import MIUI implementation
Reverse engineered from Xiaomi/beryllium/beryllium:9/PKQ1.180729.001/9.2.25:user/release-keys
Change-Id: I1d5938457b7cc4c5ef1fec235d27d8a40526961a
Author: Henrique Silva <jhenrique09.mcz@hotmail.com>
Date: Tue May 7 13:29:38 2019 -0300
base: Improvements for swipe to screenshot
* Cancel touch events when tap with three fingers
* Dyrex2004: Fix typos (Screnshot -> Screenshot)
Change-Id: I90c5d73f37f277052c4e4802fd3006f607313068
Author: ghbhaha <ghbhaha@gmail.com>
Date: Sun Aug 9 01:23:33 2015 +0800
base: Add three-fingers-swipe to screenshot [1/2]
The feature is ported from Oppo ColorOS.
With the options on, users can swipe down
on the screen to have a screenshot.
Original smali port by: wuxianlin
Change-Id: I87ed333f81e1259758ea899bf019061d8ab85fd0
Change-Id: I78c67e5470a5024034be92736a36bc43b3ca4487
6 files changed, 243 insertions, 0 deletions
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 2fe7eea3b51f..f2bf96b8cddb 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -693,4 +693,9 @@ interface IActivityManager { * @param enable set it to true to enable the app freezer, false to disable it. */ boolean enableAppFreezer(in boolean enable); + + /** + * Should disable touch if three fingers to screen shot is active? + */ + boolean isSwipeToScreenshotGestureActive(); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fe61bc37d224..c7b2fa3273af 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4809,6 +4809,12 @@ public final class Settings { */ /** + * Three Finger Gesture from Oppo + * @hide + */ + public static final String THREE_FINGER_GESTURE = "three_finger_gesture"; + + /** * Keys we no longer back up under the current schema, but want to continue to * process when restoring historical backup datasets. * diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 18e9ef0e4d05..35a56a08ab39 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6017,6 +6017,11 @@ public final class ViewRootImpl implements ViewParent, private int processPointerEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; + if (event.getPointerCount() == 3 && isSwipeToScreenshotGestureActive()) { + event.setAction(MotionEvent.ACTION_CANCEL); + Log.d("teste", "canceling motionEvent because of threeGesture detecting"); + } + mAttachInfo.mUnbufferedDispatchRequested = false; mAttachInfo.mHandlingPointerEvent = true; boolean handled = mView.dispatchPointerEvent(event); @@ -9864,4 +9869,13 @@ public final class ViewRootImpl implements ViewParent, boolean isDrawingToBLASTTransaction() { return mNextReportConsumeBLAST; } + + private boolean isSwipeToScreenshotGestureActive() { + try { + return ActivityManager.getService().isSwipeToScreenshotGestureActive(); + } catch (RemoteException e) { + Log.e("teste", "isSwipeToScreenshotGestureActive exception", e); + return false; + } + } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0ae9cc279e68..3a7b2a84d176 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1680,6 +1680,10 @@ public class ActivityManagerService extends IActivityManager.Stub private ParcelFileDescriptor[] mLifeMonitorFds; static final HostingRecord sNullHostingRecord = new HostingRecord(null); + + final SwipeToScreenshotObserver mSwipeToScreenshotObserver; + private boolean mIsSwipeToScreenshotEnabled; + /** * Used to notify activity lifecycle events. */ @@ -2558,6 +2562,7 @@ public class ActivityManagerService extends IActivityManager.Stub mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class); mInternal = new LocalService(); mPendingStartActivityUids = new PendingStartActivityUids(mContext); + mSwipeToScreenshotObserver = null; } // Note: This method is invoked on the main thread but may need to attach various @@ -2716,6 +2721,7 @@ public class ActivityManagerService extends IActivityManager.Stub mInternal = new LocalService(); mPendingStartActivityUids = new PendingStartActivityUids(mContext); + mSwipeToScreenshotObserver = new SwipeToScreenshotObserver(mHandler, mContext); } public void setSystemServiceManager(SystemServiceManager mgr) { @@ -9517,6 +9523,7 @@ public class ActivityManagerService extends IActivityManager.Stub mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs; mPssDeferralTime = pssDeferralMs; } + mSwipeToScreenshotObserver.registerObserver(); } /** @@ -20420,4 +20427,37 @@ public class ActivityManagerService extends IActivityManager.Stub throw new SecurityException("Caller uid " + callerUid + " cannot set freezer state "); } } + + private class SwipeToScreenshotObserver extends ContentObserver { + + private final Context mContext; + + public SwipeToScreenshotObserver(Handler handler, Context context) { + super(handler); + mContext = context; + } + + public void registerObserver() { + mContext.getContentResolver().registerContentObserver( + Settings.System.getUriFor(Settings.System.THREE_FINGER_GESTURE), + false, this, UserHandle.USER_ALL); + update(); + } + + private void update() { + mIsSwipeToScreenshotEnabled = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.THREE_FINGER_GESTURE, 0, UserHandle.USER_CURRENT) == 1; + } + + public void onChange(boolean selfChange) { + update(); + } + } + + @Override + public boolean isSwipeToScreenshotGestureActive() { + synchronized (this) { + return mIsSwipeToScreenshotEnabled && SystemProperties.getBoolean("sys.android.screenshot", false); + } + } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 4591754cec1c..3b96ba5d9eba 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -208,6 +208,7 @@ import com.android.internal.policy.KeyInterceptionInfo; import com.android.internal.policy.PhoneWindow; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.ScreenshotHelper; import com.android.server.ExtconStateObserver; import com.android.server.ExtconUEventObserver; import com.android.server.GestureLauncherService; @@ -653,6 +654,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mHavePendingMediaKeyRepeatWithWakeLock; private int mCurrentUserId; + private boolean haveEnableGesture = false; // Maps global key codes to the components that will handle them. private GlobalKeyManager mGlobalKeyManager; @@ -720,6 +722,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { private LineageHardwareManager mLineageHardware; + private SwipeToScreenshotListener mSwipeToScreenshot; + private class PolicyHandler extends Handler { @Override public void handleMessage(Message msg) { @@ -932,6 +936,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { resolver.registerContentObserver(LineageSettings.System.getUriFor( LineageSettings.System.VOLUME_ANSWER_CALL), false, this, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.THREE_FINGER_GESTURE), false, this, + UserHandle.USER_ALL); updateSettings(); } @@ -2048,6 +2055,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } mHandler = new PolicyHandler(); + mSwipeToScreenshot = new SwipeToScreenshotListener(context, new SwipeToScreenshotListener.Callbacks() { + @Override + public void onSwipeThreeFinger() { + mHandler.post(mScreenshotRunnable); + } + }); mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler); mSettingsObserver = new SettingsObserver(mHandler); @@ -2367,6 +2380,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void enableSwipeThreeFingerGesture(boolean enable){ + if (enable) { + if (haveEnableGesture) return; + haveEnableGesture = true; + mWindowManagerFuncs.registerPointerEventListener(mSwipeToScreenshot, DEFAULT_DISPLAY); + } else { + if (!haveEnableGesture) return; + haveEnableGesture = false; + mWindowManagerFuncs.unregisterPointerEventListener(mSwipeToScreenshot, DEFAULT_DISPLAY); + } + } + public void updateSettings() { ContentResolver resolver = mContext.getContentResolver(); boolean updateRotation = false; @@ -2441,6 +2466,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { LineageSettings.System.CAMERA_LAUNCH, 0, UserHandle.USER_CURRENT) == 1; + // Three Finger Gesture + boolean threeFingerGesture = Settings.System.getIntForUser(resolver, + Settings.System.THREE_FINGER_GESTURE, 0, UserHandle.USER_CURRENT) == 1; + enableSwipeThreeFingerGesture(threeFingerGesture); + // Configure wake gesture. boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver, Settings.Secure.WAKE_GESTURE_ENABLED, 0, diff --git a/services/core/java/com/android/server/policy/SwipeToScreenshotListener.java b/services/core/java/com/android/server/policy/SwipeToScreenshotListener.java new file mode 100644 index 000000000000..88a465b6c382 --- /dev/null +++ b/services/core/java/com/android/server/policy/SwipeToScreenshotListener.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2019 The PixelExperience Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.policy; + +import android.content.Context; +import android.os.SystemProperties; +import android.provider.Settings; +import android.util.Log; +import android.util.DisplayMetrics; +import android.view.MotionEvent; +import android.view.WindowManagerPolicyConstants.PointerEventListener; + +public class SwipeToScreenshotListener implements PointerEventListener { + private static final String TAG = "SwipeToScreenshotListener"; + private static final int THREE_GESTURE_STATE_NONE = 0; + private static final int THREE_GESTURE_STATE_DETECTING = 1; + private static final int THREE_GESTURE_STATE_DETECTED_FALSE = 2; + private static final int THREE_GESTURE_STATE_DETECTED_TRUE = 3; + private static final int THREE_GESTURE_STATE_NO_DETECT = 4; + private boolean mBootCompleted; + private Context mContext; + private boolean mDeviceProvisioned = false; + private float[] mInitMotionY; + private int[] mPointerIds; + private int mThreeGestureState = THREE_GESTURE_STATE_NONE; + private int mThreeGestureThreshold; + private int mThreshold; + private final Callbacks mCallbacks; + DisplayMetrics mDisplayMetrics; + + public SwipeToScreenshotListener(Context context, Callbacks callbacks) { + mPointerIds = new int[3]; + mInitMotionY = new float[3]; + mContext = context; + mCallbacks = callbacks; + mDisplayMetrics = mContext.getResources().getDisplayMetrics(); + mThreshold = (int) (50.0f * mDisplayMetrics.density); + mThreeGestureThreshold = mThreshold * 3; + } + + @Override + public void onPointerEvent(MotionEvent event) { + if (!mBootCompleted) { + mBootCompleted = SystemProperties.getBoolean("sys.boot_completed", false); + return; + } + if (!mDeviceProvisioned) { + mDeviceProvisioned = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.DEVICE_PROVISIONED, 0) != 0; + return; + } + if (event.getAction() == 0) { + changeThreeGestureState(THREE_GESTURE_STATE_NONE); + } else if (mThreeGestureState == THREE_GESTURE_STATE_NONE && event.getPointerCount() == 3) { + if (checkIsStartThreeGesture(event)) { + changeThreeGestureState(THREE_GESTURE_STATE_DETECTING); + for (int i = 0; i < 3; i++) { + mPointerIds[i] = event.getPointerId(i); + mInitMotionY[i] = event.getY(i); + } + } else { + changeThreeGestureState(THREE_GESTURE_STATE_NO_DETECT); + } + } + if (mThreeGestureState == THREE_GESTURE_STATE_DETECTING) { + if (event.getPointerCount() != 3) { + changeThreeGestureState(THREE_GESTURE_STATE_DETECTED_FALSE); + return; + } + if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { + float distance = 0.0f; + int i = 0; + while (i < 3) { + int index = event.findPointerIndex(mPointerIds[i]); + if (index < 0 || index >= 3) { + changeThreeGestureState(THREE_GESTURE_STATE_DETECTED_FALSE); + return; + } else { + distance += event.getY(index) - mInitMotionY[i]; + i++; + } + } + if (distance >= ((float) mThreeGestureThreshold)) { + changeThreeGestureState(THREE_GESTURE_STATE_DETECTED_TRUE); + mCallbacks.onSwipeThreeFinger(); + } + } + } + } + + private void changeThreeGestureState(int state) { + if (mThreeGestureState != state){ + mThreeGestureState = state; + boolean shouldEnableProp = mThreeGestureState == THREE_GESTURE_STATE_DETECTED_TRUE || + mThreeGestureState == THREE_GESTURE_STATE_DETECTING; + try { + SystemProperties.set("sys.android.screenshot", shouldEnableProp ? "true" : "false"); + } catch(Exception e) { + Log.e(TAG, "Exception when setprop", e); + } + } + } + + private boolean checkIsStartThreeGesture(MotionEvent event) { + if (event.getEventTime() - event.getDownTime() > 500) { + return false; + } + int height = mDisplayMetrics.heightPixels; + int width = mDisplayMetrics.widthPixels; + float minX = Float.MAX_VALUE; + float maxX = Float.MIN_VALUE; + float minY = Float.MAX_VALUE; + float maxY = Float.MIN_VALUE; + for (int i = 0; i < event.getPointerCount(); i++) { + float x = event.getX(i); + float y = event.getY(i); + if (y > ((float) (height - mThreshold))) { + return false; + } + maxX = Math.max(maxX, x); + minX = Math.min(minX, x); + maxY = Math.max(maxY, y); + minY = Math.min(minY, y); + } + if (maxY - minY <= mDisplayMetrics.density * 150.0f) { + return maxX - minX <= ((float) (width < height ? width : height)); + } + return false; + } + + interface Callbacks { + void onSwipeThreeFinger(); + } +} |