From c0e4ee7332718381902c1081ea16a63a66457f36 Mon Sep 17 00:00:00 2001 From: Dmitry Dementyev Date: Mon, 1 Jul 2019 16:41:19 +0000 Subject: [PATCH 1/7] Revert "Do not load xml metadata for unchanged packages in RegisteredServicesCache" This reverts commit 8094880025d0680ec4cf586929d85b9050d4e9d6. Reason for revert: changed services order Test: manual Bug: 136261465 Change-Id: I2f78f0dbbace212309b87f779efad020cf255196 Merged-In: I2f78f0dbbace212309b87f779efad020cf255196 --- .../content/pm/RegisteredServicesCache.java | 59 +++++++------------ .../pm/RegisteredServicesCacheTest.java | 41 ------------- 2 files changed, 20 insertions(+), 80 deletions(-) diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index c8f046775211b..020e8c22b1289 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -17,7 +17,6 @@ package android.content.pm; import android.Manifest; -import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -175,8 +174,7 @@ public abstract class RegisteredServicesCache { mContext.registerReceiver(mUserRemovedReceiver, userFilter); } - @VisibleForTesting - protected void handlePackageEvent(Intent intent, int userId) { + private final void handlePackageEvent(Intent intent, int userId) { // Don't regenerate the services map when the package is removed or its // ASEC container unmounted as a step in replacement. The subsequent // _ADDED / _AVAILABLE call will regenerate the map in the final state. @@ -238,9 +236,6 @@ public abstract class RegisteredServicesCache { public void invalidateCache(int userId) { synchronized (mServicesLock) { - if (DEBUG) { - Slog.d(TAG, "invalidating cache for " + userId + " " + mInterfaceName); - } final UserServices user = findOrCreateUserLocked(userId); user.services = null; onServicesChangedLocked(userId); @@ -465,48 +460,34 @@ public abstract class RegisteredServicesCache { * or null to assume that everything is affected. * @param userId the user for whom to update the services map. */ - private void generateServicesMap(@Nullable int[] changedUids, int userId) { + private void generateServicesMap(int[] changedUids, int userId) { if (DEBUG) { Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + Arrays.toString(changedUids)); } + final ArrayList> serviceInfos = new ArrayList<>(); + final List resolveInfos = queryIntentServices(userId); + for (ResolveInfo resolveInfo : resolveInfos) { + try { + ServiceInfo info = parseServiceInfo(resolveInfo); + if (info == null) { + Log.w(TAG, "Unable to load service info " + resolveInfo.toString()); + continue; + } + serviceInfos.add(info); + } catch (XmlPullParserException|IOException e) { + Log.w(TAG, "Unable to load service info " + resolveInfo.toString(), e); + } + } + synchronized (mServicesLock) { final UserServices user = findOrCreateUserLocked(userId); - final boolean cacheInvalid = user.services == null; - if (cacheInvalid) { + final boolean firstScan = user.services == null; + if (firstScan) { user.services = Maps.newHashMap(); } - final ArrayList> serviceInfos = new ArrayList<>(); - final List resolveInfos = queryIntentServices(userId); - - for (ResolveInfo resolveInfo : resolveInfos) { - try { - // when changedUids == null, we want to do a rescan of everything, this means - // it's the initial scan, and containsUid will trivially return true - // when changedUids != null, we got here because a package changed, but - // invalidateCache could have been called (thus user.services == null), and we - // should query from PackageManager again - if (!cacheInvalid - && !containsUid( - changedUids, resolveInfo.serviceInfo.applicationInfo.uid)) { - if (DEBUG) { - Slog.d(TAG, "Skipping parseServiceInfo for " + resolveInfo); - } - continue; - } - ServiceInfo info = parseServiceInfo(resolveInfo); - if (info == null) { - Log.w(TAG, "Unable to load service info " + resolveInfo.toString()); - continue; - } - serviceInfos.add(info); - } catch (XmlPullParserException | IOException e) { - Log.w(TAG, "Unable to load service info " + resolveInfo.toString(), e); - } - } - StringBuilder changes = new StringBuilder(); boolean changed = false; for (ServiceInfo info : serviceInfos) { @@ -527,7 +508,7 @@ public abstract class RegisteredServicesCache { changed = true; user.services.put(info.type, info); user.persistentServices.put(info.type, info.uid); - if (!(user.mPersistentServicesFileDidNotExist && cacheInvalid)) { + if (!(user.mPersistentServicesFileDidNotExist && firstScan)) { notifyListener(info.type, userId, false /* removed */); } } else if (previousUid == info.uid) { diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java index c8b449e68da7f..d3d1f22af3cb5 100644 --- a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java +++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java @@ -16,7 +16,6 @@ package android.content.pm; -import android.content.Intent; import android.content.res.Resources; import android.os.FileUtils; import android.os.Parcel; @@ -189,36 +188,6 @@ public class RegisteredServicesCacheTest extends AndroidTestCase { assertEquals(0, cache.getPersistentServicesSize(u1)); } - /** - * Check that an optimization to skip a call to PackageManager handles an invalidated cache. - * - * We added an optimization in generateServicesMap to only query PackageManager for packages - * that have been changed, because if a package is unchanged, we have already cached the - * services info for it, so we can save a query to PackageManager (and save some memory). - * However, if invalidateCache was called, we cannot optimize, and must do a full query. - * The initial optimization was buggy because it failed to check for an invalidated cache, and - * only scanned the changed packages, given in the ACTION_PACKAGE_CHANGED intent (b/122912184). - */ - public void testParseServiceInfoOptimizationHandlesInvalidatedCache() { - TestServicesCache cache = new TestServicesCache(); - cache.addServiceForQuerying(U0, r1, newServiceInfo(t1, UID1)); - cache.addServiceForQuerying(U0, r2, newServiceInfo(t2, UID2)); - assertEquals(2, cache.getAllServicesSize(U0)); - - // simulate the client of the cache invalidating it - cache.invalidateCache(U0); - - // there should be 0 services (userServices.services == null ) at this point, but we don't - // call getAllServicesSize since that would force a full scan of packages, - // instead we trigger a package change in a package that is in the list of services - Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED); - intent.putExtra(Intent.EXTRA_UID, UID1); - cache.handlePackageEvent(intent, U0); - - // check that the optimization does a full query and caches both services - assertEquals(2, cache.getAllServicesSize(U0)); - } - private static RegisteredServicesCache.ServiceInfo newServiceInfo( TestServiceType type, int uid) { final ComponentInfo info = new ComponentInfo(); @@ -296,11 +265,6 @@ public class RegisteredServicesCacheTest extends AndroidTestCase { map = new HashMap<>(); mServices.put(userId, map); } - // in actual cases, resolveInfo should always have a serviceInfo, since we specifically - // query for intent services - resolveInfo.serviceInfo = new android.content.pm.ServiceInfo(); - resolveInfo.serviceInfo.applicationInfo = - new ApplicationInfo(serviceInfo.componentInfo.applicationInfo); map.put(resolveInfo, serviceInfo); } @@ -339,11 +303,6 @@ public class RegisteredServicesCacheTest extends AndroidTestCase { public void onUserRemoved(int userId) { super.onUserRemoved(userId); } - - @Override - public void handlePackageEvent(Intent intent, int userId) { - super.handlePackageEvent(intent, userId); - } } static class TestSerializer implements XmlSerializerAndParser { From f50316cb46d11882119a61a41f2c83a79b76f108 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 3 Jul 2019 15:44:00 -0700 Subject: [PATCH 2/7] Do not trigger revoke-perm callbacks if no change Revoking a permission might e.g. kill the the app. If a permission gets revoked that was never granted there was no change, hence no need to call the callbacks and also no need to kill the app. Test: "pm clear" two times in a row. The second one did trigger a kill before, not anymore. Bug: 133830856 Change-Id: I357f2d939520ac78ef82ecf4feb7936455950fc4 --- .../server/pm/permission/PermissionManagerService.java | 5 +++++ 1 file changed, 5 insertions(+) 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 a7da3ec950f4d..d3e5df5d62d12 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; From 019a52b4add4a04c1e54b7af71e96713496fa7b4 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 2 Jul 2019 16:47:44 +0200 Subject: [PATCH 3/7] WM: implicitly exclude all edges for pre-Q immersive sticky apps Bug: 135522625 Test: atest DisplayContentTests Change-Id: Ibe6c2c6d269b15c2e79ac0241b93e42c44a167c9 Exempt-From-Owner-Approval: TBR --- api/test-current.txt | 1 + core/java/android/provider/DeviceConfig.java | 11 +++++++ .../com/android/server/wm/DisplayContent.java | 18 ++++++---- .../server/wm/WindowManagerService.java | 12 ++++++- .../com/android/server/wm/WindowState.java | 12 +++++++ .../server/wm/DisplayContentTests.java | 33 +++++++++++++++++++ .../server/wm/TestWindowManagerPolicy.java | 3 +- 7 files changed, 81 insertions(+), 9 deletions(-) diff --git a/api/test-current.txt b/api/test-current.txt index 1dc6faad37644..6f0b6a809c9c7 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/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 920eb4b517759..e30ba38c127fa 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/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 1659131d880db..c069b2e8da5c2 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5158,15 +5158,19 @@ class DisplayContent extends WindowContainer { 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 c6c9e1b39db41..b5586bf28751d 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 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); 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 f49a575349387..f2e7dc6fecae0 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; @@ -788,6 +793,34 @@ public class DisplayContentTests extends WindowTestsBase { 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); 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 c3561f4bf6ab4..d034f274f1e15 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 From b106379310783dac036088c6ef052d3ceb0754fa Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Fri, 28 Jun 2019 12:10:51 +0200 Subject: [PATCH 4/7] GestureNav: Fix broken exclusion rect calculation for modal windows Fixes an issue with non-fullscreen modal windows (such as dialogs), where the touch exclusion of the window behind was still being applied, even though the window behind did not actually receive the touches in the exclusion, because they would go to the modal window in front. Bug: 135522625 Test: atest testCalculateSystemGestureExclusion_modal Change-Id: Ia99f4f601e780715abaf966f6f297fd9d555fd0b --- .../com/android/server/wm/DisplayContent.java | 6 ++--- .../com/android/server/wm/WindowState.java | 19 +++++++++++++++ .../server/wm/DisplayContentTests.java | 24 +++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c069b2e8da5c2..675483442300f 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5142,7 +5142,7 @@ class DisplayContent extends WindowContainer { if (w.cantReceiveTouchInput() || !w.isVisible() @@ -5150,12 +5150,10 @@ class DisplayContent extends WindowContainer 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/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index f2e7dc6fecae0..7cd097ebdc2b2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -793,6 +793,30 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(expected, dc.calculateSystemGestureExclusion()); } + @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) { From 2351d5f48f10d26cd6aabb163b0b19a0b406e089 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Wed, 3 Jul 2019 15:35:07 +0200 Subject: [PATCH 5/7] GestureExclusion: Fix restriction priority Bottom restrictions should be applied first. Bug: 135522625 Test: adb shell setprop debug.pointerlocation.showexclusion true; adb shell stop; adb shell start; open app excluding entire edge, verify bottom part is applied. Change-Id: Ifc2bc64b1ce3132f198e23ae8e271380acf0c5a1 --- .../java/com/android/server/wm/DisplayContent.java | 6 +++--- .../com/android/server/wm/utils/RegionUtils.java | 13 +++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 675483442300f..b837d9ec874b6 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; @@ -5227,13 +5227,13 @@ class DisplayContent extends WindowContainer { + 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/utils/RegionUtils.java b/services/core/java/com/android/server/wm/utils/RegionUtils.java index 8cd6f88260833..b1b30701df4fa 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 rectConsumer) { + public static void forEachRectReverse(Region region, Consumer rectConsumer) { final RegionIterator it = new RegionIterator(region); + final ArrayList 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); } } From 4cbe159555e05679a1ffe8095f9ebef9df85ff7d Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 5 Jul 2019 02:03:54 -0700 Subject: [PATCH 6/7] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I634b80fa18b8f14a90e5494933bf9b49a4c3f68f --- packages/SettingsLib/res/values-en-rAU/strings.xml | 2 +- packages/SettingsLib/res/values-en-rCA/strings.xml | 2 +- packages/SettingsLib/res/values-en-rGB/strings.xml | 2 +- packages/SettingsLib/res/values-en-rIN/strings.xml | 2 +- packages/SettingsLib/res/values-in/strings.xml | 4 ++-- packages/SettingsLib/res/values-sq/strings.xml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 57f5d5a5f6143..63463b1b31f1b 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -408,7 +408,7 @@ "Charging" "charging" "Not charging" - "Plugged in, can\'t charge right now" + "Plugged in, can\'t charge at the moment" "Full" "Controlled by admin" "Disabled" diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 57f5d5a5f6143..63463b1b31f1b 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -408,7 +408,7 @@ "Charging" "charging" "Not charging" - "Plugged in, can\'t charge right now" + "Plugged in, can\'t charge at the moment" "Full" "Controlled by admin" "Disabled" diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 57f5d5a5f6143..63463b1b31f1b 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -408,7 +408,7 @@ "Charging" "charging" "Not charging" - "Plugged in, can\'t charge right now" + "Plugged in, can\'t charge at the moment" "Full" "Controlled by admin" "Disabled" diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 57f5d5a5f6143..63463b1b31f1b 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -408,7 +408,7 @@ "Charging" "charging" "Not charging" - "Plugged in, can\'t charge right now" + "Plugged in, can\'t charge at the moment" "Full" "Controlled by admin" "Disabled" diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 798ea3c80cb03..7fe1ef9213edb 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -293,8 +293,8 @@ "Kedipkan layar saat apl beroperasi lama pada utas utama" "Lokasi penunjuk" "Hamparan layar menampilkan data sentuhan saat ini" - "Tampilkan tap" - "Tampilkan masukan visual untuk tap" + "Tampilkan ketukan" + "Tampilkan masukan untuk ketukan" "Lihat pembaruan permukaan" "Sorot seluruh permukaan jendela saat diperbarui" "Tampilkan update tampilan" diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 4b38383545e5d..7a054bbec646d 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -307,7 +307,7 @@ "Simulo hapësirën e ngjyrës" "Aktivizo gjurmët e OpenGL-së" "Çaktivizo rrugëzuezin e audios përmes USB-së" - "Çaktivizo rrugëzuesin automatik për te kufjet ose altoparlantët" + "Çaktivizo router-in automatik për te kufjet ose altoparlantët" "Shfaq konturet e kuadrit" "Shfaq konturet e klipit, hapësirat etj." "Detyro drejtimin e shkrimit nga e djathta në të majtë" From 6f672a38356457bd23c89efaa8f1b89953843662 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Mon, 8 Jul 2019 16:40:42 -0700 Subject: [PATCH 7/7] Specify the duration time base Test: N/A Bug: 128316830 Change-Id: Idd8f1aaf1a8e0013c01fdf4d668f9d5e81101559 --- core/java/android/app/AppOpsManager.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 60f1424220f6e..2f0782b413bfb 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},