summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/test-current.txt1
-rw-r--r--core/java/android/app/AppOpsManager.java12
-rw-r--r--core/java/android/provider/DeviceConfig.java11
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml2
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java30
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java31
-rw-r--r--services/core/java/com/android/server/wm/utils/RegionUtils.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java57
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java3
16 files changed, 159 insertions, 30 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index 1dc6faad3764..6f0b6a809c9c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2312,6 +2312,7 @@ package android.provider {
}
public static interface DeviceConfig.WindowManager {
+ field public static final String KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE = "system_gestures_excluded_by_pre_q_sticky_immersive";
field public static final String KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP = "system_gesture_exclusion_limit_dp";
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 60f1424220f6..2f0782b413bf 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2507,7 +2507,7 @@ public class AppOpsManager {
}
/**
- * @return The duration of the operation in milliseconds.
+ * @return The duration of the operation in milliseconds. The duration is in wall time.
*/
public long getDuration() {
return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
@@ -2515,7 +2515,7 @@ public class AppOpsManager {
/**
* Return the duration in milliseconds the app accessed this op while
- * in the foreground.
+ * in the foreground. The duration is in wall time.
*
* @param flags The flags which are any combination of
* {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -2534,7 +2534,7 @@ public class AppOpsManager {
/**
* Return the duration in milliseconds the app accessed this op while
- * in the background.
+ * in the background. The duration is in wall time.
*
* @param flags The flags which are any combination of
* {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -2553,7 +2553,7 @@ public class AppOpsManager {
/**
* Return the duration in milliseconds the app accessed this op for
- * a given range of UID states.
+ * a given range of UID states. The duration is in wall time.
*
* @param fromUidState The UID state for which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
@@ -3968,6 +3968,7 @@ public class AppOpsManager {
/**
* Gets the total duration the app op was accessed (performed) in the foreground.
+ * The duration is in wall time.
*
* @param flags The flags which are any combination of
* {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -3986,6 +3987,7 @@ public class AppOpsManager {
/**
* Gets the total duration the app op was accessed (performed) in the background.
+ * The duration is in wall time.
*
* @param flags The flags which are any combination of
* {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -4004,7 +4006,7 @@ public class AppOpsManager {
/**
* Gets the total duration the app op was accessed (performed) for a given
- * range of UID states.
+ * range of UID states. The duration is in wall time.
*
* @param fromUidState The UID state from which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 920eb4b51775..e30ba38c127f 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -325,6 +325,17 @@ public final class DeviceConfig {
*/
@TestApi
String KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP = "system_gesture_exclusion_limit_dp";
+
+ /**
+ * Key for controlling whether system gestures are implicitly excluded by windows requesting
+ * sticky immersive mode from apps that are targeting an SDK prior to Q.
+ *
+ * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
+ * @hide
+ */
+ @TestApi
+ String KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE =
+ "system_gestures_excluded_by_pre_q_sticky_immersive";
}
private static final Object sLock = new Object();
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 57f5d5a5f614..63463b1b31f1 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -408,7 +408,7 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+ <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
<string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 57f5d5a5f614..63463b1b31f1 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -408,7 +408,7 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+ <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
<string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 57f5d5a5f614..63463b1b31f1 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -408,7 +408,7 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+ <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
<string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 57f5d5a5f614..63463b1b31f1 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -408,7 +408,7 @@
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
<string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
- <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+ <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
<string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
<string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 798ea3c80cb0..7fe1ef9213ed 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -293,8 +293,8 @@
<string name="strict_mode_summary" msgid="142834318897332338">"Kedipkan layar saat apl beroperasi lama pada utas utama"</string>
<string name="pointer_location" msgid="6084434787496938001">"Lokasi penunjuk"</string>
<string name="pointer_location_summary" msgid="840819275172753713">"Hamparan layar menampilkan data sentuhan saat ini"</string>
- <string name="show_touches" msgid="2642976305235070316">"Tampilkan tap"</string>
- <string name="show_touches_summary" msgid="6101183132903926324">"Tampilkan masukan visual untuk tap"</string>
+ <string name="show_touches" msgid="2642976305235070316">"Tampilkan ketukan"</string>
+ <string name="show_touches_summary" msgid="6101183132903926324">"Tampilkan masukan untuk ketukan"</string>
<string name="show_screen_updates" msgid="5470814345876056420">"Lihat pembaruan permukaan"</string>
<string name="show_screen_updates_summary" msgid="2569622766672785529">"Sorot seluruh permukaan jendela saat diperbarui"</string>
<string name="show_hw_screen_updates" msgid="4117270979975470789">"Tampilkan update tampilan"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 4b38383545e5..7a054bbec646 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -307,7 +307,7 @@
<string name="simulate_color_space" msgid="6745847141353345872">"Simulo hapësirën e ngjyrës"</string>
<string name="enable_opengl_traces_title" msgid="6790444011053219871">"Aktivizo gjurmët e OpenGL-së"</string>
<string name="usb_audio_disable_routing" msgid="8114498436003102671">"Çaktivizo rrugëzuezin e audios përmes USB-së"</string>
- <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Çaktivizo rrugëzuesin automatik për te kufjet ose altoparlantët"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Çaktivizo router-in automatik për te kufjet ose altoparlantët"</string>
<string name="debug_layout" msgid="5981361776594526155">"Shfaq konturet e kuadrit"</string>
<string name="debug_layout_summary" msgid="2001775315258637682">"Shfaq konturet e klipit, hapësirat etj."</string>
<string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Detyro drejtimin e shkrimit nga e djathta në të majtë"</string>
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index a7da3ec950f4..d3e5df5d62d1 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2269,6 +2269,11 @@ public class PermissionManagerService {
return;
}
+ // Permission is already revoked, no need to do anything.
+ if (!permissionsState.hasRuntimePermission(permName, userId)) {
+ return;
+ }
+
if (permissionsState.revokeRuntimePermission(bp, userId) ==
PERMISSION_OPERATION_FAILURE) {
return;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1659131d880d..b837d9ec874b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -140,7 +140,7 @@ import static com.android.server.wm.WindowManagerService.logSurface;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
-import static com.android.server.wm.utils.RegionUtils.forEachRect;
+import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
import android.animation.AnimationHandler;
@@ -5142,7 +5142,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
final int[] remainingLeftRight =
{mSystemGestureExclusionLimit, mSystemGestureExclusionLimit};
- // Traverse all windows bottom up to assemble the gesture exclusion rects.
+ // Traverse all windows top down to assemble the gesture exclusion rects.
// For each window, we only take the rects that fall within its touchable region.
forAllWindows(w -> {
if (w.cantReceiveTouchInput() || !w.isVisible()
@@ -5150,23 +5150,25 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|| unhandled.isEmpty()) {
return;
}
- final boolean modal =
- (w.mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
// Get the touchable region of the window, and intersect with where the screen is still
// touchable, i.e. touchable regions on top are not covering it yet.
- w.getTouchableRegion(touchableRegion);
+ w.getEffectiveTouchableRegion(touchableRegion);
touchableRegion.op(unhandled, Op.INTERSECT);
- rectListToRegion(w.getSystemGestureExclusion(), local);
+ if (w.isImplicitlyExcludingAllSystemGestures()) {
+ local.set(touchableRegion);
+ } else {
+ rectListToRegion(w.getSystemGestureExclusion(), local);
- // Transform to display coordinates
- local.scale(w.mGlobalScale);
- final Rect frame = w.getWindowFrames().mFrame;
- local.translate(frame.left, frame.top);
+ // Transform to display coordinates
+ local.scale(w.mGlobalScale);
+ final Rect frame = w.getWindowFrames().mFrame;
+ local.translate(frame.left, frame.top);
- // A window can only exclude system gestures where it is actually touchable
- local.op(touchableRegion, Op.INTERSECT);
+ // A window can only exclude system gestures where it is actually touchable
+ local.op(touchableRegion, Op.INTERSECT);
+ }
// Apply restriction if necessary.
if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) {
@@ -5225,13 +5227,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
r.op(edge, Op.INTERSECT);
final int[] remaining = {limit};
- forEachRect(r, rect -> {
+ forEachRectReverse(r, rect -> {
if (remaining[0] <= 0) {
return;
}
final int height = rect.height();
if (height > remaining[0]) {
- rect.bottom = rect.top + remaining[0];
+ rect.top = rect.bottom - remaining[0];
}
remaining[0] -= height;
global.op(rect, Op.UNION);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2db0131a122f..fb57d73c9a21 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -32,6 +32,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.myPid;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE;
import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -844,6 +845,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mWindowsChanged = false;
int mSystemGestureExclusionLimitDp;
+ boolean mSystemGestureExcludedByPreQStickyImmersive;
public interface WindowChangeListener {
public void windowsChanged();
@@ -1142,13 +1144,21 @@ public class WindowManagerService extends IWindowManager.Stub
mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
+ mSystemGestureExcludedByPreQStickyImmersive =
+ DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+ KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
new HandlerExecutor(mH), properties -> {
synchronized (mGlobalLock) {
final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
- if (mSystemGestureExclusionLimitDp != exclusionLimitDp) {
+ final boolean excludedByPreQSticky = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+ KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
+ if (mSystemGestureExcludedByPreQStickyImmersive != excludedByPreQSticky
+ || mSystemGestureExclusionLimitDp != exclusionLimitDp) {
mSystemGestureExclusionLimitDp = exclusionLimitDp;
+ mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky;
mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c6c9e1b39db4..43ad091b08c0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -24,6 +24,8 @@ import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.SurfaceControl.Transaction;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -155,6 +157,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Binder;
+import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
import android.os.PowerManager;
@@ -657,6 +660,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return true;
}
+ boolean isImplicitlyExcludingAllSystemGestures() {
+ final int immersiveStickyFlags =
+ SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ final boolean immersiveSticky =
+ (mSystemUiVisibility & immersiveStickyFlags) == immersiveStickyFlags;
+ return immersiveSticky && mWmService.mSystemGestureExcludedByPreQStickyImmersive
+ && mAppToken != null && mAppToken.mTargetSdk < Build.VERSION_CODES.Q;
+ }
+
interface PowerManagerWrapper {
void wakeUp(long time, @WakeReason int reason, String details);
@@ -2999,6 +3011,25 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
subtractTouchExcludeRegionIfNeeded(outRegion);
}
+ /**
+ * Get the effective touchable region in global coordinates.
+ *
+ * In contrast to {@link #getTouchableRegion}, this takes into account
+ * {@link WindowManager.LayoutParams#FLAG_NOT_TOUCH_MODAL touch modality.}
+ */
+ void getEffectiveTouchableRegion(Region outRegion) {
+ final boolean modal = (mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
+ final DisplayContent dc = getDisplayContent();
+
+ if (modal && dc != null) {
+ outRegion.set(dc.getBounds());
+ cropRegionToStackBoundsIfNeeded(outRegion);
+ subtractTouchExcludeRegionIfNeeded(outRegion);
+ } else {
+ getTouchableRegion(outRegion);
+ }
+ }
+
private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) {
final Task task = getTask();
if (task == null || !task.cropWindowsToStackBounds()) {
diff --git a/services/core/java/com/android/server/wm/utils/RegionUtils.java b/services/core/java/com/android/server/wm/utils/RegionUtils.java
index 8cd6f8826083..b1b30701df4f 100644
--- a/services/core/java/com/android/server/wm/utils/RegionUtils.java
+++ b/services/core/java/com/android/server/wm/utils/RegionUtils.java
@@ -20,6 +20,8 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.RegionIterator;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
@@ -48,14 +50,21 @@ public class RegionUtils {
/**
* Applies actions on each rect contained within a {@code Region}.
*
+ * Order is bottom to top, then right to left.
+ *
* @param region the given region.
* @param rectConsumer the action holder.
*/
- public static void forEachRect(Region region, Consumer<Rect> rectConsumer) {
+ public static void forEachRectReverse(Region region, Consumer<Rect> rectConsumer) {
final RegionIterator it = new RegionIterator(region);
+ final ArrayList<Rect> rects = new ArrayList<>();
final Rect rect = new Rect();
while (it.next(rect)) {
- rectConsumer.accept(rect);
+ rects.add(new Rect(rect));
}
+ // TODO: instead of creating an array and reversing it, expose the reverse iterator through
+ // JNI.
+ Collections.reverse(rects);
+ rects.forEach(rectConsumer);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f49a57534938..7cd097ebdc2b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -26,8 +26,13 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -789,6 +794,58 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
+ public void testCalculateSystemGestureExclusion_modal() throws Exception {
+ final DisplayContent dc = createNewDisplay();
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "base");
+ win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+ win.setSystemGestureExclusion(Collections.singletonList(new Rect(0, 0, 1000, 1000)));
+
+ final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "modal");
+ win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+ win2.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+ win2.getAttrs().width = 10;
+ win2.getAttrs().height = 10;
+ win2.setSystemGestureExclusion(Collections.emptyList());
+
+ dc.setLayoutNeeded();
+ dc.performLayout(true /* initial */, false /* updateImeWindows */);
+
+ win.setHasSurface(true);
+ win2.setHasSurface(true);
+
+ final Region expected = Region.obtain();
+ assertEquals(expected, dc.calculateSystemGestureExclusion());
+ }
+
+ @Test
+ public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
+ synchronized (mWm.mGlobalLock) {
+ mWm.mSystemGestureExcludedByPreQStickyImmersive = true;
+
+ final DisplayContent dc = createNewDisplay();
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
+ win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+ win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+ win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
+ SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ win.mAppToken.mTargetSdk = P;
+
+ dc.setLayoutNeeded();
+ dc.performLayout(true /* initial */, false /* updateImeWindows */);
+
+ win.setHasSurface(true);
+
+ final Region expected = Region.obtain();
+ expected.set(dc.getBounds());
+ assertEquals(expected, dc.calculateSystemGestureExclusion());
+
+ win.setHasSurface(false);
+ }
+ }
+
+ @Test
public void testOrientationChangeLogging() {
MetricsLogger mockLogger = mock(MetricsLogger.class);
Configuration oldConfig = new Configuration();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index c3561f4bf6ab..d034f274f1e1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -49,6 +49,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
int mRotationToReport = 0;
boolean mKeyguardShowingAndNotOccluded = false;
+ boolean mOkToAnimate = true;
private Runnable mRunnableWhenAddingSplashScreen;
@@ -222,7 +223,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public boolean okToAnimate() {
- return true;
+ return mOkToAnimate;
}
@Override