summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Silva <jhenrique09.mcz@hotmail.com>2019-05-08 11:52:38 -0300
committeralk3pInjection <webmaster@raspii.tech>2021-09-27 21:17:05 +0800
commitd662f25af97a2ad03445cd6cca6b1df2e4de627b (patch)
treeb2a1b5088dfb541a66f8874ca90edcc06315a9b8
parent8abff700cb9c045874f3c336e11b2e624ae53886 (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
-rw-r--r--core/java/android/app/IActivityManager.aidl5
-rwxr-xr-xcore/java/android/provider/Settings.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java14
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java40
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java30
-rw-r--r--services/core/java/com/android/server/policy/SwipeToScreenshotListener.java148
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();
+ }
+}