summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java10
-rw-r--r--apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java1
-rw-r--r--apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java10
-rw-r--r--apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java6
-rw-r--r--apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java6
-rw-r--r--apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java20
-rw-r--r--apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java14
-rw-r--r--apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java6
-rw-r--r--apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java35
-rw-r--r--apct-tests/perftests/core/src/android/text/TextPerfUtils.java19
-rw-r--r--apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java6
-rw-r--r--apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java37
-rwxr-xr-xapi/current.txt40
-rw-r--r--api/system-current.txt1
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java2
-rw-r--r--cmds/am/src/com/android/commands/am/Instrument.java16
-rw-r--r--cmds/incidentd/Android.mk6
-rw-r--r--cmds/statsd/src/atoms.proto91
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp3
-rw-r--r--config/preloaded-classes6
-rw-r--r--core/java/android/app/ActivityManager.java11
-rw-r--r--core/java/android/app/NotificationChannel.java5
-rw-r--r--core/java/android/app/WallpaperInfo.java24
-rw-r--r--core/java/android/content/Intent.java16
-rw-r--r--core/java/android/inputmethodservice/IInputMethodSessionWrapper.java11
-rw-r--r--core/java/android/os/PowerManager.java6
-rw-r--r--core/java/android/provider/Settings.java6
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java6
-rw-r--r--core/java/android/text/Layout.java36
-rw-r--r--core/java/android/text/style/TextAppearanceSpan.java4
-rw-r--r--core/java/android/view/GhostView.java6
-rw-r--r--core/java/android/view/IWindowManager.aidl41
-rw-r--r--core/java/android/view/RenderNodeAnimator.java8
-rw-r--r--core/java/android/view/RenderNodeAnimatorSetHelper.java6
-rw-r--r--core/java/android/view/Surface.java4
-rw-r--r--core/java/android/view/SurfaceView.java1
-rw-r--r--core/java/android/view/TextureLayer.java2
-rw-r--r--core/java/android/view/TextureView.java5
-rw-r--r--core/java/android/view/ThreadedRenderer.java8
-rw-r--r--core/java/android/view/View.java10
-rw-r--r--core/java/android/view/ViewAnimationHostBridge.java2
-rw-r--r--core/java/android/view/ViewDebug.java4
-rw-r--r--core/java/android/view/ViewPropertyAnimator.java1
-rw-r--r--core/java/android/view/ViewRootImpl.java6
-rw-r--r--core/java/android/view/WindowCallbacks.java3
-rw-r--r--core/java/android/webkit/WebViewDelegate.java10
-rw-r--r--core/java/android/widget/Editor.java14
-rw-r--r--core/java/android/widget/Magnifier.java10
-rw-r--r--core/java/android/widget/TextView.java8
-rw-r--r--core/java/com/android/internal/policy/BackdropFrameRenderer.java8
-rw-r--r--core/java/com/android/internal/policy/DecorView.java97
-rw-r--r--core/java/com/android/internal/view/IInputMethodSession.aidl4
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java10
-rw-r--r--core/jni/android_opengl_EGL15.cpp75
-rw-r--r--core/jni/android_view_DisplayListCanvas.cpp2
-rw-r--r--core/jni/android_view_RenderNode.cpp6
-rw-r--r--core/res/res/values/attrs.xml3
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/strings.xml18
-rw-r--r--core/tests/coretests/assets/fonts/1em_bidi_font.ttfbin0 -> 2076 bytes
-rw-r--r--core/tests/coretests/src/android/text/LayoutBidiCursorPathTest.java166
-rw-r--r--core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java17
-rw-r--r--data/etc/privapp-permissions-platform.xml1
-rw-r--r--graphics/java/android/graphics/BaseCanvas.java2
-rw-r--r--graphics/java/android/graphics/Bitmap.java4
-rw-r--r--graphics/java/android/graphics/Picture.java3
-rw-r--r--graphics/java/android/graphics/RecordingCanvas.java (renamed from core/java/android/view/DisplayListCanvas.java)62
-rw-r--r--graphics/java/android/graphics/RenderNode.java (renamed from core/java/android/view/RenderNode.java)100
-rw-r--r--graphics/java/android/graphics/Typeface.java3
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java10
-rw-r--r--graphics/java/android/graphics/drawable/RippleComponent.java7
-rw-r--r--graphics/java/android/graphics/drawable/RippleForeground.java10
-rw-r--r--graphics/java/android/graphics/fonts/Font.java143
-rw-r--r--graphics/java/android/graphics/fonts/FontFamily.java2
-rw-r--r--graphics/java/android/graphics/fonts/FontStyle.java256
-rw-r--r--graphics/java/android/graphics/fonts/SystemFonts.java3
-rw-r--r--libs/hwui/Android.bp3
-rw-r--r--libs/hwui/hwui/MinikinSkia.cpp2
-rw-r--r--libs/hwui/tests/macrobench/main.cpp2
-rw-r--r--opengl/java/android/opengl/EGL15.java18
-rw-r--r--packages/ExtServices/src/android/ext/services/notification/AgingHelper.java2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java53
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java10
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/KeyguardManagerCompat.java32
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java45
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java40
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeHost.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java93
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java5
-rw-r--r--proto/src/metrics_constants/metrics_constants.proto5
-rw-r--r--services/accessibility/java/com/android/server/accessibility/MagnificationController.java1076
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java148
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityDisplay.java46
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java23
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java6
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java18
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java64
-rw-r--r--services/core/java/com/android/server/am/ActivityTaskManagerService.java3
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java72
-rw-r--r--services/core/java/com/android/server/job/controllers/ConnectivityController.java141
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java17
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecord.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/Settings.java34
-rw-r--r--services/core/java/com/android/server/pm/SharedUserSetting.java26
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java31
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java21
-rw-r--r--services/core/java/com/android/server/power/BatterySaverPolicy.java14
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverController.java6
-rw-r--r--services/core/java/com/android/server/stats/StatsCompanionService.java32
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java73
-rw-r--r--services/core/java/com/android/server/wm/DisplaySettings.java163
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java64
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerShellCommand.java35
-rw-r--r--services/tests/mockingservicestests/Android.mk2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java270
-rw-r--r--services/tests/servicestests/Android.mk3
-rw-r--r--services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java28
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java56
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java57
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java42
-rw-r--r--services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java141
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java76
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java11
-rw-r--r--services/tests/servicestests/test-apps/SuspendTestApp/Android.mk2
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java36
-rw-r--r--services/tests/wmtests/Android.mk2
-rw-r--r--services/usage/java/com/android/server/usage/AppIdleHistory.java19
-rw-r--r--services/usage/java/com/android/server/usage/AppStandbyController.java8
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java6
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java12
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java8
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java3
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java6
-rw-r--r--tests/Internal/res/xml/livewallpaper.xml3
-rw-r--r--tests/Internal/src/android/app/WallpaperInfoTest.java27
-rw-r--r--tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java2
-rw-r--r--tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java31
-rw-r--r--tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java2
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java7
-rw-r--r--wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl5
-rw-r--r--wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java53
171 files changed, 3466 insertions, 1715 deletions
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
index eed1db032d9f..c742df3b882b 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
@@ -17,14 +17,14 @@
package android.graphics.perftests;
import android.graphics.Bitmap;
-import android.graphics.Color;
import android.graphics.Bitmap.Config;
+import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.filters.LargeTest;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import org.junit.Rule;
import org.junit.Test;
@@ -43,7 +43,7 @@ public class CanvasPerfTest {
RenderNode child = RenderNode.create("child", null);
child.setLeftTopRightBottom(50, 50, 100, 100);
- DisplayListCanvas canvas = node.start(100, 100);
+ RecordingCanvas canvas = node.start(100, 100);
node.end(canvas);
canvas = child.start(50, 50);
canvas.drawColor(Color.WHITE);
@@ -70,7 +70,7 @@ public class CanvasPerfTest {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
RenderNode node = RenderNode.create("benchmark", null);
- DisplayListCanvas canvas = node.start(100, 100);
+ RecordingCanvas canvas = node.start(100, 100);
node.end(canvas);
Bitmap bitmap = Bitmap.createBitmap(80, 80, Config.ARGB_8888);
Paint paint = new Paint();
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java
index 3a4fc7206712..f9c375804599 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java
@@ -20,7 +20,6 @@ import android.graphics.Outline;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.filters.LargeTest;
-import android.view.RenderNode;
import org.junit.Rule;
import org.junit.Test;
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
index a283e0664bc6..d18aa51bfcd3 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
@@ -17,17 +17,15 @@
package android.graphics.perftests;
import android.graphics.Outline;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.filters.LargeTest;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import org.junit.Rule;
import org.junit.Test;
-import java.util.ArrayList;
-
@LargeTest
public class RenderNodePerfTest {
@Rule
@@ -73,7 +71,7 @@ public class RenderNodePerfTest {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
RenderNode node = RenderNode.create("LinearLayout", null);
while (state.keepRunning()) {
- DisplayListCanvas canvas = node.start(100, 100);
+ RecordingCanvas canvas = node.start(100, 100);
node.end(canvas);
}
}
@@ -82,7 +80,7 @@ public class RenderNodePerfTest {
public void testStartEndDeepHierarchy() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
RenderNode[] nodes = new RenderNode[30];
- DisplayListCanvas[] canvases = new DisplayListCanvas[nodes.length];
+ RecordingCanvas[] canvases = new RecordingCanvas[nodes.length];
for (int i = 0; i < nodes.length; i++) {
nodes[i] = RenderNode.create("LinearLayout", null);
}
diff --git a/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
index 64f2800ee112..9245c1ba59e4 100644
--- a/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
@@ -18,12 +18,12 @@ package android.text;
import static android.text.Layout.Alignment.ALIGN_NORMAL;
import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.filters.LargeTest;
import android.text.NonEditableTextGenerator.TextType;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import org.junit.Rule;
import org.junit.Test;
@@ -120,7 +120,7 @@ public class BoringLayoutCreateDrawPerfTest {
while (state.keepRunning()) {
state.pauseTiming();
- final DisplayListCanvas canvas = node.start(1200, 200);
+ final RecordingCanvas canvas = node.start(1200, 200);
final int save = canvas.save();
if (!mCached) Canvas.freeTextLayoutCaches();
state.resumeTiming();
diff --git a/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
index ad5a34e44997..a7972f59f382 100644
--- a/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
@@ -17,11 +17,11 @@ package android.text;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.filters.LargeTest;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import org.junit.Rule;
import org.junit.Test;
@@ -107,7 +107,7 @@ public class PaintMeasureDrawPerfTest {
while (state.keepRunning()) {
state.pauseTiming();
- final DisplayListCanvas canvas = node.start(1200, 200);
+ final RecordingCanvas canvas = node.start(1200, 200);
final int save = canvas.save();
if (!mCached) Canvas.freeTextLayoutCaches();
state.resumeTiming();
diff --git a/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java b/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
index d98df059e2d3..00a626750c79 100644
--- a/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
+++ b/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
@@ -16,32 +16,16 @@
package android.text;
-import static android.text.TextDirectionHeuristics.LTR;
-
-import android.perftests.utils.BenchmarkState;
-import android.perftests.utils.PerfStatusReporter;
-
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
-
import android.app.Activity;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.text.Layout;
-import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.nio.CharBuffer;
-import java.util.Random;
import java.util.Locale;
@LargeTest
diff --git a/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java b/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
index 1cd0ae13069b..33b1a47413c8 100644
--- a/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
@@ -16,30 +16,16 @@
package android.text;
-import static android.text.TextDirectionHeuristics.LTR;
-
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
-
import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4;
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.text.Layout;
-import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.nio.CharBuffer;
-import java.util.Random;
-
@LargeTest
@RunWith(AndroidJUnit4.class)
public class PrecomputedTextPerfTest {
diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
index deb2b0a74aaa..b40dd6b9dbb7 100644
--- a/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
@@ -18,12 +18,12 @@ package android.text;
import static android.text.Layout.Alignment.ALIGN_NORMAL;
import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.filters.LargeTest;
import android.text.NonEditableTextGenerator.TextType;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import org.junit.Rule;
import org.junit.Test;
@@ -119,7 +119,7 @@ public class StaticLayoutCreateDrawPerfTest {
while (state.keepRunning()) {
state.pauseTiming();
- final DisplayListCanvas canvas = node.start(1200, 200);
+ final RecordingCanvas canvas = node.start(1200, 200);
int save = canvas.save();
if (!mCached) Canvas.freeTextLayoutCaches();
state.resumeTiming();
diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
index e1a38a0956d7..e224fa39422c 100644
--- a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
@@ -16,30 +16,19 @@
package android.text;
-import static android.text.TextDirectionHeuristics.LTR;
-
+import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
-
import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4;
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.text.Layout;
-import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.nio.CharBuffer;
-import java.util.Random;
-
@LargeTest
@RunWith(AndroidJUnit4.class)
public class StaticLayoutPerfTest {
@@ -256,7 +245,7 @@ public class StaticLayoutPerfTest {
state.pauseTiming();
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
state.resumeTiming();
layout.draw(c);
@@ -272,7 +261,7 @@ public class StaticLayoutPerfTest {
final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
state.resumeTiming();
layout.draw(c);
@@ -288,7 +277,7 @@ public class StaticLayoutPerfTest {
final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
state.resumeTiming();
layout.draw(c);
@@ -304,7 +293,7 @@ public class StaticLayoutPerfTest {
final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
Canvas.freeTextLayoutCaches();
state.resumeTiming();
@@ -321,7 +310,7 @@ public class StaticLayoutPerfTest {
final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
Canvas.freeTextLayoutCaches();
state.resumeTiming();
@@ -339,7 +328,7 @@ public class StaticLayoutPerfTest {
mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
state.resumeTiming();
layout.draw(c);
@@ -356,7 +345,7 @@ public class StaticLayoutPerfTest {
mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
state.resumeTiming();
layout.draw(c);
@@ -373,7 +362,7 @@ public class StaticLayoutPerfTest {
mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
Canvas.freeTextLayoutCaches();
state.resumeTiming();
@@ -391,7 +380,7 @@ public class StaticLayoutPerfTest {
mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
final StaticLayout layout =
StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
- final DisplayListCanvas c = node.start(1200, 200);
+ final RecordingCanvas c = node.start(1200, 200);
Canvas.freeTextLayoutCaches();
state.resumeTiming();
diff --git a/apct-tests/perftests/core/src/android/text/TextPerfUtils.java b/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
index aa505b533f26..22e516abe926 100644
--- a/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
+++ b/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
@@ -16,32 +16,15 @@
package android.text;
-import static android.text.TextDirectionHeuristics.LTR;
-
-import android.perftests.utils.BenchmarkState;
-import android.perftests.utils.PerfStatusReporter;
-
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
-
import android.content.res.ColorStateList;
-import android.graphics.Canvas;
import android.graphics.Typeface;
import android.icu.text.UnicodeSet;
import android.icu.text.UnicodeSetIterator;
-import android.text.Layout;
import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
import java.nio.CharBuffer;
-import java.util.Random;
import java.util.ArrayList;
+import java.util.Random;
public class TextPerfUtils {
diff --git a/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java b/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
index 4bbe4049ba35..25cc7078762a 100644
--- a/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
@@ -19,13 +19,13 @@ import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.UNSPECIFIED;
import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.text.NonEditableTextGenerator.TextType;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import android.widget.TextView;
import org.junit.Rule;
@@ -128,7 +128,7 @@ public class TextViewSetTextMeasurePerfTest {
while (state.keepRunning()) {
state.pauseTiming();
- final DisplayListCanvas canvas = node.start(1200, 200);
+ final RecordingCanvas canvas = node.start(1200, 200);
int save = canvas.save();
textView.setTextLocale(Locale.UK);
textView.setTextLocale(Locale.US);
diff --git a/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java b/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
index dc34b7fe057c..434b8e56dd36 100644
--- a/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
+++ b/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
@@ -16,46 +16,29 @@
package android.widget;
-import static android.view.View.MeasureSpec.AT_MOST;
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.UNSPECIFIED;
+import static android.widget.TextView.UNKNOWN_BORING;
import android.content.Context;
-import android.content.res.ColorStateList;
-import android.graphics.Typeface;
import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4;
-import android.text.PrecomputedText;
-import android.text.Layout;
import android.text.BoringLayout;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
+import android.text.Layout;
+import android.text.PrecomputedText;
import android.text.TextPaint;
-import android.text.style.TextAppearanceSpan;
-import android.view.LayoutInflater;
import android.text.TextPerfUtils;
import android.view.View.MeasureSpec;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
-import com.android.perftests.core.R;
-
-import java.util.Random;
-import java.util.Locale;
import org.junit.Before;
-import org.junit.Test;
import org.junit.Rule;
+import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.assertTrue;
-
-import static android.widget.TextView.UNKNOWN_BORING;
-
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TextViewPrecomputedTextPerfTest {
@@ -360,7 +343,7 @@ public class TextViewPrecomputedTextPerfTest {
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final DisplayListCanvas c = node.start(
+ final RecordingCanvas c = node.start(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
@@ -386,7 +369,7 @@ public class TextViewPrecomputedTextPerfTest {
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final DisplayListCanvas c = node.start(
+ final RecordingCanvas c = node.start(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
@@ -414,7 +397,7 @@ public class TextViewPrecomputedTextPerfTest {
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final DisplayListCanvas c = node.start(
+ final RecordingCanvas c = node.start(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
@@ -443,7 +426,7 @@ public class TextViewPrecomputedTextPerfTest {
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final DisplayListCanvas c = node.start(
+ final RecordingCanvas c = node.start(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
diff --git a/api/current.txt b/api/current.txt
index 1983fb483ecd..1c3ee82dbba0 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -1199,6 +1199,7 @@ package android {
field public static final deprecated int selectedWeekBackgroundColor = 16843586; // 0x1010342
field public static final int sessionService = 16843837; // 0x101043d
field public static final int settingsActivity = 16843301; // 0x1010225
+ field public static final int settingsSliceUri = 16844179; // 0x1010593
field public static final int setupActivity = 16843766; // 0x10103f6
field public static final int shadowColor = 16843105; // 0x1010161
field public static final int shadowDx = 16843106; // 0x1010162
@@ -5676,6 +5677,7 @@ package android.app {
method public java.lang.CharSequence getName();
method public android.net.Uri getSound();
method public long[] getVibrationPattern();
+ method public boolean hasUserSetImportance();
method public void setBypassDnd(boolean);
method public void setDescription(java.lang.String);
method public void setGroup(java.lang.String);
@@ -6320,6 +6322,7 @@ package android.app {
method public android.content.pm.ServiceInfo getServiceInfo();
method public java.lang.String getServiceName();
method public java.lang.String getSettingsActivity();
+ method public android.net.Uri getSettingsSliceUri();
method public boolean getShowMetadataInPreview();
method public java.lang.CharSequence loadAuthor(android.content.pm.PackageManager) throws android.content.res.Resources.NotFoundException;
method public java.lang.CharSequence loadContextDescription(android.content.pm.PackageManager) throws android.content.res.Resources.NotFoundException;
@@ -15316,20 +15319,9 @@ package android.graphics.fonts {
method public java.nio.ByteBuffer getBuffer();
method public java.io.File getFile();
method public android.os.LocaleList getLocaleList();
+ method public int getSlant();
method public int getTtcIndex();
method public int getWeight();
- method public boolean isItalic();
- field public static final int FONT_WEIGHT_BLACK = 900; // 0x384
- field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
- field public static final int FONT_WEIGHT_EXTRA_BOLD = 800; // 0x320
- field public static final int FONT_WEIGHT_EXTRA_LIGHT = 200; // 0xc8
- field public static final int FONT_WEIGHT_LIGHT = 300; // 0x12c
- field public static final int FONT_WEIGHT_MAX = 1000; // 0x3e8
- field public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
- field public static final int FONT_WEIGHT_MIN = 1; // 0x1
- field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
- field public static final int FONT_WEIGHT_SEMI_BOLD = 600; // 0x258
- field public static final int FONT_WEIGHT_THIN = 100; // 0x64
}
public static class Font.Builder {
@@ -15342,7 +15334,7 @@ package android.graphics.fonts {
method public android.graphics.fonts.Font build() throws java.io.IOException;
method public android.graphics.fonts.Font.Builder setFontVariationSettings(java.lang.String);
method public android.graphics.fonts.Font.Builder setFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
- method public android.graphics.fonts.Font.Builder setItalic(boolean);
+ method public android.graphics.fonts.Font.Builder setSlant(int);
method public android.graphics.fonts.Font.Builder setTtcIndex(int);
method public android.graphics.fonts.Font.Builder setWeight(int);
}
@@ -15358,6 +15350,26 @@ package android.graphics.fonts {
method public android.graphics.fonts.FontFamily build();
}
+ public final class FontStyle {
+ ctor public FontStyle();
+ ctor public FontStyle(int, int);
+ method public int getSlant();
+ method public int getWeight();
+ field public static final int FONT_SLANT_ITALIC = 1; // 0x1
+ field public static final int FONT_SLANT_UPRIGHT = 0; // 0x0
+ field public static final int FONT_WEIGHT_BLACK = 900; // 0x384
+ field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+ field public static final int FONT_WEIGHT_EXTRA_BOLD = 800; // 0x320
+ field public static final int FONT_WEIGHT_EXTRA_LIGHT = 200; // 0xc8
+ field public static final int FONT_WEIGHT_LIGHT = 300; // 0x12c
+ field public static final int FONT_WEIGHT_MAX = 1000; // 0x3e8
+ field public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+ field public static final int FONT_WEIGHT_MIN = 1; // 0x1
+ field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+ field public static final int FONT_WEIGHT_SEMI_BOLD = 600; // 0x258
+ field public static final int FONT_WEIGHT_THIN = 100; // 0x64
+ }
+
public final class FontVariationAxis {
ctor public FontVariationAxis(java.lang.String, float);
method public static android.graphics.fonts.FontVariationAxis[] fromFontVariationSettings(java.lang.String);
@@ -29733,9 +29745,11 @@ package android.opengl {
public class EGL15 {
ctor public EGL15();
method public static int eglClientWaitSync(android.opengl.EGLDisplay, android.opengl.EGLSync, int, long);
+ method public static android.opengl.EGLImage eglCreateImage(android.opengl.EGLDisplay, android.opengl.EGLContext, int, long, long[], int);
method public static android.opengl.EGLSurface eglCreatePlatformPixmapSurface(android.opengl.EGLDisplay, android.opengl.EGLConfig, java.nio.Buffer, long[], int);
method public static android.opengl.EGLSurface eglCreatePlatformWindowSurface(android.opengl.EGLDisplay, android.opengl.EGLConfig, java.nio.Buffer, long[], int);
method public static android.opengl.EGLSync eglCreateSync(android.opengl.EGLDisplay, int, long[], int);
+ method public static boolean eglDestroyImage(android.opengl.EGLDisplay, android.opengl.EGLImage);
method public static boolean eglDestroySync(android.opengl.EGLDisplay, android.opengl.EGLSync);
method public static android.opengl.EGLDisplay eglGetPlatformDisplay(int, long, long[], int);
method public static boolean eglGetSyncAttrib(android.opengl.EGLDisplay, android.opengl.EGLSync, int, long[], int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 26036ea9c281..7e510827b6ff 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -987,6 +987,7 @@ package android.content {
field public static final java.lang.String ACTION_PRE_BOOT_COMPLETED = "android.intent.action.PRE_BOOT_COMPLETED";
field public static final java.lang.String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART";
field public static final java.lang.String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE";
+ field public static final java.lang.String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE";
field public static final java.lang.String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS";
field public static final java.lang.String ACTION_SHOW_SUSPENDED_APP_DETAILS = "android.intent.action.SHOW_SUSPENDED_APP_DETAILS";
field public static final deprecated java.lang.String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index c04e61b77274..41d546f6d603 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -174,6 +174,8 @@ public class Am extends BaseCommand {
instrument.noWindowAnimation = true;
} else if (opt.equals("--no-hidden-api-checks")) {
instrument.disableHiddenApiChecks = true;
+ } else if (opt.equals("--no-isolated-storage")) {
+ instrument.disableIsolatedStorage = true;
} else if (opt.equals("--user")) {
instrument.userId = parseUserArg(nextArgRequired());
} else if (opt.equals("--abi")) {
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 0dade0b2ba81..70baa8702ba9 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -16,6 +16,9 @@
package com.android.commands.am;
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
+
import android.app.IActivityManager;
import android.app.IInstrumentationWatcher;
import android.app.Instrumentation;
@@ -74,16 +77,13 @@ public class Instrument {
String logPath = null;
public boolean noWindowAnimation = false;
public boolean disableHiddenApiChecks = false;
+ public boolean disableIsolatedStorage = false;
public String abi = null;
public int userId = UserHandle.USER_CURRENT;
public Bundle args = new Bundle();
// Required
public String componentNameArg;
- // Disable hidden API checks for the newly started instrumentation.
- // Must be kept in sync with ActivityManagerService.
- private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
-
/**
* Construct the instrument command runner.
*/
@@ -480,7 +480,13 @@ public class Instrument {
}
// Start the instrumentation
- int flags = disableHiddenApiChecks ? INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS : 0;
+ int flags = 0;
+ if (disableHiddenApiChecks) {
+ flags |= INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+ }
+ if (disableIsolatedStorage) {
+ flags |= INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
+ }
if (!mAm.startInstrumentation(cn, profileFile, flags, args, watcher, connection, userId,
abi)) {
throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
diff --git a/cmds/incidentd/Android.mk b/cmds/incidentd/Android.mk
index db864aed6bdc..eba558653b04 100644
--- a/cmds/incidentd/Android.mk
+++ b/cmds/incidentd/Android.mk
@@ -33,6 +33,9 @@ LOCAL_SRC_FILES := $(call all-cpp-files-under, src) \
LOCAL_CFLAGS += \
-Wall -Werror -Wno-missing-field-initializers -Wno-unused-variable -Wunused-parameter
+# Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed.
+LOCAL_CFLAGS += -Wno-error=implicit-fallthrough
+
ifeq (debug,)
LOCAL_CFLAGS += \
-g -O0
@@ -100,6 +103,9 @@ LOCAL_MODULE_TAGS := tests
LOCAL_CFLAGS := -Werror -Wall -Wno-unused-variable -Wunused-parameter
+# Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed.
+LOCAL_CFLAGS += -Wno-error=implicit-fallthrough
+
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_SRC_FILES := $(call all-cpp-files-under, tests) \
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 39d24ee2fe6c..7f6e41c1092f 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -144,6 +144,7 @@ message Atom {
PhoneServiceStateChanged phone_service_state_changed = 94;
PhoneStateChanged phone_state_changed = 95;
UserRestrictionChanged user_restriction_changed = 96;
+ SettingsUIChanged settings_ui_changed = 97;
}
// Pulled events will start at field 10000.
@@ -184,7 +185,6 @@ message Atom {
DiskIo disk_io = 10032;
PowerProfile power_profile = 10033;
ProcStats proc_stats_pkg_proc = 10034;
- ProcessCpuTime process_cpu_time = 10035;
NativeProcessMemoryState native_process_memory_state = 10036;
}
@@ -1438,6 +1438,79 @@ message PhoneStateChanged {
}
/**
+ * Logs when Settings UI has changed.
+ *
+ * Logged from:
+ * packages/apps/Settings
+ */
+message SettingsUIChanged {
+ /**
+ * The action performed in this event
+ */
+ enum Action {
+ ACTION_UNKNOWN = 0;
+ PAGE_VISIBLE = 1;
+ PAGE_HIDE = 2;
+ PREF_CHANGE = 3;
+ }
+
+ /**
+ * Id for Settings pages. Each page must have its own unique Id.
+ */
+ enum PageId {
+ // Unknown page. Should not be used in production code.
+ PAGE_UNKNOWN = 0;
+
+ // OPEN: Settings homepage
+ SETTINGS_HOMEPAGE = 1502;
+
+ // OPEN: Settings > System > Input & Gesture > Wake screen
+ SETTINGS_GESTURE_WAKE_SCREEN = 1570;
+
+ // OPEN: Settings > Network & internet > Mobile network
+ MOBILE_NETWORK = 1571;
+
+ // OPEN: Settings > Network & internet > Mobile network > Choose network
+ MOBILE_NETWORK_SELECT = 1581;
+
+ // OPEN: Settings > Network & internet > Mobile network > Mobile Data > Dialog
+ MOBILE_DATA_DIALOG = 1582;
+
+ // OPEN: Settings > Network & internet > Mobile network > Data roaming > Dialog
+ MOBILE_ROAMING_DIALOG = 1583;
+
+ // Settings > Display > Lock screen display > On lock screen
+ LOCK_SCREEN_NOTIFICATION_CONTENT = 1584;
+ }
+
+ /**
+ * Where this SettingsUIChange event comes from. For example, if
+ * it's a PAGE_VISIBLE event, where the page is opened from.
+ */
+ optional PageId attribution = 1;
+
+ /**
+ * What the UI action is.
+ */
+ optional Action action = 2;
+
+ /**
+ * Where the action is happening
+ */
+ optional PageId pageId = 3;
+
+ /**
+ * What preference changed in this event.
+ */
+ optional string changedPreferenceKey = 4;
+
+ /**
+ * The new value of the changed preference.
+ */
+ optional int64 changedPreferenceIntValue = 5;
+}
+
+/**
* Logs that a setting was updated.
* Logged from:
* frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -3036,22 +3109,6 @@ message PowerProfile {
}
/**
- * Pulls process user time and system time. Puller takes a snapshot of all pids
- * in the system and returns cpu stats for those that are working at the time.
- * Dead pids will be dropped. Kernel processes are excluded.
- * Min cool-down is 5 sec.
- */
-message ProcessCpuTime {
- optional int32 uid = 1 [(is_uid) = true];
-
- optional string process_name = 2;
- // Process cpu time in user space, cumulative from boot/process start
- optional int64 user_time_millis = 3;
- // Process cpu time in system space, cumulative from boot/process start
- optional int64 system_time_millis = 4;
-}
-
-/**
* Logs when a user restriction was added or removed.
*
* Logged from:
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 8871d4d054c5..1a9ba8a8de17 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -229,9 +229,6 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
// PowerProfile constants for power model calculations.
{android::util::POWER_PROFILE,
{{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::POWER_PROFILE)}},
- // Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses.
- {android::util::PROCESS_CPU_TIME,
- {{}, {}, 5 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}},
};
StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 1a8a32ec574f..95bcf0ecf132 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -3227,7 +3227,7 @@ android.view.DisplayCutout$ParcelableWrapper$1
android.view.DisplayEventReceiver
android.view.DisplayInfo
android.view.DisplayInfo$1
-android.view.DisplayListCanvas
+android.graphics.RecordingCanvas
android.view.FallbackEventHandler
android.view.FocusFinder
android.view.FocusFinder$1
@@ -3305,8 +3305,8 @@ android.view.OrientationEventListener
android.view.OrientationEventListener$SensorEventListenerImpl
android.view.PointerIcon
android.view.PointerIcon$1
-android.view.RenderNode
-android.view.RenderNode$NoImagePreloadHolder
+android.graphics.RenderNode
+android.graphics.RenderNode$NoImagePreloadHolder
android.view.RenderNodeAnimator
android.view.RenderNodeAnimator$1
android.view.RenderNodeAnimatorSetHelper
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 14b8ae45d989..7330da323f47 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -137,6 +137,17 @@ public class ActivityManager {
private static final int FIRST_START_NON_FATAL_ERROR_CODE = 100;
private static final int LAST_START_NON_FATAL_ERROR_CODE = 199;
+ /**
+ * Disable hidden API checks for the newly started instrumentation.
+ * @hide
+ */
+ public static final int INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
+ /**
+ * Mount full external storage for the newly started instrumentation.
+ * @hide
+ */
+ public static final int INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL = 1 << 1;
+
static final class UidObserver extends IUidObserver.Stub {
final OnUidImportanceListener mListener;
final Context mContext;
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 848def63177e..9f93e1765da3 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -603,9 +603,10 @@ public final class NotificationChannel implements Parcelable {
}
/**
- * @hide
+ * Returns whether the user has chosen the importance of this channel, either to affirm the
+ * initial selection from the app, or changed it to be higher or lower.
*/
- public boolean isImportanceLocked() {
+ public boolean hasUserSetImportance() {
return (mUserLockedFields & USER_LOCKED_IMPORTANCE) != 0;
}
diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java
index 9873a8152b3f..e33d1fed4b4c 100644
--- a/core/java/android/app/WallpaperInfo.java
+++ b/core/java/android/app/WallpaperInfo.java
@@ -16,6 +16,7 @@
package android.app;
+import android.app.slice.Slice;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -77,6 +78,7 @@ public final class WallpaperInfo implements Parcelable {
final int mContextDescriptionResource;
final boolean mShowMetadataInPreview;
final boolean mSupportsAmbientMode;
+ final String mSettingsSliceUri;
/**
* Constructor.
@@ -118,7 +120,6 @@ public final class WallpaperInfo implements Parcelable {
com.android.internal.R.styleable.Wallpaper);
mSettingsActivityName = sa.getString(
com.android.internal.R.styleable.Wallpaper_settingsActivity);
-
mThumbnailResource = sa.getResourceId(
com.android.internal.R.styleable.Wallpaper_thumbnail,
-1);
@@ -140,6 +141,8 @@ public final class WallpaperInfo implements Parcelable {
mSupportsAmbientMode = sa.getBoolean(
com.android.internal.R.styleable.Wallpaper_supportsAmbientMode,
false);
+ mSettingsSliceUri = sa.getString(
+ com.android.internal.R.styleable.Wallpaper_settingsSliceUri);
sa.recycle();
} catch (NameNotFoundException e) {
@@ -159,6 +162,7 @@ public final class WallpaperInfo implements Parcelable {
mContextDescriptionResource = source.readInt();
mShowMetadataInPreview = source.readInt() != 0;
mSupportsAmbientMode = source.readInt() != 0;
+ mSettingsSliceUri = source.readString();
mService = ResolveInfo.CREATOR.createFromParcel(source);
}
@@ -332,13 +336,28 @@ public final class WallpaperInfo implements Parcelable {
* explicit {@link android.content.ComponentName}
* composed of {@link #getPackageName} and the class name returned here.
*
- * <p>A null will be returned if there is no settings activity associated
+ * <p>{@code null} will be returned if there is no settings activity associated
* with the wallpaper.
*/
public String getSettingsActivity() {
return mSettingsActivityName;
}
+ /**
+ * Returns an URI that provides a settings {@link Slice} for this wallpaper.
+ *
+ * <p>{@code null} will be returned if there is no settings Slice URI associated
+ * with the wallpaper.
+ *
+ * @return The URI.
+ */
+ public Uri getSettingsSliceUri() {
+ if (mSettingsSliceUri == null) {
+ return null;
+ }
+ return Uri.parse(mSettingsSliceUri);
+ }
+
public void dump(Printer pw, String prefix) {
pw.println(prefix + "Service:");
mService.dump(pw, prefix + " ");
@@ -367,6 +386,7 @@ public final class WallpaperInfo implements Parcelable {
dest.writeInt(mContextDescriptionResource);
dest.writeInt(mShowMetadataInPreview ? 1 : 0);
dest.writeInt(mSupportsAmbientMode ? 1 : 0);
+ dest.writeString(mSettingsSliceUri);
mService.writeToParcel(dest, flags);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c0463e9ae7af..ea1a2fe758af 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1908,6 +1908,22 @@ public class Intent implements Parcelable, Cloneable {
@SystemApi
public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
+ /**
+ * Activity action: Launch UI to review app uses of permissions.
+ * <p>
+ * Input: Nothing
+ * </p>
+ * <p>
+ * Output: Nothing.
+ * </p>
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_REVIEW_PERMISSION_USAGE =
+ "android.intent.action.REVIEW_PERMISSION_USAGE";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent broadcast actions (see action variable).
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 0982d65ee4c9..843db6d28d30 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -41,8 +41,7 @@ import com.android.internal.view.IInputMethodSession;
class IInputMethodSessionWrapper extends IInputMethodSession.Stub
implements HandlerCaller.Callback {
private static final String TAG = "InputMethodWrapper";
-
- private static final int DO_FINISH_INPUT = 60;
+
private static final int DO_DISPLAY_COMPLETIONS = 65;
private static final int DO_UPDATE_EXTRACTED_TEXT = 67;
private static final int DO_UPDATE_SELECTION = 90;
@@ -89,9 +88,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
}
switch (msg.what) {
- case DO_FINISH_INPUT:
- mInputMethodSession.finishInput();
- return;
case DO_DISPLAY_COMPLETIONS:
mInputMethodSession.displayCompletions((CompletionInfo[])msg.obj);
return;
@@ -150,11 +146,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
}
@Override
- public void finishInput() {
- mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_INPUT));
- }
-
- @Override
public void displayCompletions(CompletionInfo[] completions) {
mCaller.executeOrSendMessage(mCaller.obtainMessageO(
DO_DISPLAY_COMPLETIONS, completions));
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 8ea061e4a8d0..e0b2c7853eba 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -557,6 +557,7 @@ public final class PowerManager {
ServiceType.FORCE_ALL_APPS_STANDBY,
ServiceType.OPTIONAL_SENSORS,
ServiceType.AOD,
+ ServiceType.QUICK_DOZE,
})
public @interface ServiceType {
int NULL = 0;
@@ -586,6 +587,11 @@ public final class PowerManager {
* Whether to disable non-essential sensors. (e.g. edge sensors.)
*/
int OPTIONAL_SENSORS = 13;
+
+ /**
+ * Whether to go into Deep Doze as soon as the screen turns off or not.
+ */
+ int QUICK_DOZE = 15;
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ad640219a6a5..80e8f78ec92b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10907,6 +10907,7 @@ public final class Settings {
* idle_pending_to (long)
* max_idle_pending_to (long)
* idle_pending_factor (float)
+ * quick_doze_delay_to (long)
* idle_to (long)
* max_idle_to (long)
* idle_factor (float)
@@ -10940,6 +10941,11 @@ public final class Settings {
* gps_mode (int)
* adjust_brightness_disabled (boolean)
* adjust_brightness_factor (float)
+ * force_all_apps_standby (boolean)
+ * force_background_check (boolean)
+ * optional_sensors_disabled (boolean)
+ * aod_disabled (boolean)
+ * quick_doze_enabled (boolean)
* </pre>
* @hide
* @see com.android.server.power.BatterySaverPolicy
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index d7fe15d0e925..b8e03876a836 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -737,7 +737,8 @@ public abstract class NotificationListenerService extends Service {
* <p>This method will throw a security exception if you don't have access to notifications
* for the given user.</p>
* <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
- * device} in order to use this method.
+ * device} or be the {@link NotificationAssistantService notification assistant} in order to
+ * use this method.
*
* @param pkg The package to retrieve channels for.
*/
@@ -760,7 +761,8 @@ public abstract class NotificationListenerService extends Service {
* <p>This method will throw a security exception if you don't have access to notifications
* for the given user.</p>
* <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
- * device} in order to use this method.
+ * device} or be the {@link NotificationAssistantService notification assistant} in order to
+ * use this method.
*
* @param pkg The package to retrieve channel groups for.
*/
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 0808cdd6aedb..3ab8a0a8885f 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1806,6 +1806,7 @@ public abstract class Layout {
}
}
+
/**
* Fills in the specified Path with a representation of a cursor
* at the specified offset. This will often be a vertical line
@@ -1821,7 +1822,6 @@ public abstract class Layout {
boolean clamped = shouldClampCursor(line);
float h1 = getPrimaryHorizontal(point, clamped) - 0.5f;
- float h2 = isLevelBoundary(point) ? getSecondaryHorizontal(point, clamped) - 0.5f : h1;
int caps = TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SHIFT_ON) |
TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SELECTING);
@@ -1839,34 +1839,24 @@ public abstract class Layout {
if (h1 < 0.5f)
h1 = 0.5f;
- if (h2 < 0.5f)
- h2 = 0.5f;
- if (Float.compare(h1, h2) == 0) {
- dest.moveTo(h1, top);
- dest.lineTo(h1, bottom);
- } else {
- dest.moveTo(h1, top);
- dest.lineTo(h1, (top + bottom) >> 1);
-
- dest.moveTo(h2, (top + bottom) >> 1);
- dest.lineTo(h2, bottom);
- }
+ dest.moveTo(h1, top);
+ dest.lineTo(h1, bottom);
if (caps == 2) {
- dest.moveTo(h2, bottom);
- dest.lineTo(h2 - dist, bottom + dist);
- dest.lineTo(h2, bottom);
- dest.lineTo(h2 + dist, bottom + dist);
+ dest.moveTo(h1, bottom);
+ dest.lineTo(h1 - dist, bottom + dist);
+ dest.lineTo(h1, bottom);
+ dest.lineTo(h1 + dist, bottom + dist);
} else if (caps == 1) {
- dest.moveTo(h2, bottom);
- dest.lineTo(h2 - dist, bottom + dist);
+ dest.moveTo(h1, bottom);
+ dest.lineTo(h1 - dist, bottom + dist);
- dest.moveTo(h2 - dist, bottom + dist - 0.5f);
- dest.lineTo(h2 + dist, bottom + dist - 0.5f);
+ dest.moveTo(h1 - dist, bottom + dist - 0.5f);
+ dest.lineTo(h1 + dist, bottom + dist - 0.5f);
- dest.moveTo(h2 + dist, bottom + dist);
- dest.lineTo(h2, bottom);
+ dest.moveTo(h1 + dist, bottom + dist);
+ dest.lineTo(h1, bottom);
}
if (fn == 2) {
diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java
index f846a356d8fa..23557694a48d 100644
--- a/core/java/android/text/style/TextAppearanceSpan.java
+++ b/core/java/android/text/style/TextAppearanceSpan.java
@@ -22,7 +22,7 @@ import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.LeakyTypefaceStorage;
import android.graphics.Typeface;
-import android.graphics.fonts.Font;
+import android.graphics.fonts.FontStyle;
import android.os.LocaleList;
import android.os.Parcel;
import android.text.ParcelableSpan;
@@ -490,7 +490,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
if (styledTypeface != null) {
final Typeface readyTypeface;
if (mTextFontWeight >= 0) {
- final int weight = Math.min(Font.FONT_WEIGHT_MAX, mTextFontWeight);
+ final int weight = Math.min(FontStyle.FONT_WEIGHT_MAX, mTextFontWeight);
final boolean italic = (style & Typeface.ITALIC) != 0;
readyTypeface = ds.setTypeface(Typeface.create(styledTypeface, weight, italic));
} else {
diff --git a/core/java/android/view/GhostView.java b/core/java/android/view/GhostView.java
index fa7b067deb20..98ed21735e62 100644
--- a/core/java/android/view/GhostView.java
+++ b/core/java/android/view/GhostView.java
@@ -18,6 +18,8 @@ package android.view;
import android.annotation.UnsupportedAppUsage;
import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.widget.FrameLayout;
import java.util.ArrayList;
@@ -46,8 +48,8 @@ public class GhostView extends View {
@Override
protected void onDraw(Canvas canvas) {
- if (canvas instanceof DisplayListCanvas) {
- DisplayListCanvas dlCanvas = (DisplayListCanvas) canvas;
+ if (canvas instanceof RecordingCanvas) {
+ RecordingCanvas dlCanvas = (RecordingCanvas) canvas;
mView.mRecreateDisplayList = true;
RenderNode renderNode = mView.updateDisplayListIfDirty();
if (renderNode.isValid()) {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 3e559d9e106f..0c3a2957e1bc 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -226,25 +226,50 @@ interface IWindowManager
int getPreferredOptionsPanelGravity(int displayId);
/**
- * Lock the device orientation to the specified rotation, or to the
- * current rotation if -1. Sensor input will be ignored until
- * thawRotation() is called.
- * @hide
+ * Equivalent to calling {@link #freezeDisplayRotation(int, int)} with {@link
+ * android.view.Display#DEFAULT_DISPLAY} and given rotation.
*/
void freezeRotation(int rotation);
/**
- * Release the orientation lock imposed by freezeRotation().
- * @hide
+ * Equivalent to calling {@link #thawDisplayRotation(int)} with {@link
+ * android.view.Display#DEFAULT_DISPLAY}.
*/
void thawRotation();
/**
- * Gets whether the rotation is frozen.
+ * Equivelant to call {@link #isDisplayRotationFrozen(int)} with {@link
+ * android.view.Display#DEFAULT_DISPLAY}.
+ */
+ boolean isRotationFrozen();
+
+ /**
+ * Lock the display orientation to the specified rotation, or to the current
+ * rotation if -1. Sensor input will be ignored until thawRotation() is called.
*
+ * @param displayId the ID of display which rotation should be frozen.
+ * @param rotation one of {@link android.view.Surface#ROTATION_0},
+ * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
+ * {@link android.view.Surface#ROTATION_270} or -1 to freeze it to current rotation.
+ * @hide
+ */
+ void freezeDisplayRotation(int displayId, int rotation);
+
+ /**
+ * Release the orientation lock imposed by freezeRotation() on the display.
+ *
+ * @param displayId the ID of display which rotation should be thawed.
+ * @hide
+ */
+ void thawDisplayRotation(int displayId);
+
+ /**
+ * Gets whether the rotation is frozen on the display.
+ *
+ * @param displayId the ID of display which frozen is needed.
* @return Whether the rotation is frozen.
*/
- boolean isRotationFrozen();
+ boolean isDisplayRotationFrozen(int displayId);
/**
* Screenshot the current wallpaper layer, including the whole screen.
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index e48bcfdb7203..9d31bd16b452 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -22,6 +22,8 @@ import android.animation.ValueAnimator;
import android.annotation.UnsupportedAppUsage;
import android.graphics.CanvasProperty;
import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import android.util.SparseIntArray;
import com.android.internal.util.VirtualRefBasePtr;
@@ -286,8 +288,8 @@ public class RenderNodeAnimator extends Animator {
setTarget(mViewTarget.mRenderNode);
}
- /** Sets the animation target to the owning view of the DisplayListCanvas */
- public void setTarget(DisplayListCanvas canvas) {
+ /** Sets the animation target to the owning view of the RecordingCanvas */
+ public void setTarget(RecordingCanvas canvas) {
setTarget(canvas.mNode);
}
@@ -405,7 +407,7 @@ public class RenderNodeAnimator extends Animator {
return listeners;
}
- long getNativeAnimator() {
+ public long getNativeAnimator() {
return mNativePtr.get();
}
diff --git a/core/java/android/view/RenderNodeAnimatorSetHelper.java b/core/java/android/view/RenderNodeAnimatorSetHelper.java
index e1ef05941394..d222e0739fa2 100644
--- a/core/java/android/view/RenderNodeAnimatorSetHelper.java
+++ b/core/java/android/view/RenderNodeAnimatorSetHelper.java
@@ -16,6 +16,8 @@
package android.view;
import android.animation.TimeInterpolator;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
import com.android.internal.view.animation.FallbackLUTInterpolator;
import com.android.internal.view.animation.NativeInterpolatorFactory;
@@ -29,10 +31,12 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
*/
public class RenderNodeAnimatorSetHelper {
- public static RenderNode getTarget(DisplayListCanvas recordingCanvas) {
+ /** checkstyle @hide */
+ public static RenderNode getTarget(RecordingCanvas recordingCanvas) {
return recordingCanvas.mNode;
}
+ /** checkstyle @hide */
public static long createNativeInterpolator(TimeInterpolator interpolator, long
duration) {
if (interpolator == null) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 6fb1bbabddc2..f17a45800aeb 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -22,7 +22,9 @@ import android.content.res.CompatibilityInfo.Translator;
import android.graphics.Canvas;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RenderNode;
import android.graphics.SurfaceTexture;
import android.os.Parcel;
import android.os.Parcelable;
@@ -889,7 +891,7 @@ public class Surface implements Parcelable {
private final class HwuiContext {
private final RenderNode mRenderNode;
private long mHwuiRenderer;
- private DisplayListCanvas mCanvas;
+ private RecordingCanvas mCanvas;
private final boolean mIsWideColorGamut;
HwuiContext(boolean isWideColorGamut) {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index e71182c33c12..67f9399e678a 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -30,6 +30,7 @@ import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.RenderNode;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
diff --git a/core/java/android/view/TextureLayer.java b/core/java/android/view/TextureLayer.java
index 35a886fa27a3..d89d634c6a25 100644
--- a/core/java/android/view/TextureLayer.java
+++ b/core/java/android/view/TextureLayer.java
@@ -31,7 +31,7 @@ import com.android.internal.util.VirtualRefBasePtr;
*
* @hide
*/
-final class TextureLayer {
+public final class TextureLayer {
private ThreadedRenderer mRenderer;
private VirtualRefBasePtr mFinalizer;
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 997e48fe61ac..0175ba201dd1 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -23,6 +23,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.Drawable;
@@ -343,7 +344,7 @@ public class TextureView extends View {
properties (alpha, layer paint) affect all of the content of a TextureView. */
if (canvas.isHardwareAccelerated()) {
- DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
+ RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
TextureLayer layer = getTextureLayer();
if (layer != null) {
@@ -351,7 +352,7 @@ public class TextureView extends View {
applyTransformMatrix();
mLayer.setLayerPaint(mLayerPaint); // ensure layer paint is up to date
- displayListCanvas.drawTextureLayer(layer);
+ recordingCanvas.drawTextureLayer(layer);
}
}
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 42690cef9da3..c1ab4d4b895e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -24,7 +24,9 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Point;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RenderNode;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -693,7 +695,7 @@ public final class ThreadedRenderer {
updateViewTreeDisplayList(view);
if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
- DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
+ RecordingCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
try {
final int saveCount = canvas.save();
canvas.translate(mInsetLeft, mInsetTop);
@@ -770,7 +772,7 @@ public final class ThreadedRenderer {
*
* @param canvas The Canvas used to render the view.
*/
- void onPreDraw(DisplayListCanvas canvas);
+ void onPreDraw(RecordingCanvas canvas);
/**
* Invoked after a view is drawn by a threaded renderer.
@@ -778,7 +780,7 @@ public final class ThreadedRenderer {
*
* @param canvas The Canvas used to render the view.
*/
- void onPostDraw(DisplayListCanvas canvas);
+ void onPostDraw(RecordingCanvas canvas);
}
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cc58b8928f6e..c82918249531 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -57,9 +57,11 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
+import android.graphics.RenderNode;
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -19233,7 +19235,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int height = mBottom - mTop;
int layerType = getLayerType();
- final DisplayListCanvas canvas = renderNode.start(width, height);
+ final RecordingCanvas canvas = renderNode.start(width, height);
try {
if (layerType == LAYER_TYPE_SOFTWARE) {
@@ -20250,7 +20252,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (!drawingWithDrawingCache) {
if (drawingWithRenderNode) {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
- ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
+ ((RecordingCanvas) canvas).drawRenderNode(renderNode);
} else {
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
@@ -20581,7 +20583,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final RenderNode renderNode = mBackgroundRenderNode;
if (renderNode != null && renderNode.isValid()) {
setBackgroundRenderNodeProperties(renderNode);
- ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
+ ((RecordingCanvas) canvas).drawRenderNode(renderNode);
return;
}
}
@@ -20633,7 +20635,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final Rect bounds = drawable.getBounds();
final int width = bounds.width();
final int height = bounds.height();
- final DisplayListCanvas canvas = renderNode.start(width, height);
+ final RecordingCanvas canvas = renderNode.start(width, height);
// Reverse left/top translation done by drawable canvas, which will
// instead be applied by rendernode's LTRB bounds below. This way, the
diff --git a/core/java/android/view/ViewAnimationHostBridge.java b/core/java/android/view/ViewAnimationHostBridge.java
index 58f555dfa305..e0fae21bbdf6 100644
--- a/core/java/android/view/ViewAnimationHostBridge.java
+++ b/core/java/android/view/ViewAnimationHostBridge.java
@@ -16,6 +16,8 @@
package android.view;
+import android.graphics.RenderNode;
+
/**
* Maps a View to a RenderNode's AnimationHost
*
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 8dd03476a2b8..292e933c3f7e 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -23,7 +23,9 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Picture;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RenderNode;
import android.os.Debug;
import android.os.Handler;
import android.os.RemoteException;
@@ -601,7 +603,7 @@ public class ViewDebug {
}
if (view.isHardwareAccelerated()) {
- DisplayListCanvas canvas = node.start(dm.widthPixels, dm.heightPixels);
+ RecordingCanvas canvas = node.start(dm.widthPixels, dm.heightPixels);
try {
return profileViewOperation(view, () -> view.draw(canvas));
} finally {
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index e3e2069422fc..a0ab362f3985 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -19,6 +19,7 @@ package android.view;
import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
+import android.graphics.RenderNode;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bef8e8fedfdf..7da31ebe4a17 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -51,8 +51,10 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.RenderNode;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
@@ -3120,7 +3122,7 @@ public final class ViewRootImpl implements ViewParent,
int mHardwareYOffset;
@Override
- public void onPreDraw(DisplayListCanvas canvas) {
+ public void onPreDraw(RecordingCanvas canvas) {
// If mCurScrollY is not 0 then this influences the hardwareYOffset. The end result is we
// can apply offsets that are not handled by anything else, resulting in underdraw as
// the View is shifted (thus shifting the window background) exposing unpainted
@@ -3134,7 +3136,7 @@ public final class ViewRootImpl implements ViewParent,
}
@Override
- public void onPostDraw(DisplayListCanvas canvas) {
+ public void onPostDraw(RecordingCanvas canvas) {
drawAccessibilityFocusedDrawableIfNeeded(canvas);
if (mUseMTRenderer) {
for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/WindowCallbacks.java b/core/java/android/view/WindowCallbacks.java
index b2dc1e91bdf7..a99730205136 100644
--- a/core/java/android/view/WindowCallbacks.java
+++ b/core/java/android/view/WindowCallbacks.java
@@ -16,6 +16,7 @@
package android.view;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
/**
@@ -82,5 +83,5 @@ public interface WindowCallbacks {
*
* @param canvas The canvas to draw on.
*/
- void onPostDraw(DisplayListCanvas canvas);
+ void onPostDraw(RecordingCanvas canvas);
}
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index ba665713fb21..6ab7f66aedd3 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -27,11 +27,11 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.Trace;
import android.util.SparseArray;
-import android.view.DisplayListCanvas;
import android.view.View;
import android.view.ViewRootImpl;
@@ -107,12 +107,12 @@ public final class WebViewDelegate {
* @throws IllegalArgumentException if the canvas is not hardware accelerated
*/
public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) {
- if (!(canvas instanceof DisplayListCanvas)) {
+ if (!(canvas instanceof RecordingCanvas)) {
// Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
throw new IllegalArgumentException(canvas.getClass().getName()
+ " is not a DisplayList canvas");
}
- ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, null);
+ ((RecordingCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, null);
}
/**
@@ -129,12 +129,12 @@ public final class WebViewDelegate {
*/
public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor,
@Nullable Runnable releasedRunnable) {
- if (!(canvas instanceof DisplayListCanvas)) {
+ if (!(canvas instanceof RecordingCanvas)) {
// Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
throw new IllegalArgumentException(canvas.getClass().getName()
+ " is not a DisplayList canvas");
}
- ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable);
+ ((RecordingCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable);
}
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 8027dd7cdb10..48c164f726bc 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -42,8 +42,10 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.RenderNode;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -83,7 +85,6 @@ import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.ContextMenu;
import android.view.ContextThemeWrapper;
-import android.view.DisplayListCanvas;
import android.view.DragAndDropPermissions;
import android.view.DragEvent;
import android.view.Gravity;
@@ -93,7 +94,6 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
-import android.view.RenderNode;
import android.view.SubMenu;
import android.view.View;
import android.view.View.DragShadowBuilder;
@@ -1941,18 +1941,18 @@ public class Editor {
// Rebuild display list if it is invalid
if (blockDisplayListIsInvalid) {
- final DisplayListCanvas displayListCanvas = blockDisplayList.start(
+ final RecordingCanvas recordingCanvas = blockDisplayList.start(
right - left, bottom - top);
try {
// drawText is always relative to TextView's origin, this translation
// brings this range of text back to the top left corner of the viewport
- displayListCanvas.translate(-left, -top);
- layout.drawText(displayListCanvas, blockBeginLine, blockEndLine);
+ recordingCanvas.translate(-left, -top);
+ layout.drawText(recordingCanvas, blockBeginLine, blockEndLine);
mTextRenderNodes[blockIndex].isDirty = false;
// No need to untranslate, previous context is popped after
// drawDisplayList
} finally {
- blockDisplayList.end(displayListCanvas);
+ blockDisplayList.end(recordingCanvas);
// Same as drawDisplayList below, handled by our TextView's parent
blockDisplayList.setClipToBounds(false);
}
@@ -1962,7 +1962,7 @@ public class Editor {
blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
mTextRenderNodes[blockIndex].needsToBeShifted = false;
}
- ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList);
+ ((RecordingCanvas) canvas).drawRenderNode(blockDisplayList);
return startIndexToFindAvailableRenderNode;
}
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 16ddd0fc8247..6a3fc0fad4dd 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -33,15 +33,15 @@ import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RenderNode;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.view.ContextThemeWrapper;
import android.view.Display;
-import android.view.DisplayListCanvas;
import android.view.PixelCopy;
-import android.view.RenderNode;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
@@ -704,7 +704,7 @@ public final class Magnifier {
cornerRadius
);
- final DisplayListCanvas canvas = mRenderer.getRootNode().start(width, height);
+ final RecordingCanvas canvas = mRenderer.getRootNode().start(width, height);
try {
canvas.insertReorderBarrier();
canvas.drawRenderNode(mBitmapRenderNode);
@@ -736,7 +736,7 @@ public final class Magnifier {
bitmapRenderNode.setClipToOutline(true);
// Create a dummy draw, which will be replaced later with real drawing.
- final DisplayListCanvas canvas = bitmapRenderNode.start(mContentWidth, mContentHeight);
+ final RecordingCanvas canvas = bitmapRenderNode.start(mContentWidth, mContentHeight);
try {
canvas.drawColor(0xFF00FF00);
} finally {
@@ -817,7 +817,7 @@ public final class Magnifier {
return;
}
- final DisplayListCanvas canvas =
+ final RecordingCanvas canvas =
mBitmapRenderNode.start(mContentWidth, mContentHeight);
try {
canvas.drawColor(Color.WHITE);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3dd6fd1410bd..66809dbc4e45 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -63,7 +63,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
-import android.graphics.fonts.Font;
+import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
import android.icu.text.DecimalFormatSymbols;
import android.os.AsyncTask;
@@ -2073,7 +2073,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
private void setTypefaceFromAttrs(@Nullable Typeface typeface, @Nullable String familyName,
@XMLTypefaceAttr int typefaceIndex, @Typeface.Style int style,
- @IntRange(from = -1, to = Font.FONT_WEIGHT_MAX) int weight) {
+ @IntRange(from = -1, to = FontStyle.FONT_WEIGHT_MAX) int weight) {
if (typeface == null && familyName != null) {
// Lookup normal Typeface from system font map.
final Typeface normalTypeface = Typeface.create(familyName, Typeface.NORMAL);
@@ -2100,9 +2100,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void resolveStyleAndSetTypeface(@NonNull Typeface typeface, @Typeface.Style int style,
- @IntRange(from = -1, to = Font.FONT_WEIGHT_MAX) int weight) {
+ @IntRange(from = -1, to = FontStyle.FONT_WEIGHT_MAX) int weight) {
if (weight >= 0) {
- weight = Math.min(Font.FONT_WEIGHT_MAX, weight);
+ weight = Math.min(FontStyle.FONT_WEIGHT_MAX, weight);
final boolean italic = (style & Typeface.ITALIC) != 0;
setTypeface(Typeface.create(typeface, weight, italic));
} else {
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index a70209c705c0..f14007bd7ac6 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -16,13 +16,13 @@
package com.android.internal.policy;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RenderNode;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Looper;
import android.view.Choreographer;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import android.view.ThreadedRenderer;
/**
@@ -339,7 +339,7 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
// Draw the caption and content backdrops in to our render node.
- DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
+ RecordingCanvas canvas = mFrameAndBackdropNode.start(width, height);
final Drawable drawable = mUserCaptionBackgroundDrawable != null
? mUserCaptionBackgroundDrawable : mCaptionBackgroundDrawable;
@@ -368,7 +368,7 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
if (mSystemBarBackgroundNode == null) {
return;
}
- DisplayListCanvas canvas = mSystemBarBackgroundNode.start(width, height);
+ RecordingCanvas canvas = mSystemBarBackgroundNode.start(width, height);
mSystemBarBackgroundNode.setLeftTopRightBottom(left, top, left + width, top + height);
final int topInset = DecorView.getColorViewTopInset(mStableInsets.top, mSystemInsets.top);
if (mStatusBarColor != null) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 469726613513..94140ab7f440 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -16,52 +16,60 @@
package com.android.internal.policy;
-import android.annotation.Nullable;
-import android.annotation.TestApi;
-import android.app.WindowConfiguration;
-import android.graphics.Outline;
-import android.graphics.drawable.InsetDrawable;
-import android.graphics.drawable.LayerDrawable;
-import android.util.Pair;
-import android.view.ViewOutlineProvider;
-import android.view.accessibility.AccessibilityNodeInfo;
-import com.android.internal.R;
-import com.android.internal.policy.PhoneWindow.PanelFeatureState;
-import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback;
-import com.android.internal.view.FloatingActionMode;
-import com.android.internal.view.RootViewSurfaceTaker;
-import com.android.internal.view.StandaloneActionMode;
-import com.android.internal.view.menu.ContextMenuBuilder;
-import com.android.internal.view.menu.MenuHelper;
-import com.android.internal.widget.ActionBarContextView;
-import com.android.internal.widget.BackgroundFallback;
-import com.android.internal.widget.DecorCaptionView;
-import com.android.internal.widget.FloatingToolbar;
+import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.N;
+import static android.view.View.MeasureSpec.AT_MOST;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.getMode;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.Window.DECOR_CAPTION_SHADE_DARK;
+import static android.view.Window.DECOR_CAPTION_SHADE_LIGHT;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+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.FLAG_TRANSLUCENT_NAVIGATION;
+import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
-import java.util.List;
+import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.app.WindowConfiguration;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
+import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.graphics.drawable.LayerDrawable;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.ContextThemeWrapper;
-import android.view.DisplayListCanvas;
import android.view.Gravity;
import android.view.InputQueue;
import android.view.KeyEvent;
@@ -73,6 +81,7 @@ import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.Window;
@@ -81,34 +90,26 @@ import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.PopupWindow;
-import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-import static android.os.Build.VERSION_CODES.M;
-import static android.os.Build.VERSION_CODES.N;
-import static android.view.View.MeasureSpec.AT_MOST;
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.getMode;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static android.view.Window.DECOR_CAPTION_SHADE_DARK;
-import static android.view.Window.DECOR_CAPTION_SHADE_LIGHT;
-import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
-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.FLAG_TRANSLUCENT_NAVIGATION;
-import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
-import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
+import com.android.internal.R;
+import com.android.internal.policy.PhoneWindow.PanelFeatureState;
+import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback;
+import com.android.internal.view.FloatingActionMode;
+import com.android.internal.view.RootViewSurfaceTaker;
+import com.android.internal.view.StandaloneActionMode;
+import com.android.internal.view.menu.ContextMenuBuilder;
+import com.android.internal.view.menu.MenuHelper;
+import com.android.internal.widget.ActionBarContextView;
+import com.android.internal.widget.BackgroundFallback;
+import com.android.internal.widget.DecorCaptionView;
+import com.android.internal.widget.FloatingToolbar;
+
+import java.util.List;
/** @hide */
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
@@ -2134,7 +2135,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
@Override
- public void onPostDraw(DisplayListCanvas canvas) {
+ public void onPostDraw(RecordingCanvas canvas) {
drawResizingShadowIfNeeded(canvas);
}
@@ -2152,7 +2153,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
new float[] { 0f, 0.3f, 1f }, Shader.TileMode.CLAMP));
}
- private void drawResizingShadowIfNeeded(DisplayListCanvas canvas) {
+ private void drawResizingShadowIfNeeded(RecordingCanvas canvas) {
if (mResizeMode != RESIZE_MODE_DOCKED_DIVIDER || mWindow.mIsFloating
|| mWindow.isTranslucent()
|| mWindow.isShowingWallpaper()) {
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index 367b713ed78f..794238a3826e 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -29,10 +29,8 @@ import android.view.inputmethod.ExtractedText;
* {@hide}
*/
oneway interface IInputMethodSession {
- void finishInput();
-
void updateExtractedText(int token, in ExtractedText text);
-
+
void updateSelection(int oldSelStart, int oldSelEnd,
int newSelStart, int newSelEnd,
int candidatesStart, int candidatesEnd);
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 9263b579ee02..97896f0f6028 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -24,23 +24,21 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
-import android.graphics.drawable.Drawable;
import android.graphics.Paint;
import android.graphics.Path;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Debug;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.util.IntArray;
import android.util.Log;
import android.util.SparseArray;
-import android.view.DisplayListCanvas;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.RenderNodeAnimator;
@@ -1131,8 +1129,8 @@ public class LockPatternView extends View {
drawCellDrawable(canvas, i, j, cellState.radius, drawLookup[i][j]);
} else {
if (isHardwareAccelerated() && cellState.hwAnimating) {
- DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
- displayListCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY,
+ RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
+ recordingCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY,
cellState.hwRadius, cellState.hwPaint);
} else {
drawCircle(canvas, (int) centerX, (int) centerY + translationY,
diff --git a/core/jni/android_opengl_EGL15.cpp b/core/jni/android_opengl_EGL15.cpp
index 4a30babafa49..b52f137da7d6 100644
--- a/core/jni/android_opengl_EGL15.cpp
+++ b/core/jni/android_opengl_EGL15.cpp
@@ -456,27 +456,41 @@ exit:
static jobject
android_eglCreatePlatformPixmapSurface
(JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject native_pixmap_buf, jlongArray attrib_list_ref, jint offset) {
+ jniThrowException(_env, "java/lang/UnsupportedOperationException",
+ "eglCreatePlatformPixmapSurface");
+ return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, (EGLSurface) 0);
+}
+
+/* EGLBoolean eglWaitSync ( EGLDisplay dpy, EGLSync sync, EGLint flags ) */
+static jboolean
+android_eglWaitSync
+ (JNIEnv *_env, jobject _this, jobject dpy, jobject sync, jint flags) {
+ EGLBoolean _returnValue = (EGLBoolean) 0;
+ EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+ EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync);
+
+ _returnValue = eglWaitSync(
+ (EGLDisplay)dpy_native,
+ (EGLSync)sync_native,
+ (EGLint)flags
+ );
+ return (jboolean)_returnValue;
+}
+
+/* EGLImage eglCreateImage ( EGLDisplay dpy, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list ) */
+static jobject
+android_eglCreateImage
+ (JNIEnv *_env, jobject _this, jobject dpy, jobject context, jint target, jlong buffer, jlongArray attrib_list_ref, jint offset) {
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
- jint _bufferOffset = (jint) 0;
- EGLSurface _returnValue = (EGLSurface) 0;
+ EGLImage _returnValue = (EGLImage) 0;
EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
- EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
- jint _native_pixmapRemaining;
- void *native_pixmap = (void *) 0;
+ EGLContext context_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, context);
EGLAttrib *attrib_list_base = (EGLAttrib *) 0;
- jint _attrib_listRemaining;
+ jint _remaining;
EGLAttrib *attrib_list = (EGLAttrib *) 0;
- if (!native_pixmap_buf) {
- _exception = 1;
- _exceptionType = "java/lang/IllegalArgumentException";
- _exceptionMessage = "native_pixmap == null";
- goto exit;
- }
- native_pixmap = (void *)getPointer(_env, native_pixmap_buf, (jarray*)&_array, &_native_pixmapRemaining, &_bufferOffset);
if (!attrib_list_ref) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -489,19 +503,16 @@ android_eglCreatePlatformPixmapSurface
_exceptionMessage = "offset < 0";
goto exit;
}
- _attrib_listRemaining = _env->GetArrayLength(attrib_list_ref) - offset;
+ _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
attrib_list_base = (EGLAttrib *)
_env->GetLongArrayElements(attrib_list_ref, (jboolean *)0);
attrib_list = attrib_list_base + offset;
- if (native_pixmap == NULL) {
- char * _native_pixmapBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
- native_pixmap = (void *) (_native_pixmapBase + _bufferOffset);
- }
- _returnValue = eglCreatePlatformPixmapSurface(
+ _returnValue = eglCreateImage(
(EGLDisplay)dpy_native,
- (EGLConfig)config_native,
- (void *)native_pixmap,
+ (EGLContext)context_native,
+ (EGLenum)target,
+ (EGLClientBuffer)buffer,
(EGLAttrib *)attrib_list
);
@@ -510,27 +521,23 @@ exit:
_env->ReleaseLongArrayElements(attrib_list_ref, (jlong*)attrib_list_base,
JNI_ABORT);
}
- if (_array) {
- releasePointer(_env, _array, native_pixmap, _exception ? JNI_FALSE : JNI_TRUE);
- }
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+ return toEGLHandle(_env, eglimageClass, eglimageConstructor, _returnValue);
}
-/* EGLBoolean eglWaitSync ( EGLDisplay dpy, EGLSync sync, EGLint flags ) */
+/* EGLBoolean eglDestroyImage ( EGLDisplay dpy, EGLImage image ) */
static jboolean
-android_eglWaitSync
- (JNIEnv *_env, jobject _this, jobject dpy, jobject sync, jint flags) {
+android_eglDestroyImage
+ (JNIEnv *_env, jobject _this, jobject dpy, jobject image) {
EGLBoolean _returnValue = (EGLBoolean) 0;
EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
- EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync);
+ EGLImage image_native = (EGLImage) fromEGLHandle(_env, eglimageGetHandleID, image);
- _returnValue = eglWaitSync(
+ _returnValue = eglDestroyImage(
(EGLDisplay)dpy_native,
- (EGLSync)sync_native,
- (EGLint)flags
+ (EGLImage)image_native
);
return (jboolean)_returnValue;
}
@@ -547,6 +554,8 @@ static const JNINativeMethod methods[] = {
{"eglCreatePlatformWindowSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/nio/Buffer;[JI)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePlatformWindowSurface },
{"eglCreatePlatformPixmapSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/nio/Buffer;[JI)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePlatformPixmapSurface },
{"eglWaitSync", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;I)Z", (void *) android_eglWaitSync },
+{"eglCreateImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLContext;IJ[JI)Landroid/opengl/EGLImage;", (void *) android_eglCreateImage },
+{"eglDestroyImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLImage;)Z", (void *) android_eglDestroyImage },
};
int register_android_opengl_jni_EGL15(JNIEnv *_env)
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 4fdd2bcd4f39..8998cd706dd8 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -183,7 +183,7 @@ static void android_view_DisplayListCanvas_drawCircleProps(jlong canvasPtr,
// JNI Glue
// ----------------------------------------------------------------------------
-const char* const kClassPathName = "android/view/DisplayListCanvas";
+const char* const kClassPathName = "android/graphics/RecordingCanvas";
static JNINativeMethod gMethods[] = {
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 63b004681df9..bb71a5d4accf 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -576,7 +576,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
// JNI Glue
// ----------------------------------------------------------------------------
-const char* const kClassPathName = "android/view/RenderNode";
+const char* const kClassPathName = "android/graphics/RenderNode";
static const JNINativeMethod gMethods[] = {
// ----------------------------------------------------------------------------
@@ -588,7 +588,7 @@ static const JNINativeMethod gMethods[] = {
{ "nGetDebugSize", "(J)I", (void*) android_view_RenderNode_getDebugSize },
{ "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator },
{ "nEndAllAnimators", "(J)V", (void*) android_view_RenderNode_endAllAnimators },
- { "nRequestPositionUpdates", "(JLandroid/view/RenderNode$PositionUpdateListener;)V", (void*) android_view_RenderNode_requestPositionUpdates },
+ { "nRequestPositionUpdates", "(JLandroid/graphics/RenderNode$PositionUpdateListener;)V", (void*) android_view_RenderNode_requestPositionUpdates },
{ "nSetDisplayList", "(JJ)V", (void*) android_view_RenderNode_setDisplayList },
@@ -677,7 +677,7 @@ static const JNINativeMethod gMethods[] = {
};
int register_android_view_RenderNode(JNIEnv* env) {
- jclass clazz = FindClassOrDie(env, "android/view/RenderNode$PositionUpdateListener");
+ jclass clazz = FindClassOrDie(env, "android/graphics/RenderNode$PositionUpdateListener");
gPositionListener_PositionChangedMethod = GetMethodIDOrDie(env, clazz,
"positionChanged", "(JIIII)V");
gPositionListener_PositionLostMethod = GetMethodIDOrDie(env, clazz,
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9bedab53bb2c..32cf2e8bac86 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7894,6 +7894,9 @@
<!-- Wallpapers optimized and capable of drawing in ambient mode will return true. -->
<attr name="supportsAmbientMode" format="boolean" />
+ <!-- Uri that specifies a settings Slice for this wallpaper. -->
+ <attr name="settingsSliceUri" />
+
</declare-styleable>
<!-- Use <code>dream</code> as the root tag of the XML resource that
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 31212a6ab28f..fd688a72b7ea 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2916,6 +2916,7 @@
<public name="isLightTheme" />
<public name="isSplitRequired" />
<public name="textLocale" />
+ <public name="settingsSliceUri" />
</public-group>
<public-group type="drawable" first-id="0x010800b4">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fa4406185218..9ea82a9b9c2e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2924,55 +2924,55 @@
<!-- Title for EditText context menu [CHAR LIMIT=20] -->
<string name="editTextMenuTitle">Text actions</string>
- <!-- Label for item in the text selection menu to trigger an Email app. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to trigger an Email app. Should be a verb. [CHAR LIMIT=30] -->
<string name="email">Email</string>
<!-- Accessibility description for an item in the text selection menu to trigger an Email app [CHAR LIMIT=NONE] -->
<string name="email_desc">Email selected address</string>
- <!-- Label for item in the text selection menu to trigger a Dialer app. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to trigger a Dialer app. Should be a verb. [CHAR LIMIT=30] -->
<string name="dial">Call</string>
<!-- Accessibility description for an item in the text selection menu to call a phone number [CHAR LIMIT=NONE] -->
<string name="dial_desc">Call selected phone number</string>
- <!-- Label for item in the text selection menu to trigger a Map app. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to trigger a Map app. Should be a verb. [CHAR LIMIT=30] -->
<string name="map">Map</string>
<!-- Accessibility description for an item in the text selection menu to open maps for an address [CHAR LIMIT=NONE] -->
<string name="map_desc">Locate selected address</string>
- <!-- Label for item in the text selection menu to trigger a Browser app. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to trigger a Browser app. Should be a verb. [CHAR LIMIT=30] -->
<string name="browse">Open</string>
<!-- Accessibility description for an item in the text selection menu to open a URL in a browser [CHAR LIMIT=NONE] -->
<string name="browse_desc">Open selected URL</string>
- <!-- Label for item in the text selection menu to trigger an SMS app. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to trigger an SMS app. Should be a verb. [CHAR LIMIT=30] -->
<string name="sms">Message</string>
<!-- Accessibility description for an item in the text selection menu to send an SMS to a phone number [CHAR LIMIT=NONE] -->
<string name="sms_desc">Message selected phone number</string>
- <!-- Label for item in the text selection menu to trigger adding a contact. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to trigger adding a contact. Should be a verb. [CHAR LIMIT=30] -->
<string name="add_contact">Add</string>
<!-- Accessibility description for an item in the text selection menu to add the selected detail to contacts [CHAR LIMIT=NONE] -->
<string name="add_contact_desc">Add to contacts</string>
- <!-- Label for item in the text selection menu to view the calendar for the selected time/date. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to view the calendar for the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
<string name="view_calendar">View</string>
<!-- Accessibility description for an item in the text selection menu to view the calendar for a date [CHAR LIMIT=NONE]-->
<string name="view_calendar_desc">View selected time in calendar</string>
- <!-- Label for item in the text selection menu to create a calendar event at the selected time/date. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to create a calendar event at the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
<string name="add_calendar_event">Schedule</string>
<!-- Accessibility description for an item in the text selection menu to schedule an event for a date [CHAR LIMIT=NONE] -->
<string name="add_calendar_event_desc">Schedule event for selected time</string>
- <!-- Label for item in the text selection menu to track a selected flight number. Should be a verb. [CHAR LIMIT=20] -->
+ <!-- Label for item in the text selection menu to track a selected flight number. Should be a verb. [CHAR LIMIT=30] -->
<string name="view_flight">Track</string>
<!-- Accessibility description for an item in the text selection menu to track a flight [CHAR LIMIT=NONE] -->
diff --git a/core/tests/coretests/assets/fonts/1em_bidi_font.ttf b/core/tests/coretests/assets/fonts/1em_bidi_font.ttf
new file mode 100644
index 000000000000..459925433349
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/1em_bidi_font.ttf
Binary files differ
diff --git a/core/tests/coretests/src/android/text/LayoutBidiCursorPathTest.java b/core/tests/coretests/src/android/text/LayoutBidiCursorPathTest.java
new file mode 100644
index 000000000000..1208d7ca194a
--- /dev/null
+++ b/core/tests/coretests/src/android/text/LayoutBidiCursorPathTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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 android.text;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import android.content.Context;
+import android.graphics.Path;
+import android.graphics.Typeface;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.method.MetaKeyKeyListener;
+import android.view.KeyEvent;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LayoutBidiCursorPathTest {
+
+ private static final float BIDI_TEXT_SIZE = 12f;
+ private static final String LTR_TEXT = "hello";
+ private static final String RTL_TEXT = "مرحبا";
+
+ private SpannableStringBuilder mBidiText;
+ private TextPaint mTextPaint;
+
+ @Before
+ public void setup() {
+ mBidiText = new SpannableStringBuilder(LTR_TEXT + RTL_TEXT);
+
+ final Context context = InstrumentationRegistry.getTargetContext();
+ mTextPaint = new TextPaint();
+ mTextPaint.setTypeface(
+ Typeface.createFromAsset(context.getAssets(), "fonts/1em_bidi_font.ttf"));
+ mTextPaint.setTextSize(BIDI_TEXT_SIZE);
+ }
+
+ @Test
+ public void testGetCursorPathSegments() {
+ // Setup layout and Act.
+ final Path actualPath = new Path();
+ setupLayoutAndGetCursorPath(actualPath);
+
+ // Expected path.
+ final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
+ final int top = 0;
+ // sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
+ final int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
+
+ final Path expectedPath = new Path();
+
+ expectedPath.moveTo(h1, top);
+ expectedPath.lineTo(h1, bottom);
+
+ // Assert.
+ assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
+ }
+
+ @Test
+ public void testGetCursorPath_whenShiftIsPressed() {
+ // When shift is pressed a triangle is drawn at the bottom quarter of the cursor.
+ // Set up key.
+ final MetaKeyKeyListener metaKeyKeyListener = new MetaKeyKeyListener() {};
+ metaKeyKeyListener
+ .onKeyDown(null /*view*/, mBidiText, KeyEvent.KEYCODE_SHIFT_RIGHT, null /*keyEvent*/);
+
+ // Setup layout and Act.
+ final Path actualPath = new Path();
+ setupLayoutAndGetCursorPath(actualPath);
+
+ // Expected path.
+ final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
+ final int top = 0;
+ // sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
+ int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
+ // Draw a triangle at the bottom quarter of the cursor, thus cut the cursor to its 3/4
+ // length.
+ final int dist = (bottom - top) / 4;
+ bottom -= dist;
+
+ final Path expectedPath = new Path();
+
+ expectedPath.moveTo(h1, top);
+ expectedPath.lineTo(h1, bottom);
+
+ expectedPath.moveTo(h1, bottom);
+ expectedPath.lineTo(h1 - dist, bottom + dist);
+
+ expectedPath.moveTo(h1 - dist, bottom + dist - 0.5f);
+ expectedPath.lineTo(h1 + dist, bottom + dist - 0.5f);
+
+ expectedPath.moveTo(h1 + dist, bottom + dist);
+ expectedPath.lineTo(h1, bottom);
+
+ // Assert.
+ assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
+ }
+
+ @Test
+ public void testGetCursorPath_whenAltIsPressed() {
+ // When alt is pressed a triangle is drawn at the top quarter of the cursor.
+ // Set up key.
+ final MetaKeyKeyListener metaKeyKeyListener = new MetaKeyKeyListener() {};
+ metaKeyKeyListener
+ .onKeyDown(null /*view*/, mBidiText, KeyEvent.KEYCODE_ALT_RIGHT, null /*keyEvent*/);
+
+ // Setup layout and Act.
+ final Path actualPath = new Path();
+ setupLayoutAndGetCursorPath(actualPath);
+
+ // Expected path.
+ final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
+ int top = 0;
+ // sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
+ final int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
+ // Draw a triangle at the top quarter of the cursor, thus cut the cursor to its 3/4 length.
+ final int dist = (bottom - top) / 4;
+ top += dist;
+
+ final Path expectedPath = new Path();
+
+ expectedPath.moveTo(h1, top);
+ expectedPath.lineTo(h1, bottom);
+
+ expectedPath.moveTo(h1, top);
+ expectedPath.lineTo(h1 - dist, top - dist);
+
+ expectedPath.moveTo(h1 - dist, top - dist + 0.5f);
+ expectedPath.lineTo(h1 + dist, top - dist + 0.5f);
+
+ expectedPath.moveTo(h1 + dist, top - dist);
+ expectedPath.lineTo(h1, top);
+
+ // Assert.
+ assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
+ }
+
+ private void setupLayoutAndGetCursorPath(Path path) {
+ final Layout layout = StaticLayout.Builder.obtain(
+ mBidiText, 0, mBidiText.length(), mTextPaint, Integer.MAX_VALUE)
+ .setIncludePad(false)
+ .build();
+
+ layout.getCursorPath(LTR_TEXT.length(), path, mBidiText);
+ }
+}
diff --git a/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java b/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java
index 1097bc731de8..01382aae923e 100644
--- a/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java
+++ b/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java
@@ -17,14 +17,9 @@
package android.content.pm;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import android.content.Context;
import android.os.FileUtils;
-import android.os.Process;
import android.os.ServiceManager;
import android.os.UserManager;
import android.support.test.InstrumentationRegistry;
@@ -32,7 +27,6 @@ import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -86,12 +80,23 @@ public class KernelPackageMappingTests {
}
@Test
+ public void testSharedInstalledPrimary() throws Exception {
+ assertEquals("1001", getContent(getKernelPackageFile("shared:android.uid.phone", "appid")));
+ }
+
+ @Test
public void testInstalledAll() throws Exception {
assertEquals("", getContent(getKernelPackageFile("com.android.settings",
"excluded_userids")));
}
@Test
+ public void testSharedInstalledAll() throws Exception {
+ assertEquals("", getContent(getKernelPackageFile("shared:android.uid.phone",
+ "excluded_userids")));
+ }
+
+ @Test
public void testNotInstalledSecondary() throws Exception {
mSecondaryUser = getUserManager().createUser("Secondary", 0);
assertEquals(Integer.toString(mSecondaryUser.id),
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 44f8737da2c1..28e92dbe264a 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -146,6 +146,7 @@ applications that come with the platform
<permission name="android.permission.CLEAR_APP_CACHE"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"/>
+ <permission name="android.permission.GET_APP_OPS_STATS"/>
<permission name="android.permission.UPDATE_APP_OPS_STATS"/>
</privapp-permissions>
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index ea0a109c3a04..3db240b54299 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -83,7 +83,7 @@ public abstract class BaseCanvas {
// ---------------------------------------------------------------------------
// Drawing methods
- // These are also implemented in DisplayListCanvas so that we can
+ // These are also implemented in RecordingCanvas so that we can
// selectively apply on them
// Everything below here is copy/pasted from Canvas.java
// The JNI registration is handled by android_view_Canvas.cpp
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 1cd756f9f73f..364fb04e57b1 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -31,8 +31,6 @@ import android.os.StrictMode;
import android.os.Trace;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import android.view.ThreadedRenderer;
import dalvik.annotation.optimization.CriticalNative;
@@ -1297,7 +1295,7 @@ public final class Bitmap implements Parcelable {
node.setLeftTopRightBottom(0, 0, width, height);
node.setClipToBounds(false);
node.setAllowForceDark(false);
- final DisplayListCanvas canvas = node.start(width, height);
+ final RecordingCanvas canvas = node.start(width, height);
if (source.getWidth() != width || source.getHeight() != height) {
canvas.scale(width / (float) source.getWidth(),
height / (float) source.getHeight());
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index f7acb11c8811..f6d801b3ba43 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.UnsupportedAppUsage;
+
import java.io.InputStream;
import java.io.OutputStream;
@@ -216,7 +217,7 @@ public class Picture {
public PictureCanvas(Picture pict, long nativeCanvas) {
super(nativeCanvas);
mPicture = pict;
- // Disable bitmap density scaling. This matches DisplayListCanvas.
+ // Disable bitmap density scaling. This matches RecordingCanvas.
mDensity = 0;
}
diff --git a/core/java/android/view/DisplayListCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
index 667fab5537c9..7af006b4bdf0 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -14,47 +14,47 @@
* limitations under the License.
*/
-package android.view;
+package android.graphics;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
-import android.graphics.BaseRecordingCanvas;
-import android.graphics.Bitmap;
-import android.graphics.CanvasProperty;
-import android.graphics.Paint;
import android.util.Pools.SynchronizedPool;
+import android.view.TextureLayer;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
/**
* A Canvas implementation that records view system drawing operations for deferred rendering.
- * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
+ * This is intended for use with RenderNode. This class keeps a list of all the Paint and
* Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
- * the DisplayList is still holding a native reference to the memory.
+ * the RecordingCanvas is still holding a native reference to the memory.
*
* @hide
*/
-public final class DisplayListCanvas extends BaseRecordingCanvas {
+public final class RecordingCanvas extends BaseRecordingCanvas {
// The recording canvas pool should be large enough to handle a deeply nested
// view hierarchy because display lists are generated recursively.
private static final int POOL_LIMIT = 25;
public static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
- private static final SynchronizedPool<DisplayListCanvas> sPool =
+ private static final SynchronizedPool<RecordingCanvas> sPool =
new SynchronizedPool<>(POOL_LIMIT);
- RenderNode mNode;
+ /**
+ * TODO: Temporarily exposed for RenderNodeAnimator(Set)
+ * @hide */
+ public RenderNode mNode;
private int mWidth;
private int mHeight;
- static DisplayListCanvas obtain(@NonNull RenderNode node, int width, int height) {
+ static RecordingCanvas obtain(@NonNull RenderNode node, int width, int height) {
if (node == null) throw new IllegalArgumentException("node cannot be null");
- DisplayListCanvas canvas = sPool.acquire();
+ RecordingCanvas canvas = sPool.acquire();
if (canvas == null) {
- canvas = new DisplayListCanvas(node, width, height);
+ canvas = new RecordingCanvas(node, width, height);
} else {
nResetDisplayListCanvas(canvas.mNativeCanvasWrapper, node.mNativeRenderNode,
width, height);
@@ -83,7 +83,7 @@ public final class DisplayListCanvas extends BaseRecordingCanvas {
// Constructors
///////////////////////////////////////////////////////////////////////////
- private DisplayListCanvas(@NonNull RenderNode node, int width, int height) {
+ private RecordingCanvas(@NonNull RenderNode node, int width, int height) {
super(nCreateDisplayListCanvas(node.mNativeRenderNode, width, height));
mDensity = 0; // disable bitmap density scaling
}
@@ -95,7 +95,7 @@ public final class DisplayListCanvas extends BaseRecordingCanvas {
@Override
public void setDensity(int density) {
- // drop silently, since DisplayListCanvas doesn't perform density scaling
+ // drop silently, since RecordingCanvas doesn't perform density scaling
}
@Override
@@ -156,6 +156,8 @@ public final class DisplayListCanvas extends BaseRecordingCanvas {
* functionality used by webview for calling into their renderer from our display lists.
*
* @param drawGLFunction A native function pointer
+ *
+ * @hide
*/
@UnsupportedAppUsage
public void callDrawGLFunction2(long drawGLFunction) {
@@ -166,13 +168,15 @@ public final class DisplayListCanvas extends BaseRecordingCanvas {
* Records the functor specified with the drawGLFunction function pointer. This is
* functionality used by webview for calling into their renderer from our display lists.
*
- * @param drawGLFunction A native function pointer
+ * @param drawGLFunctor A native function pointer
* @param releasedCallback Called when the display list is destroyed, and thus
* the functor is no longer referenced by this canvas's display list.
*
* NOTE: The callback does *not* necessarily mean that there are no longer
* any references to the functor, just that the reference from this specific
* canvas's display list has been released.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
@@ -201,8 +205,9 @@ public final class DisplayListCanvas extends BaseRecordingCanvas {
* Draws the specified layer onto this canvas.
*
* @param layer The layer to composite on this canvas
+ * @hide
*/
- void drawTextureLayer(TextureLayer layer) {
+ public void drawTextureLayer(TextureLayer layer) {
nDrawTextureLayer(mNativeCanvasWrapper, layer.getLayerHandle());
}
@@ -210,6 +215,16 @@ public final class DisplayListCanvas extends BaseRecordingCanvas {
// Drawing
///////////////////////////////////////////////////////////////////////////
+ /**
+ * Draws a circle
+ *
+ * @param cx
+ * @param cy
+ * @param radius
+ * @param paint
+ *
+ * @hide
+ */
@UnsupportedAppUsage
public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
@@ -217,6 +232,19 @@ public final class DisplayListCanvas extends BaseRecordingCanvas {
radius.getNativeContainer(), paint.getNativeContainer());
}
+ /**
+ * Draws a round rect
+ *
+ * @param left
+ * @param top
+ * @param right
+ * @param bottom
+ * @param rx
+ * @param ry
+ * @param paint
+ *
+ * @hide
+ */
public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
diff --git a/core/java/android/view/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 8ae912762fdb..60641d82cb65 100644
--- a/core/java/android/view/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -14,16 +14,15 @@
* limitations under the License.
*/
-package android.view;
+package android.graphics;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
-import android.graphics.Matrix;
-import android.graphics.Outline;
-import android.graphics.Paint;
-import android.graphics.Rect;
+import android.view.NativeVectorDrawableAnimator;
+import android.view.RenderNodeAnimator;
+import android.view.View;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
@@ -36,7 +35,7 @@ import java.lang.annotation.RetentionPolicy;
/**
* <p>A display list records a series of graphics related operations and can replay
* them later. Display lists are usually built by recording operations on a
- * {@link DisplayListCanvas}. Replaying the operations from a display list avoids
+ * {@link RecordingCanvas}. Replaying the operations from a display list avoids
* executing application code on every frame, and is thus much more efficient.</p>
*
* <p>Display lists are used internally for all views by default, and are not
@@ -53,7 +52,7 @@ import java.lang.annotation.RetentionPolicy;
* affected paragraph needs to be recorded again.</p>
*
* <h3>Hardware acceleration</h3>
- * <p>Display lists can only be replayed using a {@link DisplayListCanvas}. They are not
+ * <p>Display lists can only be replayed using a {@link RecordingCanvas}. They are not
* supported in software. Always make sure that the {@link android.graphics.Canvas}
* you are using to render a display list is hardware accelerated using
* {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
@@ -63,7 +62,7 @@ import java.lang.annotation.RetentionPolicy;
* ThreadedRenderer renderer = myView.getThreadedRenderer();
* if (renderer != null) {
* DisplayList displayList = renderer.createDisplayList();
- * DisplayListCanvas canvas = displayList.start(width, height);
+ * RecordingCanvas canvas = displayList.start(width, height);
* try {
* // Draw onto the canvas
* // For instance: canvas.drawBitmap(...);
@@ -77,7 +76,7 @@ import java.lang.annotation.RetentionPolicy;
* <pre class="prettyprint">
* protected void onDraw(Canvas canvas) {
* if (canvas.isHardwareAccelerated()) {
- * DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
+ * RecordingCanvas displayListCanvas = (RecordingCanvas) canvas;
* displayListCanvas.drawDisplayList(mDisplayList);
* }
* }
@@ -102,7 +101,7 @@ import java.lang.annotation.RetentionPolicy;
* <pre class="prettyprint">
* private void createDisplayList() {
* mDisplayList = DisplayList.create("MyDisplayList");
- * DisplayListCanvas canvas = mDisplayList.start(width, height);
+ * RecordingCanvas canvas = mDisplayList.start(width, height);
* try {
* for (Bitmap b : mBitmaps) {
* canvas.drawBitmap(b, 0.0f, 0.0f, null);
@@ -115,7 +114,7 @@ import java.lang.annotation.RetentionPolicy;
*
* protected void onDraw(Canvas canvas) {
* if (canvas.isHardwareAccelerated()) {
- * DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
+ * RecordingCanvas displayListCanvas = (RecordingCanvas) canvas;
* displayListCanvas.drawDisplayList(mDisplayList);
* }
* }
@@ -143,10 +142,10 @@ public class RenderNode {
RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
}
- /** Not for general use; use only if you are ThreadedRenderer or DisplayListCanvas.
+ /** Not for general use; use only if you are ThreadedRenderer or RecordingCanvas.
* @hide
*/
- final long mNativeRenderNode;
+ public final long mNativeRenderNode;
private final AnimationHost mAnimationHost;
private RenderNode(String name, AnimationHost animationHost) {
@@ -195,7 +194,7 @@ public class RenderNode {
*
* @hide
*/
- interface PositionUpdateListener {
+ public interface PositionUpdateListener {
/**
* Called by native by a Rendering Worker thread to update window position
@@ -228,7 +227,7 @@ public class RenderNode {
* stored in this display list.
*
* Calling this method will mark the render node invalid until
- * {@link #end(DisplayListCanvas)} is called.
+ * {@link #end(RecordingCanvas)} is called.
* Only valid render nodes can be replayed.
*
* @param width The width of the recording viewport
@@ -236,19 +235,19 @@ public class RenderNode {
*
* @return A canvas to record drawing operations.
*
- * @see #end(DisplayListCanvas)
+ * @see #end(RecordingCanvas)
* @see #isValid()
*/
@UnsupportedAppUsage
- public DisplayListCanvas start(int width, int height) {
- return DisplayListCanvas.obtain(this, width, height);
+ public RecordingCanvas start(int width, int height) {
+ return RecordingCanvas.obtain(this, width, height);
}
/**
* Same as {@link #start(int, int)} but with the RenderNode's width & height
*/
- public DisplayListCanvas start() {
- return DisplayListCanvas.obtain(this,
+ public RecordingCanvas start() {
+ return RecordingCanvas.obtain(this,
nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
}
@@ -261,7 +260,7 @@ public class RenderNode {
* @see #isValid()
*/
@UnsupportedAppUsage
- public void end(DisplayListCanvas canvas) {
+ public void end(RecordingCanvas canvas) {
long displayList = canvas.finishRecording();
nSetDisplayList(mNativeRenderNode, displayList);
canvas.recycle();
@@ -292,14 +291,32 @@ public class RenderNode {
// Matrix manipulation
///////////////////////////////////////////////////////////////////////////
+ /**
+ * Whether or not the RenderNode has an identity transform. This is a faster
+ * way to do the otherwise equivalent {@link #getMatrix(Matrix)} {@link Matrix#isIdentity()}
+ * as it doesn't require copying the Matrix first, thus minimizing overhead.
+ *
+ * @return true if the RenderNode has an identity transform, false otherwise
+ */
public boolean hasIdentityMatrix() {
return nHasIdentityMatrix(mNativeRenderNode);
}
+ /**
+ * Gets the current transform matrix
+ *
+ * @param outMatrix The matrix to store the transform of the RenderNode
+ */
public void getMatrix(@NonNull Matrix outMatrix) {
nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
}
+ /**
+ * Gets the current transform inverted. This is a faster way to do the otherwise
+ * equivalent {@link #getMatrix(Matrix)} followed by {@link Matrix#invert(Matrix)}
+ *
+ * @param outMatrix The matrix to store the inverse transform of the RenderNode
+ */
public void getInverseMatrix(@NonNull Matrix outMatrix) {
nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
}
@@ -308,14 +325,25 @@ public class RenderNode {
// RenderProperty Setters
///////////////////////////////////////////////////////////////////////////
+ /**
+ * TODO
+ */
public boolean setLayerType(int layerType) {
return nSetLayerType(mNativeRenderNode, layerType);
}
+ /**
+ * TODO
+ */
public boolean setLayerPaint(@Nullable Paint paint) {
return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
}
+ /**
+ * Sets the clip bounds of the RenderNode.
+ * @param rect the bounds to clip to. If null, the clip bounds are reset
+ * @return True if the clip bounds changed, false otherwise
+ */
public boolean setClipBounds(@Nullable Rect rect) {
if (rect == null) {
return nSetClipBoundsEmpty(mNativeRenderNode);
@@ -371,8 +399,10 @@ public class RenderNode {
case Outline.MODE_EMPTY:
return nSetOutlineEmpty(mNativeRenderNode);
case Outline.MODE_ROUND_RECT:
- return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
- outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha);
+ return nSetOutlineRoundRect(mNativeRenderNode,
+ outline.mRect.left, outline.mRect.top,
+ outline.mRect.right, outline.mRect.bottom,
+ outline.mRadius, outline.mAlpha);
case Outline.MODE_CONVEX_PATH:
return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath,
outline.mAlpha);
@@ -381,6 +411,9 @@ public class RenderNode {
throw new IllegalArgumentException("Unrecognized outline?");
}
+ /**
+ * @return True if this RenderNode has a shadow, false otherwise
+ */
public boolean hasShadow() {
return nHasShadow(mNativeRenderNode);
}
@@ -414,6 +447,11 @@ public class RenderNode {
return nSetClipToOutline(mNativeRenderNode, clipToOutline);
}
+ /**
+ * See {@link #setClipToOutline(boolean)}
+ *
+ * @return True if this RenderNode clips to its outline, false otherwise
+ */
public boolean getClipToOutline() {
return nGetClipToOutline(mNativeRenderNode);
}
@@ -518,10 +556,21 @@ public class RenderNode {
return nHasOverlappingRendering(mNativeRenderNode);
}
+ /**
+ * Sets the base elevation of this RenderNode in pixels
+ *
+ * @param lift the elevation in pixels
+ * @return true if the elevation changed, false if it was the same
+ */
public boolean setElevation(float lift) {
return nSetElevation(mNativeRenderNode, lift);
}
+ /**
+ * See {@link #setElevation(float)}
+ *
+ * @return The RenderNode's current elevation
+ */
public float getElevation() {
return nGetElevation(mNativeRenderNode);
}
@@ -906,9 +955,12 @@ public class RenderNode {
* bit of a kludge.
*
* @hide */
- interface AnimationHost {
+ public interface AnimationHost {
+ /** checkstyle */
void registerAnimatingRenderNode(RenderNode animator);
+ /** checkstyle */
void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator);
+ /** checkstyle */
boolean isAttached();
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 7ad207f339d1..ba47300210cd 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -27,6 +27,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
+import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
import android.graphics.fonts.SystemFonts;
import android.net.Uri;
@@ -148,7 +149,7 @@ public class Typeface {
@UnsupportedAppUsage
private @Style int mStyle = 0;
- private @IntRange(from = 0, to = android.graphics.fonts.Font.FONT_WEIGHT_MAX) int mWeight = 0;
+ private @IntRange(from = 0, to = FontStyle.FONT_WEIGHT_MAX) int mWeight = 0;
// Value for weight and italic. Indicates the value is resolved by font metadata.
// Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 6c1372ff25b4..789e38c4e650 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -39,7 +39,9 @@ import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RenderNode;
import android.os.Build;
import android.util.ArrayMap;
import android.util.AttributeSet;
@@ -50,9 +52,7 @@ import android.util.PathParser;
import android.util.Property;
import android.util.TimeUtils;
import android.view.Choreographer;
-import android.view.DisplayListCanvas;
import android.view.NativeVectorDrawableAnimator;
-import android.view.RenderNode;
import android.view.RenderNodeAnimatorSetHelper;
import android.view.View;
@@ -1542,11 +1542,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
}
/**
- * Holds a weak reference to the target that was last seen (through the DisplayListCanvas
+ * Holds a weak reference to the target that was last seen (through the RecordingCanvas
* in the last draw call), so that when animator set needs to start, we can add the animator
* to the last seen RenderNode target and start right away.
*/
- protected void recordLastSeenTarget(DisplayListCanvas canvas) {
+ protected void recordLastSeenTarget(RecordingCanvas canvas) {
final RenderNode node = RenderNodeAnimatorSetHelper.getTarget(canvas);
mLastSeenTarget = new WeakReference<RenderNode>(node);
// Add the animator to the list of animators on every draw
@@ -1742,7 +1742,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
@Override
public void onDraw(Canvas canvas) {
if (canvas.isHardwareAccelerated()) {
- recordLastSeenTarget((DisplayListCanvas) canvas);
+ recordLastSeenTarget((RecordingCanvas) canvas);
}
}
diff --git a/graphics/java/android/graphics/drawable/RippleComponent.java b/graphics/java/android/graphics/drawable/RippleComponent.java
index 626bcee9454b..c1f8798faaeb 100644
--- a/graphics/java/android/graphics/drawable/RippleComponent.java
+++ b/graphics/java/android/graphics/drawable/RippleComponent.java
@@ -16,15 +16,8 @@
package android.graphics.drawable;
-import android.animation.Animator;
-import android.graphics.Canvas;
-import android.graphics.Paint;
import android.graphics.Rect;
import android.util.DisplayMetrics;
-import android.view.DisplayListCanvas;
-import android.view.RenderNodeAnimator;
-
-import java.util.ArrayList;
/**
* Abstract class that handles size & positioning common to the ripple & focus states.
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index a8dc34af292b..cce9ba31929f 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -23,10 +23,10 @@ import android.animation.TimeInterpolator;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.util.FloatProperty;
import android.util.MathUtils;
-import android.view.DisplayListCanvas;
import android.view.RenderNodeAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
@@ -132,7 +132,7 @@ class RippleForeground extends RippleComponent {
}
}
- private void startPending(DisplayListCanvas c) {
+ private void startPending(RecordingCanvas c) {
if (!mPendingHwAnimators.isEmpty()) {
for (int i = 0; i < mPendingHwAnimators.size(); i++) {
RenderNodeAnimator animator = mPendingHwAnimators.get(i);
@@ -164,7 +164,7 @@ class RippleForeground extends RippleComponent {
}
}
- private void drawHardware(DisplayListCanvas c, Paint p) {
+ private void drawHardware(RecordingCanvas c, Paint p) {
startPending(c);
pruneHwFinished();
if (mPropPaint != null) {
@@ -332,11 +332,11 @@ class RippleForeground extends RippleComponent {
* @param p the paint used to draw the ripple
*/
public void draw(Canvas c, Paint p) {
- final boolean hasDisplayListCanvas = !mForceSoftware && c instanceof DisplayListCanvas;
+ final boolean hasDisplayListCanvas = !mForceSoftware && c instanceof RecordingCanvas;
pruneSwFinished();
if (hasDisplayListCanvas) {
- final DisplayListCanvas hw = (DisplayListCanvas) c;
+ final RecordingCanvas hw = (RecordingCanvas) c;
drawHardware(hw, p);
} else {
drawSoftware(c, p);
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index bd1ac25bf8df..f426b2d3465b 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -51,61 +51,6 @@ public final class Font {
private static final int STYLE_NORMAL = 0;
/**
- * A minimum weight value for the font
- */
- public static final int FONT_WEIGHT_MIN = 1;
-
- /**
- * A font weight value for the thin weight
- */
- public static final int FONT_WEIGHT_THIN = 100;
-
- /**
- * A font weight value for the extra-light weight
- */
- public static final int FONT_WEIGHT_EXTRA_LIGHT = 200;
-
- /**
- * A font weight value for the light weight
- */
- public static final int FONT_WEIGHT_LIGHT = 300;
-
- /**
- * A font weight value for the normal weight
- */
- public static final int FONT_WEIGHT_NORMAL = 400;
-
- /**
- * A font weight value for the medium weight
- */
- public static final int FONT_WEIGHT_MEDIUM = 500;
-
- /**
- * A font weight value for the semi-bold weight
- */
- public static final int FONT_WEIGHT_SEMI_BOLD = 600;
-
- /**
- * A font weight value for the bold weight.
- */
- public static final int FONT_WEIGHT_BOLD = 700;
-
- /**
- * A font weight value for the extra-bold weight
- */
- public static final int FONT_WEIGHT_EXTRA_BOLD = 800;
-
- /**
- * A font weight value for the black weight
- */
- public static final int FONT_WEIGHT_BLACK = 900;
-
- /**
- * A maximum weight value for the font
- */
- public static final int FONT_WEIGHT_MAX = 1000;
-
- /**
* A builder class for creating new Font.
*/
public static class Builder {
@@ -275,66 +220,68 @@ public final class Font {
* <tr>
* <td align="center">100</td>
* <td align="center">Thin</td>
- * <td align="center">{@link Font#FONT_WEIGHT_THIN}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_THIN}</td>
* </tr>
* <tr>
* <td align="center">200</td>
* <td align="center">Extra Light (Ultra Light)</td>
- * <td align="center">{@link Font#FONT_WEIGHT_EXTRA_LIGHT}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_LIGHT}</td>
* </tr>
* <tr>
* <td align="center">300</td>
* <td align="center">Light</td>
- * <td align="center">{@link Font#FONT_WEIGHT_LIGHT}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_LIGHT}</td>
* </tr>
* <tr>
* <td align="center">400</td>
* <td align="center">Normal (Regular)</td>
- * <td align="center">{@link Font#FONT_WEIGHT_NORMAL}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_NORMAL}</td>
* </tr>
* <tr>
* <td align="center">500</td>
* <td align="center">Medium</td>
- * <td align="center">{@link Font#FONT_WEIGHT_MEDIUM}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_MEDIUM}</td>
* </tr>
* <tr>
* <td align="center">600</td>
* <td align="center">Semi Bold (Demi Bold)</td>
- * <td align="center">{@link Font#FONT_WEIGHT_SEMI_BOLD}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_SEMI_BOLD}</td>
* </tr>
* <tr>
* <td align="center">700</td>
* <td align="center">Bold</td>
- * <td align="center">{@link Font#FONT_WEIGHT_BOLD}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_BOLD}</td>
* </tr>
* <tr>
* <td align="center">800</td>
* <td align="center">Extra Bold (Ultra Bold)</td>
- * <td align="center">{@link Font#FONT_WEIGHT_EXTRA_BOLD}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_BOLD}</td>
* </tr>
* <tr>
* <td align="center">900</td>
* <td align="center">Black (Heavy)</td>
- * <td align="center">{@link Font#FONT_WEIGHT_BLACK}</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_BLACK}</td>
* </tr>
* </tbody>
* </p>
*
- * @see Font#FONT_WEIGHT_THIN
- * @see Font#FONT_WEIGHT_EXTRA_LIGHT
- * @see Font#FONT_WEIGHT_LIGHT
- * @see Font#FONT_WEIGHT_NORMAL
- * @see Font#FONT_WEIGHT_MEDIUM
- * @see Font#FONT_WEIGHT_SEMI_BOLD
- * @see Font#FONT_WEIGHT_BOLD
- * @see Font#FONT_WEIGHT_EXTRA_BOLD
- * @see Font#FONT_WEIGHT_BLACK
+ * @see FontStyle#FONT_WEIGHT_THIN
+ * @see FontStyle#FONT_WEIGHT_EXTRA_LIGHT
+ * @see FontStyle#FONT_WEIGHT_LIGHT
+ * @see FontStyle#FONT_WEIGHT_NORMAL
+ * @see FontStyle#FONT_WEIGHT_MEDIUM
+ * @see FontStyle#FONT_WEIGHT_SEMI_BOLD
+ * @see FontStyle#FONT_WEIGHT_BOLD
+ * @see FontStyle#FONT_WEIGHT_EXTRA_BOLD
+ * @see FontStyle#FONT_WEIGHT_BLACK
* @param weight a weight value
* @return this builder
*/
public @NonNull Builder setWeight(
- @IntRange(from = FONT_WEIGHT_MIN, to = FONT_WEIGHT_MAX) int weight) {
- Preconditions.checkArgument(FONT_WEIGHT_MIN <= weight && weight <= FONT_WEIGHT_MAX);
+ @IntRange(from = FontStyle.FONT_WEIGHT_MIN, to = FontStyle.FONT_WEIGHT_MAX)
+ int weight) {
+ Preconditions.checkArgument(
+ FontStyle.FONT_WEIGHT_MIN <= weight && weight <= FontStyle.FONT_WEIGHT_MAX);
mWeight = weight;
return this;
}
@@ -346,13 +293,12 @@ public final class Font {
* will resolve the style by reading font tables.
*
* For example, if you want to use italic font as upright font, call {@code
- * setItalic(false)} explicitly.
+ * setSlant(false)} explicitly.
*
- * @param italic {@code true} if the font is italic. Otherwise {@code false}.
* @return this builder
*/
- public @NonNull Builder setItalic(boolean italic) {
- mItalic = italic ? STYLE_ITALIC : STYLE_NORMAL;
+ public @NonNull Builder setSlant(@FontStyle.FontSlant int slant) {
+ mItalic = slant == FontStyle.FONT_SLANT_UPRIGHT ? STYLE_NORMAL : STYLE_ITALIC;
return this;
}
@@ -414,8 +360,11 @@ public final class Font {
mItalic = STYLE_NORMAL;
}
}
- mWeight = Math.max(FONT_WEIGHT_MIN, Math.min(FONT_WEIGHT_MAX, mWeight));
+ mWeight = Math.max(FontStyle.FONT_WEIGHT_MIN,
+ Math.min(FontStyle.FONT_WEIGHT_MAX, mWeight));
final boolean italic = (mItalic == STYLE_ITALIC);
+ final int slant = (mItalic == STYLE_ITALIC)
+ ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT;
final long builderPtr = nInitBuilder();
if (mAxes != null) {
for (FontVariationAxis axis : mAxes) {
@@ -424,8 +373,8 @@ public final class Font {
}
final ByteBuffer readonlyBuffer = mBuffer.asReadOnlyBuffer();
final long ptr = nBuild(builderPtr, readonlyBuffer, mWeight, italic, mTtcIndex);
- final Font font = new Font(ptr, readonlyBuffer, mFile, mWeight, italic, mTtcIndex,
- mAxes, mLocaleList);
+ final Font font = new Font(ptr, readonlyBuffer, mFile,
+ new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList);
sFontRegistory.registerNativeAllocation(font, ptr);
return font;
}
@@ -454,8 +403,7 @@ public final class Font {
private final long mNativePtr; // address of the shared ptr of minikin::Font
private final @NonNull ByteBuffer mBuffer;
private final @Nullable File mFile;
- private final @IntRange(from = 0, to = 1000) int mWeight;
- private final boolean mItalic;
+ private final FontStyle mFontStyle;
private final @IntRange(from = 0) int mTtcIndex;
private final @Nullable FontVariationAxis[] mAxes;
private final @NonNull String mLocaleList;
@@ -464,13 +412,11 @@ public final class Font {
* Use Builder instead
*/
private Font(long nativePtr, @NonNull ByteBuffer buffer, @Nullable File file,
- @IntRange(from = 0, to = 1000) int weight, boolean italic,
- @IntRange(from = 0) int ttcIndex, @Nullable FontVariationAxis[] axes,
- @NonNull String localeList) {
+ @NonNull FontStyle fontStyle, @IntRange(from = 0) int ttcIndex,
+ @Nullable FontVariationAxis[] axes, @NonNull String localeList) {
mBuffer = buffer;
mFile = file;
- mWeight = weight;
- mItalic = italic;
+ mFontStyle = fontStyle;
mNativePtr = nativePtr;
mTtcIndex = ttcIndex;
mAxes = axes;
@@ -504,17 +450,17 @@ public final class Font {
* @return a weight value
*/
public @IntRange(from = 0, to = 1000)int getWeight() {
- return mWeight;
+ return mFontStyle.getWeight();
}
/**
- * Returns true if this font is marked as italic, otherwise returns false.
+ * Get a slant value associated with this font.
*
- * @see Builder#setItalic(boolean)
- * @return true if italic, otherwise false
+ * @see Builder#setSlant(boolean)
+ * @return a slant value
*/
- public boolean isItalic() {
- return mItalic;
+ public @FontStyle.FontSlant int getSlant() {
+ return mFontStyle.getSlant();
}
/**
@@ -564,21 +510,20 @@ public final class Font {
return false;
}
Font f = (Font) o;
- return f.mWeight == mWeight && f.mItalic == mItalic && f.mTtcIndex == mTtcIndex
+ return mFontStyle.equals(f.mFontStyle) && f.mTtcIndex == mTtcIndex
&& Arrays.equals(f.mAxes, mAxes) && f.mBuffer.equals(mBuffer);
}
@Override
public int hashCode() {
- return Objects.hash(mWeight, mItalic, mTtcIndex, Arrays.hashCode(mAxes), mBuffer);
+ return Objects.hash(mFontStyle, mTtcIndex, Arrays.hashCode(mAxes), mBuffer);
}
@Override
public String toString() {
return "Font {"
+ "path=" + mFile
- + ", weight=" + mWeight
- + ", italic=" + mItalic
+ + ", style=" + mFontStyle
+ ", ttcIndex=" + mTtcIndex
+ ", axes=" + FontVariationAxis.toFontVariationSettings(mAxes)
+ ", localeList=" + mLocaleList
diff --git a/graphics/java/android/graphics/fonts/FontFamily.java b/graphics/java/android/graphics/fonts/FontFamily.java
index 3bcdc31a3160..52a37da47cff 100644
--- a/graphics/java/android/graphics/fonts/FontFamily.java
+++ b/graphics/java/android/graphics/fonts/FontFamily.java
@@ -124,7 +124,7 @@ public final class FontFamily {
}
private static int makeStyleIdentifier(@NonNull Font font) {
- return font.getWeight() | (font.isItalic() ? (1 << 16) : 0);
+ return font.getWeight() | (font.getSlant() << 16);
}
private static native long nInitBuilder();
diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java
new file mode 100644
index 000000000000..82fc7ac01772
--- /dev/null
+++ b/graphics/java/android/graphics/fonts/FontStyle.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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 android.graphics.fonts;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.Nullable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * A font style object.
+ *
+ * This class represents a single font style which is a pair of weight value and slant value.
+ * Here are common font styles examples:
+ * <p>
+ * <pre>
+ * <code>
+ * final FontStyle NORMAL = new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT);
+ * final FontStyle BOLD = new FontStyle(FONT_WEIGHT_BOLD, FONT_SLANT_UPRIGHT);
+ * final FontStyle ITALIC = new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC);
+ * final FontStyle BOLD_ITALIC = new FontStyle(FONT_WEIGHT_BOLD, FONT_SLANT_ITALIC);
+ * </code>
+ * </pre>
+ * </p>
+ *
+ */
+public final class FontStyle {
+ private static final String TAG = "FontStyle";
+
+ /**
+ * A minimum weight value for the font
+ */
+ public static final int FONT_WEIGHT_MIN = 1;
+
+ /**
+ * A font weight value for the thin weight
+ */
+ public static final int FONT_WEIGHT_THIN = 100;
+
+ /**
+ * A font weight value for the extra-light weight
+ */
+ public static final int FONT_WEIGHT_EXTRA_LIGHT = 200;
+
+ /**
+ * A font weight value for the light weight
+ */
+ public static final int FONT_WEIGHT_LIGHT = 300;
+
+ /**
+ * A font weight value for the normal weight
+ */
+ public static final int FONT_WEIGHT_NORMAL = 400;
+
+ /**
+ * A font weight value for the medium weight
+ */
+ public static final int FONT_WEIGHT_MEDIUM = 500;
+
+ /**
+ * A font weight value for the semi-bold weight
+ */
+ public static final int FONT_WEIGHT_SEMI_BOLD = 600;
+
+ /**
+ * A font weight value for the bold weight.
+ */
+ public static final int FONT_WEIGHT_BOLD = 700;
+
+ /**
+ * A font weight value for the extra-bold weight
+ */
+ public static final int FONT_WEIGHT_EXTRA_BOLD = 800;
+
+ /**
+ * A font weight value for the black weight
+ */
+ public static final int FONT_WEIGHT_BLACK = 900;
+
+ /**
+ * A maximum weight value for the font
+ */
+ public static final int FONT_WEIGHT_MAX = 1000;
+
+ /**
+ * A font slant value for upright
+ */
+ public static final int FONT_SLANT_UPRIGHT = 0;
+
+ /**
+ * A font slant value for italic
+ */
+ public static final int FONT_SLANT_ITALIC = 1;
+
+ // TODO: Support FONT_SLANT_OBLIQUE
+
+ /** @hide */
+ @IntDef(prefix = { "FONT_SLANT_" }, value = {
+ FONT_SLANT_UPRIGHT,
+ FONT_SLANT_ITALIC
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FontSlant {}
+
+ private final @IntRange(from = 0, to = 1000) int mWeight;
+ private final @FontSlant int mSlant;
+ // TODO: Support width
+
+ public FontStyle() {
+ mWeight = FONT_WEIGHT_NORMAL;
+ mSlant = FONT_SLANT_UPRIGHT;
+ }
+
+ /**
+ * Create FontStyle with specific weight and italic
+ *
+ * <p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="center">Value</th>
+ * <th align="center">Name</th>
+ * <th align="center">Android Definition</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td align="center">100</td>
+ * <td align="center">Thin</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_THIN}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">200</td>
+ * <td align="center">Extra Light (Ultra Light)</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_LIGHT}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">300</td>
+ * <td align="center">Light</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_LIGHT}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">400</td>
+ * <td align="center">Normal (Regular)</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_NORMAL}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">500</td>
+ * <td align="center">Medium</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_MEDIUM}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">600</td>
+ * <td align="center">Semi Bold (Demi Bold)</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_SEMI_BOLD}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">700</td>
+ * <td align="center">Bold</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_BOLD}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">800</td>
+ * <td align="center">Extra Bold (Ultra Bold)</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_BOLD}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">900</td>
+ * <td align="center">Black (Heavy)</td>
+ * <td align="center">{@link FontStyle#FONT_WEIGHT_BLACK}</td>
+ * </tr>
+ * </tbody>
+ * </p>
+ *
+ * @see FontStyle#FONT_WEIGHT_THIN
+ * @see FontStyle#FONT_WEIGHT_EXTRA_LIGHT
+ * @see FontStyle#FONT_WEIGHT_LIGHT
+ * @see FontStyle#FONT_WEIGHT_NORMAL
+ * @see FontStyle#FONT_WEIGHT_MEDIUM
+ * @see FontStyle#FONT_WEIGHT_SEMI_BOLD
+ * @see FontStyle#FONT_WEIGHT_BOLD
+ * @see FontStyle#FONT_WEIGHT_EXTRA_BOLD
+ * @see FontStyle#FONT_WEIGHT_BLACK
+ * @param weight a weight value
+ * @param slant a slant value
+ */
+ public FontStyle(int weight, @FontSlant int slant) {
+ Preconditions.checkArgument(FONT_WEIGHT_MIN <= weight && weight <= FONT_WEIGHT_MAX,
+ "weight value must be [" + FONT_WEIGHT_MIN + ", " + FONT_WEIGHT_MAX + "]");
+ Preconditions.checkArgument(slant == FONT_SLANT_UPRIGHT || slant == FONT_SLANT_ITALIC,
+ "slant value must be FONT_SLANT_UPRIGHT or FONT_SLANT_UPRIGHT");
+ mWeight = weight;
+ mSlant = slant;
+ }
+
+
+ /**
+ * Gets the weight value
+ *
+ * @see FontStyle#setWeight(int)
+ * @return a weight value
+ */
+ public @IntRange(from = 0, to = 1000) int getWeight() {
+ return mWeight;
+ }
+
+ /**
+ * Gets the slant value
+ *
+ * @return a slant value
+ */
+ public @FontSlant int getSlant() {
+ return mSlant;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o == null || !(o instanceof FontStyle)) {
+ return false;
+ }
+ FontStyle fontStyle = (FontStyle) o;
+ return fontStyle.mWeight == mWeight && fontStyle.mSlant == mSlant;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mWeight, mSlant);
+ }
+
+ @Override
+ public String toString() {
+ return "FontStyle { weight=" + mWeight + ", slant=" + mSlant + "}";
+ }
+}
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 2d21bbbd4e43..750adb2757c8 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -192,7 +192,8 @@ public final class SystemFonts {
try {
font = new Font.Builder(buffer, new File(fullPath), languageTags)
.setWeight(fontConfig.getWeight())
- .setItalic(fontConfig.isItalic())
+ .setSlant(fontConfig.isItalic() ? FontStyle.FONT_SLANT_ITALIC
+ : FontStyle.FONT_SLANT_UPRIGHT)
.setTtcIndex(fontConfig.getTtcIndex())
.setFontVariationSettings(fontConfig.getAxes())
.build();
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 503951d1adc6..f0053a48ae3d 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -231,6 +231,9 @@ cc_defaults {
"protos/graphicsstats.proto",
],
+ // Allow implicit fallthroughs in HardwareBitmapUploader.cpp until they are fixed.
+ cflags: ["-Wno-implicit-fallthrough"],
+
proto: {
export_proto_headers: true,
},
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 0022c931c45e..c6e4c154b41e 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -141,7 +141,7 @@ uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) {
// select only flags that might affect text layout
flags &= (SkPaint::kAntiAlias_Flag | SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag |
SkPaint::kSubpixelText_Flag | SkPaint::kEmbeddedBitmapText_Flag |
- SkPaint::kAutoHinting_Flag | SkPaint::kVerticalText_Flag);
+ SkPaint::kAutoHinting_Flag);
flags |= (hinting << 16);
return flags;
}
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index e3c97ce686d9..524dfb0fe4ef 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -288,7 +288,7 @@ void parseOptions(int argc, char* argv[]) {
case '?':
fprintf(stderr, "Unrecognized option '%s'\n", argv[optind - 1]);
- // fall-through
+ [[fallthrough]];
default:
error = true;
break;
diff --git a/opengl/java/android/opengl/EGL15.java b/opengl/java/android/opengl/EGL15.java
index 9aae6ad0f080..f855fe2591e1 100644
--- a/opengl/java/android/opengl/EGL15.java
+++ b/opengl/java/android/opengl/EGL15.java
@@ -146,4 +146,22 @@ public class EGL15 {
int flags
);
+ // C function EGLImage eglCreateImage ( EGLDisplay dpy, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list )
+
+ public static native EGLImage eglCreateImage(
+ EGLDisplay dpy,
+ EGLContext context,
+ int target,
+ long buffer,
+ long[] attrib_list,
+ int offset
+ );
+
+ // C function EGLBoolean eglDestroyImage ( EGLDisplay dpy, EGLImage image )
+
+ public static native boolean eglDestroyImage(
+ EGLDisplay dpy,
+ EGLImage image
+ );
+
}
diff --git a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java b/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
index 5782ea100070..31c9224a8489 100644
--- a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
@@ -66,7 +66,7 @@ public class AgingHelper {
public void onNotificationSeen(NotificationEntry entry) {
// user has strong opinions about this notification. we can't down rank it, so don't bother.
- if (entry.getChannel().isImportanceLocked()) {
+ if (entry.getChannel().hasUserSetImportance()) {
return;
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
index 19e8673fba89..114d69e35e39 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
@@ -27,6 +27,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper;
/**
* Background task resource loader
*/
+@Deprecated
class BackgroundTaskLoader implements Runnable {
static String TAG = "BackgroundTaskLoader";
static boolean DEBUG = false;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java
index 898d64a1ea1a..7e0f8fe2e033 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java
@@ -27,6 +27,7 @@ import java.util.List;
/**
* A list of filtered tasks.
*/
+@Deprecated
class FilteredTaskList {
private final ArrayList<Task> mTasks = new ArrayList<>();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java
index 852463ffc188..f02bc5ab15e1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java
@@ -34,6 +34,7 @@ import java.util.ArrayList;
/**
* Loader class that loads full-resolution thumbnails when appropriate.
*/
+@Deprecated
public class HighResThumbnailLoader implements
TaskCallbacks, BackgroundTaskLoader.OnIdleChangedListener {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
index f69e91145dfc..8b3ae42ef479 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
@@ -45,6 +45,7 @@ import java.util.List;
* 3) executePlan() will actually load and fill in the icons and thumbnails according to the load
* options specified, such that we can transition into the Recents activity seamlessly
*/
+@Deprecated
public class RecentsTaskLoadPlan {
/** The set of conditions to preload tasks. */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
index 996c837ba121..b50aa76e1d0d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
@@ -42,6 +42,7 @@ import java.util.Map;
/**
* Recents task loader
*/
+@Deprecated
public class RecentsTaskLoader {
private static final String TAG = "RecentsTaskLoader";
private static final boolean DEBUG = false;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index b51004bf6d56..368e50362cd6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -16,6 +16,7 @@
package com.android.systemui.shared.recents.model;
+import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.content.ComponentName;
import android.content.Intent;
@@ -31,13 +32,14 @@ import java.util.ArrayList;
import java.util.Objects;
/**
- * A task represents the top most task in the system's task stack.
+ * A task in the recent tasks list.
*/
public class Task {
public static final String TAG = "Task";
/* Task callbacks */
+ @Deprecated
public interface TaskCallbacks {
/* Notifies when a task has been bound */
void onTaskDataLoaded(Task task, ThumbnailData thumbnailData);
@@ -65,6 +67,21 @@ public class Task {
private int mHashCode;
+ public TaskKey(ActivityManager.RecentTaskInfo t) {
+ ComponentName sourceComponent = t.origActivity != null
+ // Activity alias if there is one
+ ? t.origActivity
+ // The real activity if there is no alias (or the target if there is one)
+ : t.realActivity;
+ this.id = t.taskId;
+ this.windowingMode = t.configuration.windowConfiguration.getWindowingMode();
+ this.baseIntent = t.baseIntent;
+ this.sourceComponent = sourceComponent;
+ this.userId = t.userId;
+ this.lastActiveTime = t.lastActiveTime;
+ updateHashCode();
+ }
+
public TaskKey(int id, int windowingMode, Intent intent,
ComponentName sourceComponent, int userId, long lastActiveTime) {
this.id = id;
@@ -125,7 +142,8 @@ public class Task {
/**
* The temporary sort index in the stack, used when ordering the stack.
*/
- public int temporarySortIndexInStack;
+ @Deprecated
+ int temporarySortIndexInStack;
/**
* The icon is the task description icon (if provided), which falls back to the activity icon,
@@ -134,6 +152,7 @@ public class Task {
public Drawable icon;
public ThumbnailData thumbnail;
@ViewDebug.ExportedProperty(category="recents")
+ @Deprecated
public String title;
@ViewDebug.ExportedProperty(category="recents")
public String titleDescription;
@@ -142,6 +161,7 @@ public class Task {
@ViewDebug.ExportedProperty(category="recents")
public int colorBackground;
@ViewDebug.ExportedProperty(category="recents")
+ @Deprecated
public boolean useLightOnPrimaryColor;
/**
@@ -153,10 +173,13 @@ public class Task {
* The state isLaunchTarget will be set for the correct task upon launching Recents.
*/
@ViewDebug.ExportedProperty(category="recents")
+ @Deprecated
public boolean isLaunchTarget;
@ViewDebug.ExportedProperty(category="recents")
+ @Deprecated
public boolean isStackTask;
@ViewDebug.ExportedProperty(category="recents")
+ @Deprecated
public boolean isSystemApp;
@ViewDebug.ExportedProperty(category="recents")
public boolean isDockable;
@@ -165,6 +188,7 @@ public class Task {
* Resize mode. See {@link ActivityInfo#resizeMode}.
*/
@ViewDebug.ExportedProperty(category="recents")
+ @Deprecated
public int resizeMode;
@ViewDebug.ExportedProperty(category="recents")
@@ -173,12 +197,31 @@ public class Task {
@ViewDebug.ExportedProperty(category="recents")
public boolean isLocked;
+ @Deprecated
private ArrayList<TaskCallbacks> mCallbacks = new ArrayList<>();
public Task() {
// Do nothing
}
+ public Task(TaskKey key) {
+ this.key = key;
+ this.taskDescription = new TaskDescription();
+ }
+
+ public Task(TaskKey key, int colorPrimary, int colorBackground,
+ boolean isDockable, boolean isLocked, TaskDescription taskDescription,
+ ComponentName topActivity) {
+ this.key = key;
+ this.colorPrimary = colorPrimary;
+ this.colorBackground = colorBackground;
+ this.taskDescription = taskDescription;
+ this.isDockable = isDockable;
+ this.isLocked = isLocked;
+ this.topActivity = topActivity;
+ }
+
+ @Deprecated
public Task(TaskKey key, Drawable icon, ThumbnailData thumbnail, String title,
String titleDescription, int colorPrimary, int colorBackground, boolean isLaunchTarget,
boolean isStackTask, boolean isSystemApp, boolean isDockable,
@@ -206,6 +249,7 @@ public class Task {
/**
* Copies the metadata from another task, but retains the current callbacks.
*/
+ @Deprecated
public void copyFrom(Task o) {
this.key = o.key;
this.icon = o.icon;
@@ -228,6 +272,7 @@ public class Task {
/**
* Add a callback.
*/
+ @Deprecated
public void addCallback(TaskCallbacks cb) {
if (!mCallbacks.contains(cb)) {
mCallbacks.add(cb);
@@ -237,11 +282,13 @@ public class Task {
/**
* Remove a callback.
*/
+ @Deprecated
public void removeCallback(TaskCallbacks cb) {
mCallbacks.remove(cb);
}
/** Updates the task's windowing mode. */
+ @Deprecated
public void setWindowingMode(int windowingMode) {
key.setWindowingMode(windowingMode);
int callbackCount = mCallbacks.size();
@@ -251,6 +298,7 @@ public class Task {
}
/** Notifies the callback listeners that this task has been loaded */
+ @Deprecated
public void notifyTaskDataLoaded(ThumbnailData thumbnailData, Drawable applicationIcon) {
this.icon = applicationIcon;
this.thumbnail = thumbnailData;
@@ -261,6 +309,7 @@ public class Task {
}
/** Notifies the callback listeners that this task has been unloaded */
+ @Deprecated
public void notifyTaskDataUnloaded(Drawable defaultApplicationIcon) {
icon = defaultApplicationIcon;
thumbnail = null;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java
index 5f3dcd16e074..d378189b1675 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java
@@ -21,6 +21,7 @@ import android.util.SparseArray;
/**
* An interface for a task filter to query whether a particular task should show in a stack.
*/
+@Deprecated
public interface TaskFilter {
/** Returns whether the filter accepts the specified task */
boolean acceptTask(SparseArray<Task> taskIdMap, Task t, int index);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
index 23582d4bc21d..342cb75b2c14 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
@@ -34,7 +34,7 @@ public abstract class TaskKeyCache<V> {
* Gets a specific entry in the cache with the specified key, regardless of whether the cached
* value is valid or not.
*/
- final synchronized V get(TaskKey key) {
+ public final synchronized V get(TaskKey key) {
return getCacheEntry(key.id);
}
@@ -42,7 +42,7 @@ public abstract class TaskKeyCache<V> {
* Returns the value only if the key is valid (has not been updated since the last time it was
* in the cache)
*/
- final synchronized V getAndInvalidateIfModified(TaskKey key) {
+ public final synchronized V getAndInvalidateIfModified(TaskKey key) {
TaskKey lastKey = mKeys.get(key.id);
if (lastKey != null) {
if ((lastKey.windowingMode != key.windowingMode) ||
@@ -59,7 +59,7 @@ public abstract class TaskKeyCache<V> {
}
/** Puts an entry in the cache for a specific key. */
- final synchronized void put(TaskKey key, V value) {
+ public final synchronized void put(TaskKey key, V value) {
if (key == null || value == null) {
Log.e(TAG, "Unexpected null key or value: " + key + ", " + value);
return;
@@ -70,14 +70,14 @@ public abstract class TaskKeyCache<V> {
/** Removes a cache entry for a specific key. */
- final synchronized void remove(TaskKey key) {
+ public final synchronized void remove(TaskKey key) {
// Remove the key after the cache value because we need it to make the callback
removeCacheEntry(key.id);
mKeys.remove(key.id);
}
/** Removes all the entries in the cache. */
- final synchronized void evictAll() {
+ public final synchronized void evictAll() {
evictAllCache();
mKeys.clear();
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java
index fbb6acebc8e0..6b9b9f55e49e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java
@@ -21,6 +21,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
/**
* A Task load queue
*/
+@Deprecated
class TaskResourceLoadQueue {
private final ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<>();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java
index c731ac9b8886..fd92bca7fcda 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java
@@ -33,6 +33,7 @@ import java.util.List;
/**
* The task stack contains a list of multiple tasks.
*/
+@Deprecated
public class TaskStack {
private static final String TAG = "TaskStack";
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java
index 2de7f74ba477..26f6b596e023 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java
@@ -34,6 +34,7 @@ import java.util.List;
* The generic set of animation properties to animate a {@link View}. The animation can have
* different interpolators, start delays and durations for each of the different properties.
*/
+@Deprecated
public class AnimationProps {
private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java
index 45728c403ac4..30bea32dedff 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java
@@ -27,6 +27,7 @@ import com.android.systemui.shared.recents.utilities.Utilities;
/**
* An outline provider that has a clip and outline that can be animated.
*/
+@Deprecated
public class AnimateableViewBounds extends ViewOutlineProvider {
private static final float MIN_ALPHA = 0.1f;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/KeyguardManagerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/KeyguardManagerCompat.java
new file mode 100644
index 000000000000..c42e7e3fd216
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/KeyguardManagerCompat.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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.systemui.shared.system;
+
+import android.app.KeyguardManager;
+import android.content.Context;
+
+public class KeyguardManagerCompat {
+ private final KeyguardManager mKeyguardManager;
+
+ public KeyguardManagerCompat(Context context) {
+ mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
+ }
+
+ public boolean isDeviceLocked(int userId) {
+ return mKeyguardManager.isDeviceLocked(userId);
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java
new file mode 100644
index 000000000000..a5299038d3a9
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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.systemui.shared.system;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+
+public class RecentTaskInfoCompat {
+
+ private ActivityManager.RecentTaskInfo mInfo;
+
+ public RecentTaskInfoCompat(ActivityManager.RecentTaskInfo info) {
+ mInfo = info;
+ }
+
+ public int getUserId() {
+ return mInfo.userId;
+ }
+
+ public boolean supportsSplitScreenMultiWindow() {
+ return mInfo.supportsSplitScreenMultiWindow;
+ }
+
+ public ComponentName getTopActivity() {
+ return mInfo.topActivity;
+ }
+
+ public ActivityManager.TaskDescription getTaskDescription() {
+ return mInfo.taskDescription;
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java
new file mode 100644
index 000000000000..eaf8d9b57398
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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.systemui.shared.system;
+
+import android.app.ActivityManager;
+
+public class TaskDescriptionCompat {
+
+ private ActivityManager.TaskDescription mTaskDescription;
+
+ public TaskDescriptionCompat(ActivityManager.TaskDescription td) {
+ mTaskDescription = td;
+ }
+
+ public int getPrimaryColor() {
+ return mTaskDescription != null
+ ? mTaskDescription.getPrimaryColor()
+ : 0;
+ }
+
+ public int getBackgroundColor() {
+ return mTaskDescription != null
+ ? mTaskDescription.getBackgroundColor()
+ : 0;
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
index b2b140e4b0a9..de2a3e44841e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
@@ -17,7 +17,7 @@ package com.android.systemui.shared.system;
import android.graphics.Canvas;
import android.graphics.Rect;
-import android.view.DisplayListCanvas;
+import android.graphics.RecordingCanvas;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.WindowCallbacks;
@@ -55,7 +55,7 @@ public class WindowCallbacksCompat {
}
@Override
- public void onPostDraw(DisplayListCanvas canvas) {
+ public void onPostDraw(RecordingCanvas canvas) {
WindowCallbacksCompat.this.onPostDraw(canvas);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 77f4bf529f21..d8eb96504e79 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -30,7 +30,7 @@ import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
-import android.view.DisplayListCanvas;
+import android.graphics.RecordingCanvas;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.WindowManager;
@@ -381,7 +381,7 @@ public class ImageWallpaper extends WallpaperService {
try {
Bitmap wallpaper = mWallpaperManager.getBitmap(true /* hardware */);
if (wallpaper != null
- && wallpaper.getByteCount() > DisplayListCanvas.MAX_BITMAP_SIZE) {
+ && wallpaper.getByteCount() > RecordingCanvas.MAX_BITMAP_SIZE) {
throw new RuntimeException("Wallpaper is too large to draw!");
}
return wallpaper;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index bb059809be2b..1e61a77a76cf 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -47,6 +47,12 @@ public interface DozeHost {
void onIgnoreTouchWhilePulsing(boolean ignore);
+ /**
+ * If the device was waken up by a passive interrupt that will show the lock screen without
+ * expanding the notification panel/shade.
+ */
+ void setPassiveInterrupt(boolean lightInterrupt);
+
interface Callback {
/**
* Called when a high priority notification is added.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index cb91d7815be5..d69b1bfa64c3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -142,6 +142,7 @@ public class DozeTriggers implements DozeMachine.Part {
mDozeHost.onDoubleTap(screenX, screenY);
mMachine.wakeUp();
} else if (isPickup || isWakeLockScreen) {
+ mDozeHost.setPassiveInterrupt(true);
mMachine.wakeUp();
} else {
mDozeHost.extendPulse();
@@ -210,6 +211,7 @@ public class DozeTriggers implements DozeMachine.Part {
case INITIALIZED:
mBroadcastReceiver.register(mContext);
mDozeHost.addCallback(mHostCallback);
+ mDozeHost.setPassiveInterrupt(false);
checkTriggersAtInit();
break;
case DOZE:
@@ -219,6 +221,7 @@ public class DozeTriggers implements DozeMachine.Part {
mDozeSensors.reregisterAllSensors();
}
mDozeSensors.setListening(true);
+ mDozeHost.setPassiveInterrupt(false);
break;
case DOZE_AOD_PAUSED:
case DOZE_AOD_PAUSING:
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
index f217596bd4a9..5bb5b2da32b4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
@@ -16,7 +16,6 @@
package com.android.systemui.recents.views;
-import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.graphics.Point;
@@ -25,14 +24,11 @@ import android.util.SparseArray;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.TaskStack;
public class TaskViewAccessibilityDelegate extends View.AccessibilityDelegate {
private static final String TAG = "TaskViewAccessibilityDelegate";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 30d9ef7bd7a3..8526afd34514 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -131,7 +131,7 @@ public class DragDownHelper implements Gefingerpoken {
if (!isFalseTouch() && mDragDownCallback.onDraggedDown(mStartingChild,
(int) (y - mInitialTouchY))) {
if (mStartingChild == null) {
- mDragDownCallback.setEmptyDragAmount(0f);
+ cancelExpansion();
} else {
mCallback.setUserLockedChild(mStartingChild, false);
mStartingChild = null;
@@ -206,11 +206,8 @@ public class DragDownHelper implements Gefingerpoken {
ValueAnimator anim = ValueAnimator.ofFloat(mLastHeight, 0);
anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS);
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue());
- }
+ anim.addUpdateListener(animation -> {
+ mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue());
});
anim.start();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 18151d0e794a..1f576342d5cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -29,9 +29,9 @@ import android.graphics.CanvasProperty;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
+import android.graphics.RecordingCanvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.view.DisplayListCanvas;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.ViewAnimationUtils;
@@ -192,8 +192,8 @@ public class KeyguardAffordanceView extends ImageView {
// Our hardware drawing proparties can be null if the finishing started but we have
// never drawn before. In that case we are not doing a render thread animation
// anyway, so we need to use the normal drawing.
- DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
- displayListCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius,
+ RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
+ recordingCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius,
mHwCirclePaint);
} else {
updateCircleColor();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 7fa042655e53..1495abf9310c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -793,7 +793,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
private void setOpenedAmount(float openedAmount) {
mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f;
mOpenedAmount = openedAmount;
- if (!mAmbientState.isPanelFullWidth()) {
+ if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDark()) {
// We don't do a transformation at all, lets just assume we are fully opened
openedAmount = 1.0f;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 0bc54a33347c..659f6c75c703 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -5654,19 +5654,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@Override
public boolean onDraggedDown(View startingChild, int dragLengthY) {
if (mStatusBarState == StatusBarState.KEYGUARD
- && hasActiveNotifications() && (!mStatusBar.isDozing()
- || mStatusBar.isPulsing())) {
+ && hasActiveNotifications()) {
mLockscreenGestureLogger.write(
MetricsEvent.ACTION_LS_SHADE,
(int) (dragLengthY / mDisplayMetrics.density),
0 /* velocityDp - N/A */);
- // We have notifications, go to locked shade.
- mStatusBar.goToLockedShade(startingChild);
- if (startingChild instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
- row.onExpandedByGesture(true /* drag down is always an open */);
+ if (mNotificationPanel.onDraggedDown() || startingChild != null) {
+ // We have notifications, go to locked shade.
+ mStatusBar.goToLockedShade(startingChild);
+ if (startingChild instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
+ row.onExpandedByGesture(true /* drag down is always an open */);
+ }
}
+
return true;
} else {
// abort gesture.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 33bc164d807c..836a55fde0f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -108,11 +108,7 @@ public class KeyguardClockPositionAlgorithm {
* Dozing and receiving a notification (AOD notification.)
*/
private boolean mPulsing;
-
- /**
- * Distance in pixels between the top of the screen and the first view of the bouncer.
- */
- private int mBouncerTop;
+ private float mEmptyDragAmount;
/**
* Refreshes the dimension values.
@@ -131,9 +127,8 @@ public class KeyguardClockPositionAlgorithm {
}
public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
- float panelExpansion, int parentHeight,
- int keyguardStatusHeight, float dark, boolean secure, boolean pulsing,
- int bouncerTop) {
+ float panelExpansion, int parentHeight, int keyguardStatusHeight, float dark,
+ boolean secure, boolean pulsing, float emptyDragAmount) {
mMinTopMargin = minTopMargin + mContainerTopPadding;
mMaxShadeBottom = maxShadeBottom;
mNotificationStackHeight = notificationStackHeight;
@@ -143,7 +138,7 @@ public class KeyguardClockPositionAlgorithm {
mDarkAmount = dark;
mCurrentlySecure = secure;
mPulsing = pulsing;
- mBouncerTop = bouncerTop;
+ mEmptyDragAmount = emptyDragAmount;
}
public void run(Result result) {
@@ -194,15 +189,14 @@ public class KeyguardClockPositionAlgorithm {
}
float clockYRegular = getExpandedClockPosition();
- boolean hasEnoughSpace = mMinTopMargin + mKeyguardStatusHeight < mBouncerTop;
- float clockYTarget = mCurrentlySecure && hasEnoughSpace ?
- mMinTopMargin : -mKeyguardStatusHeight;
+ float clockYBouncer = -mKeyguardStatusHeight;
// Move clock up while collapsing the shade
float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(mPanelExpansion);
- final float clockY = MathUtils.lerp(clockYTarget, clockYRegular, shadeExpansion);
+ float clockY = MathUtils.lerp(clockYBouncer, clockYRegular, shadeExpansion);
+ clockYDark = MathUtils.lerp(clockYBouncer, clockYDark, shadeExpansion);
- return (int) MathUtils.lerp(clockY, clockYDark, mDarkAmount);
+ return (int) (MathUtils.lerp(clockY, clockYDark, mDarkAmount) + mEmptyDragAmount);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 75077029c16b..e31bad65dbb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -38,6 +38,7 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.PowerManager;
+import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
@@ -104,6 +105,11 @@ public class NotificationPanelView extends PanelView implements
private static final boolean DEBUG = false;
+ private static final boolean EXPAND_ON_WAKE_UP = SystemProperties.getBoolean(
+ "persist.sysui.expand_shade_on_wake_up", true);
+ private static final boolean WAKE_UP_TO_SHADE = SystemProperties.getBoolean(
+ "persist.sysui.go_to_shade_on_wake_up", true);
+
/**
* Fling expanding QS.
*/
@@ -280,6 +286,12 @@ public class NotificationPanelView extends PanelView implements
*/
private float mLinearDarkAmount;
+ /**
+ * State where the device isn't dozing anymore, but the lock screen isn't fully awake.
+ * The screen will be dimmed down with the shade collapsed.
+ */
+ private boolean mSemiAwake;
+
private float mDarkAmountTarget;
private boolean mPulsing;
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
@@ -573,7 +585,7 @@ public class NotificationPanelView extends PanelView implements
mInterpolatedDarkAmount,
mStatusBar.isKeyguardCurrentlySecure(),
mPulsing,
- mBouncerTop);
+ mEmptyDragAmount);
mClockPositionAlgorithm.run(mClockPositionResult);
PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.X,
mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock);
@@ -1235,6 +1247,12 @@ public class NotificationPanelView extends PanelView implements
if (keyguardShowing) {
updateDozingVisibilities(false /* animate */);
}
+
+ // Expand notification shade if the device was is semi-awake state
+ if (mBarState == StatusBarState.SHADE && isSemiAwake()) {
+ mNotificationStackScroller.setDark(false /* dark */, false /* animated */,
+ null /* touchLocation */);
+ }
resetVerticalPanelPosition();
updateQsState();
}
@@ -2335,13 +2353,7 @@ public class NotificationPanelView extends PanelView implements
}
public void setEmptyDragAmount(float amount) {
- float factor = 0.8f;
- if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
- factor = 0.4f;
- } else if (!mStatusBar.hasActiveNotifications()) {
- factor = 0.4f;
- }
- mEmptyDragAmount = amount * factor;
+ mEmptyDragAmount = amount * 0.2f;
positionClockAndNotifications();
}
@@ -2769,11 +2781,14 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.setAnimationsEnabled(!disabled);
}
- public void setDozing(boolean dozing, boolean animate,
- PointF wakeUpTouchLocation) {
- mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
+ public void setDozing(boolean dozing, boolean animate, PointF wakeUpTouchLocation,
+ boolean passiveInterrupted) {
if (dozing == mDozing) return;
mDozing = dozing;
+ mSemiAwake = !EXPAND_ON_WAKE_UP && !mDozing && passiveInterrupted;
+ if (!mSemiAwake) {
+ mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
+ }
if (mBarState == StatusBarState.KEYGUARD
|| mBarState == StatusBarState.SHADE_LOCKED) {
@@ -2787,24 +2802,38 @@ public class NotificationPanelView extends PanelView implements
} else {
mDarkAnimator.cancel();
}
+ if (mSemiAwake) {
+ setDarkAmount(0, 0);
+ }
}
mDarkAmountTarget = darkAmount;
- if (animate) {
- if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) {
- mDarkInterpolator = dozing
- ? Interpolators.FAST_OUT_SLOW_IN
- : Interpolators.TOUCH_RESPONSE_REVERSE;
+ if (!mSemiAwake) {
+ if (animate) {
+ startDarkAnimation();
+ } else {
+ setDarkAmount(darkAmount, darkAmount);
}
- mNotificationStackScroller.notifyDarkAnimationStart(dozing);
- mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount);
- mDarkAnimator.setInterpolator(Interpolators.LINEAR);
- mDarkAnimator.setDuration(mNotificationStackScroller.getDarkAnimationDuration(dozing));
- mDarkAnimator.start();
- } else {
- setDarkAmount(darkAmount, darkAmount);
}
}
+ public boolean isSemiAwake() {
+ return mSemiAwake;
+ }
+
+ private void startDarkAnimation() {
+ if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) {
+ mDarkInterpolator = mDozing
+ ? Interpolators.FAST_OUT_SLOW_IN
+ : Interpolators.TOUCH_RESPONSE_REVERSE;
+ }
+ mNotificationStackScroller.notifyDarkAnimationStart(mDozing);
+ mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozing ? 1 : 0);
+ mDarkAnimator.setInterpolator(Interpolators.LINEAR);
+ mDarkAnimator.setDuration(
+ mNotificationStackScroller.getDarkAnimationDuration(mDozing));
+ mDarkAnimator.start();
+ }
+
private void setDarkAmount(float linearAmount, float amount) {
mInterpolatedDarkAmount = amount;
mLinearDarkAmount = linearAmount;
@@ -2989,4 +3018,22 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.setScrimController(scrimController);
updateShowEmptyShadeView();
}
+
+ /**
+ * Whenever a user drags down on the empty area (pulling down the shade and clock) and lets go.
+ *
+ * @return {@code true} if dragging down should take the user to SHADE_LOCKED.
+ */
+ public boolean onDraggedDown() {
+ if (isSemiAwake()) {
+ mSemiAwake = false;
+ mNotificationStackScroller.setDark(false /* dark */, true /* animate */,
+ null /* touchLocation */);
+ startDarkAnimation();
+ mStatusBar.updateScrimController();
+
+ return WAKE_UP_TO_SHADE;
+ }
+ return true;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index e3a7b75554d3..1bed26dd3474 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -63,7 +63,7 @@ import java.util.function.Consumer;
public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnColorsChangedListener,
Dumpable {
- private static final String TAG = "ScrimController";
+ static final String TAG = "ScrimController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/**
@@ -96,6 +96,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
*/
public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
/**
+ * A scrim varies its opacity based on a busyness factor, for example
+ * how many notifications are currently visible.
+ */
+ public static final float GRADIENT_SCRIM_DARK_KEYGUARD = 0.80f;
+ /**
* The most common scrim, the one under the keyguard.
*/
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
@@ -361,7 +366,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
mExpansionFraction = fraction;
final boolean keyguardOrUnlocked = mState == ScrimState.UNLOCKED
- || mState == ScrimState.KEYGUARD;
+ || mState == ScrimState.KEYGUARD || mState == ScrimState.DARK_KEYGUARD;
if (!keyguardOrUnlocked || !mExpansionAffectsAlpha) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 085f7b6394ef..ade063d9718f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -49,6 +49,8 @@ public enum ScrimState {
// fade it out afterwards.
mBlankScreen = true;
}
+ } else if (previousState == ScrimState.KEYGUARD) {
+ mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
} else {
mAnimationDuration = ScrimController.ANIMATION_DURATION;
}
@@ -59,8 +61,24 @@ public enum ScrimState {
@Override
public float getBehindAlpha(float busynessFactor) {
return MathUtils.map(0 /* start */, 1 /* stop */,
- mScrimBehindAlphaKeyguard, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
- busynessFactor);
+ mScrimBehindAlphaKeyguard, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
+ busynessFactor);
+ }
+ },
+
+ /**
+ * On semi-awake lock screen.
+ */
+ DARK_KEYGUARD(7) {
+
+ @Override
+ public void prepare(ScrimState previousState) {
+ mBlankScreen = mDisplayRequiresBlanking && previousState != ScrimState.AOD;
+ mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
+ mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_DARK_KEYGUARD;
+ mCurrentInFrontAlpha = 0;
+ mCurrentInFrontTint = Color.BLACK;
+ mCurrentBehindTint = Color.BLACK;
}
},
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index cc9adb86a6b4..56e5a1e1bd6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3617,7 +3617,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mDozeScrimController.setDozing(mDozing);
mKeyguardIndicationController.setDozing(mDozing);
- mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation);
+ mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation,
+ mDozeServiceHost.wasPassivelyInterrupted());
mNotificationLogger.setDozing(mDozing);
mGroupManager.setDozing(mDozing);
updateQsExpansionEnabled();
@@ -4203,7 +4204,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mAmbientPulseManager.releaseAllImmediately();
mVisualStabilityManager.setScreenOn(true);
mNotificationPanel.setTouchAndAnimationDisabled(false);
- mDozeServiceHost.stopDozing();
updateVisibleToUser();
updateIsKeyguard();
updateScrimController();
@@ -4401,6 +4401,9 @@ public class StatusBar extends SystemUI implements DemoMode,
// FLAG_DISMISS_KEYGUARD_ACTIVITY.
ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
+ if (mNotificationPanel.isSemiAwake()) {
+ state = ScrimState.DARK_KEYGUARD;
+ }
mScrimController.transitionTo(state);
} else if (isInLaunchTransition() || mLaunchCameraOnScreenTurningOn
|| launchingAffordanceWithPreview) {
@@ -4412,7 +4415,8 @@ public class StatusBar extends SystemUI implements DemoMode,
} else if (mDozing) {
mScrimController.transitionTo(ScrimState.AOD);
} else if (mIsKeyguard && !wakeAndUnlocking) {
- mScrimController.transitionTo(ScrimState.KEYGUARD);
+ mScrimController.transitionTo(mNotificationPanel.isSemiAwake()
+ ? ScrimState.DARK_KEYGUARD : ScrimState.KEYGUARD);
} else {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
}
@@ -4432,6 +4436,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private boolean mAnimateWakeup;
private boolean mAnimateScreenOff;
private boolean mIgnoreTouchWhilePulsing;
+ private boolean mPassivelyInterrupted;
@Override
public String toString() {
@@ -4515,6 +4520,11 @@ public class StatusBar extends SystemUI implements DemoMode,
}
@Override
+ public void setPassiveInterrupt(boolean passiveInterrupt) {
+ mPassivelyInterrupted = passiveInterrupt;
+ }
+
+ @Override
public void onIgnoreTouchWhilePulsing(boolean ignore) {
if (ignore != mIgnoreTouchWhilePulsing) {
DozeLog.tracePulseTouchDisabledByProx(mContext, ignore);
@@ -4633,6 +4643,10 @@ public class StatusBar extends SystemUI implements DemoMode,
public boolean shouldAnimateScreenOff() {
return mAnimateScreenOff;
}
+
+ public boolean wasPassivelyInterrupted() {
+ return mPassivelyInterrupted;
+ }
}
public boolean shouldIgnoreTouch() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
index 8e32a0b44c28..59bd85eaabd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -27,8 +27,7 @@ import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.os.Handler;
-import android.os.SystemProperties;
-import android.view.DisplayListCanvas;
+import android.graphics.RecordingCanvas;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.view.ViewConfiguration;
@@ -122,7 +121,7 @@ public class KeyButtonRipple extends Drawable {
public void draw(Canvas canvas) {
mSupportHardware = canvas.isHardwareAccelerated();
if (mSupportHardware) {
- drawHardware((DisplayListCanvas) canvas);
+ drawHardware((RecordingCanvas) canvas);
} else {
drawSoftware(canvas);
}
@@ -147,7 +146,7 @@ public class KeyButtonRipple extends Drawable {
return getBounds().width() > getBounds().height();
}
- private void drawHardware(DisplayListCanvas c) {
+ private void drawHardware(RecordingCanvas c) {
if (mDrawingHardwareGlow) {
c.drawRoundRect(mLeftProp, mTopProp, mRightProp, mBottomProp, mRxProp, mRyProp,
mPaintProp);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index 2398fd3c4712..6abd407afd91 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -115,6 +115,11 @@ class DozeHostFake implements DozeHost {
}
@Override
+ public void setPassiveInterrupt(boolean lightInterrupt) {
+
+ }
+
+ @Override
public void setDozeScreenBrightness(int value) {
}
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index d86de5dfd799..da1fee374520 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -6564,6 +6564,11 @@ message MetricsEvent {
// OS: Q
MOBILE_ROAMING_DIALOG = 1583;
+ // OPEN: Settings > Display > Lock screen display > On lock screen
+ // CATEGORY: SETTINGS
+ // OS: Q
+ LOCK_SCREEN_NOTIFICATION_CONTENT = 1584;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index b938f3be4926..17bf5705d489 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -32,6 +32,8 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.MathUtils;
import android.util.Slog;
+import android.util.SparseArray;
+import android.view.Display;
import android.view.MagnificationSpec;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
@@ -40,6 +42,7 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.wm.WindowManagerInternal;
@@ -55,7 +58,7 @@ import java.util.Locale;
* magnification region. If a value is out of bounds, it will be adjusted to guarantee these
* constraints.
*/
-public class MagnificationController implements Handler.Callback {
+public class MagnificationController {
private static final boolean DEBUG = false;
private static final String LOG_TAG = "MagnificationController";
@@ -64,90 +67,553 @@ public class MagnificationController implements Handler.Callback {
private static final boolean DEBUG_SET_MAGNIFICATION_SPEC = false;
- private static final int INVALID_ID = -1;
-
private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
- // Messages
- private static final int MSG_SEND_SPEC_TO_ANIMATION = 1;
- private static final int MSG_SCREEN_TURNED_OFF = 2;
- private static final int MSG_ON_MAGNIFIED_BOUNDS_CHANGED = 3;
- private static final int MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED = 4;
- private static final int MSG_ON_USER_CONTEXT_CHANGED = 5;
-
private final Object mLock;
+ private final AccessibilityManagerService mAms;
+
+ private final SettingsBridge mSettingsBridge;
+
+ private final ScreenStateObserver mScreenStateObserver;
+
+ private int mUserId;
+
+ private final long mMainThreadId;
+
+ private Handler mHandler;
+
+ private final WindowManagerInternal mWindowManager;
+
+ private final DisplayMagnification mDisplay;
+
/**
- * The current magnification spec. If an animation is running, this
- * reflects the end state.
+ * This class implements {@link WindowManagerInternal.MagnificationCallbacks} and holds
+ * magnification information per display.
*/
- private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
+ private final class DisplayMagnification implements
+ WindowManagerInternal.MagnificationCallbacks {
+ /**
+ * The current magnification spec. If an animation is running, this
+ * reflects the end state.
+ */
+ private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
- private final Region mMagnificationRegion = Region.obtain();
- private final Rect mMagnificationBounds = new Rect();
+ private final Region mMagnificationRegion = Region.obtain();
+ private final Rect mMagnificationBounds = new Rect();
- private final Rect mTempRect = new Rect();
- private final Rect mTempRect1 = new Rect();
+ private final Rect mTempRect = new Rect();
+ private final Rect mTempRect1 = new Rect();
- private final AccessibilityManagerService mAms;
+ private final SpecAnimationBridge mSpecAnimationBridge;
- private final SettingsBridge mSettingsBridge;
+ // Flag indicating that we are registered with window manager.
+ private boolean mRegistered;
+ private boolean mUnregisterPending;
- private final ScreenStateObserver mScreenStateObserver;
+ private final int mDisplayId;
+
+ private static final int INVALID_ID = -1;
+ private int mIdOfLastServiceToMagnify = INVALID_ID;
- private final SpecAnimationBridge mSpecAnimationBridge;
- private final WindowManagerInternal.MagnificationCallbacks mWMCallbacks =
- new WindowManagerInternal.MagnificationCallbacks () {
- @Override
- public void onMagnificationRegionChanged(Region region) {
- final SomeArgs args = SomeArgs.obtain();
- args.arg1 = Region.obtain(region);
- mHandler.obtainMessage(MSG_ON_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
+ DisplayMagnification(int displayId, SpecAnimationBridge specAnimation) {
+ mDisplayId = displayId;
+ mSpecAnimationBridge = specAnimation;
+ }
+
+ void register() {
+ synchronized (mLock) {
+ if (!mRegistered) {
+ mWindowManager.setMagnificationCallbacks(this);
+ mSpecAnimationBridge.setEnabled(true);
+ // Obtain initial state.
+ mWindowManager.getMagnificationRegion(mMagnificationRegion);
+ mMagnificationRegion.getBounds(mMagnificationBounds);
+ mRegistered = true;
}
+ }
+ }
- @Override
- public void onRectangleOnScreenRequested(int left, int top, int right, int bottom) {
- final SomeArgs args = SomeArgs.obtain();
- args.argi1 = left;
- args.argi2 = top;
- args.argi3 = right;
- args.argi4 = bottom;
- mHandler.obtainMessage(MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED, args)
- .sendToTarget();
+ void unregister() {
+ synchronized (mLock) {
+ if (!isMagnifying()) {
+ unregisterInternalLocked();
+ } else {
+ mUnregisterPending = true;
+ reset(true);
}
+ }
+ }
+
+ boolean isRegisteredLocked() {
+ return mRegistered;
+ }
+
+
+ float getScale() {
+ return mCurrentMagnificationSpec.scale;
+ }
+
+ float getOffsetX() {
+ return mCurrentMagnificationSpec.offsetX;
+ }
+
+ float getCenterX() {
+ synchronized (mLock) {
+ return (mMagnificationBounds.width() / 2.0f
+ + mMagnificationBounds.left - getOffsetX()) / getScale();
+ }
+ }
+
+ float getCenterY() {
+ synchronized (mLock) {
+ return (mMagnificationBounds.height() / 2.0f
+ + mMagnificationBounds.top - getOffsetY()) / getScale();
+ }
+ }
- @Override
- public void onRotationChanged(int rotation) {
- // Treat as context change and reset
- mHandler.sendEmptyMessage(MSG_ON_USER_CONTEXT_CHANGED);
+ /**
+ * Returns the scale currently used by the window manager. If an
+ * animation is in progress, this reflects the current state of the
+ * animation.
+ *
+ * @return the scale currently used by the window manager
+ */
+ float getSentScale() {
+ return mSpecAnimationBridge.mSentMagnificationSpec.scale;
+ }
+
+ /**
+ * Returns the X offset currently used by the window manager. If an
+ * animation is in progress, this reflects the current state of the
+ * animation.
+ *
+ * @return the X offset currently used by the window manager
+ */
+ float getSentOffsetX() {
+ return mSpecAnimationBridge.mSentMagnificationSpec.offsetX;
+ }
+
+ /**
+ * Returns the Y offset currently used by the window manager. If an
+ * animation is in progress, this reflects the current state of the
+ * animation.
+ *
+ * @return the Y offset currently used by the window manager
+ */
+ float getSentOffsetY() {
+ return mSpecAnimationBridge.mSentMagnificationSpec.offsetY;
+ }
+
+ boolean resetIfNeeded(boolean animate) {
+ synchronized (mLock) {
+ if (isMagnifying()) {
+ reset(animate);
+ return true;
}
+ return false;
+ }
+ }
+
+ float getOffsetY() {
+ return mCurrentMagnificationSpec.offsetY;
+ }
+
+ boolean isMagnifying() {
+ return mCurrentMagnificationSpec.scale > 1.0f;
+ }
+
+ void unregisterInternalLocked() {
+ if (mRegistered) {
+ mSpecAnimationBridge.setEnabled(false);
+ mWindowManager.setMagnificationCallbacks(null);
+ mMagnificationRegion.setEmpty();
+
+ mRegistered = false;
+ }
+ mUnregisterPending = false;
+ }
+
+
+ @Override
+ public void onMagnificationRegionChanged(Region magnificationRegion) {
+ final Message m = PooledLambda.obtainMessage(
+ DisplayMagnification.this::updateMagnificationRegion,
+ Region.obtain(magnificationRegion));
+ mHandler.sendMessage(m);
+ }
+
+ @Override
+ public void onRectangleOnScreenRequested(int left, int top, int right, int bottom) {
+ final Message m = PooledLambda.obtainMessage(
+ DisplayMagnification.this::requestRectangleOnScreen, left, top, right, bottom);
+ mHandler.sendMessage(m);
+ }
+
+ @Override
+ public void onRotationChanged(int rotation) {
+ // Treat as context change and reset
+ final Message m = PooledLambda.obtainMessage(DisplayMagnification.this::resetIfNeeded,
+ true);
+ mHandler.sendMessage(m);
+ }
- @Override
- public void onUserContextChanged() {
- mHandler.sendEmptyMessage(MSG_ON_USER_CONTEXT_CHANGED);
+ @Override
+ public void onUserContextChanged() {
+ final Message m = PooledLambda.obtainMessage(DisplayMagnification.this::resetIfNeeded,
+ true);
+ mHandler.sendMessage(m);
+ }
+
+ /**
+ * Update our copy of the current magnification region
+ *
+ * @param magnified the magnified region
+ */
+ void updateMagnificationRegion(Region magnified) {
+ synchronized (mLock) {
+ if (!mRegistered) {
+ // Don't update if we've unregistered
+ return;
}
- };
+ if (!mMagnificationRegion.equals(magnified)) {
+ mMagnificationRegion.set(magnified);
+ mMagnificationRegion.getBounds(mMagnificationBounds);
+ // It's possible that our magnification spec is invalid with the new bounds.
+ // Adjust the current spec's offsets if necessary.
+ if (updateCurrentSpecWithOffsetsLocked(
+ mCurrentMagnificationSpec.offsetX, mCurrentMagnificationSpec.offsetY)) {
+ sendSpecToAnimation(mCurrentMagnificationSpec, false);
+ }
+ onMagnificationChangedLocked();
+ }
+ magnified.recycle();
+ }
+ }
- private int mUserId;
+ void sendSpecToAnimation(MagnificationSpec spec, boolean animate) {
+ if (DEBUG) {
+ Slog.i(LOG_TAG,
+ "sendSpecToAnimation(spec = " + spec + ", animate = " + animate + ")");
+ }
+ if (Thread.currentThread().getId() == mMainThreadId) {
+ mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
+ } else {
+ final Message m = PooledLambda.obtainMessage(
+ this.mSpecAnimationBridge::updateSentSpecMainThread, spec, animate);
+ mHandler.sendMessage(m);
+ }
+ }
- private final long mMainThreadId;
+ /**
+ * Get the ID of the last service that changed the magnification spec.
+ *
+ * @return The id
+ */
+ int getIdOfLastServiceToMagnify() {
+ return mIdOfLastServiceToMagnify;
+ }
- private Handler mHandler;
+ void onMagnificationChangedLocked() {
+ mAms.notifyMagnificationChanged(mMagnificationRegion,
+ getScale(), getCenterX(), getCenterY());
+ if (mUnregisterPending && !isMagnifying()) {
+ unregisterInternalLocked();
+ }
+ }
- private int mIdOfLastServiceToMagnify = INVALID_ID;
+ boolean magnificationRegionContains(float x, float y) {
+ synchronized (mLock) {
+ return mMagnificationRegion.contains((int) x, (int) y);
- private final WindowManagerInternal mWindowManager;
+ }
+ }
+
+ void getMagnificationBounds(@NonNull Rect outBounds) {
+ synchronized (mLock) {
+ outBounds.set(mMagnificationBounds);
+ }
+ }
+
+ void getMagnificationRegion(@NonNull Region outRegion) {
+ synchronized (mLock) {
+ outRegion.set(mMagnificationRegion);
+ }
+ }
+
+ void requestRectangleOnScreen(int left, int top, int right, int bottom) {
+ synchronized (mLock) {
+ final Rect magnifiedFrame = mTempRect;
+ getMagnificationBounds(magnifiedFrame);
+ if (!magnifiedFrame.intersects(left, top, right, bottom)) {
+ return;
+ }
+
+ final Rect magnifFrameInScreenCoords = mTempRect1;
+ getMagnifiedFrameInContentCoordsLocked(magnifFrameInScreenCoords);
+
+ final float scrollX;
+ final float scrollY;
+ if (right - left > magnifFrameInScreenCoords.width()) {
+ final int direction = TextUtils
+ .getLayoutDirectionFromLocale(Locale.getDefault());
+ if (direction == View.LAYOUT_DIRECTION_LTR) {
+ scrollX = left - magnifFrameInScreenCoords.left;
+ } else {
+ scrollX = right - magnifFrameInScreenCoords.right;
+ }
+ } else if (left < magnifFrameInScreenCoords.left) {
+ scrollX = left - magnifFrameInScreenCoords.left;
+ } else if (right > magnifFrameInScreenCoords.right) {
+ scrollX = right - magnifFrameInScreenCoords.right;
+ } else {
+ scrollX = 0;
+ }
+
+ if (bottom - top > magnifFrameInScreenCoords.height()) {
+ scrollY = top - magnifFrameInScreenCoords.top;
+ } else if (top < magnifFrameInScreenCoords.top) {
+ scrollY = top - magnifFrameInScreenCoords.top;
+ } else if (bottom > magnifFrameInScreenCoords.bottom) {
+ scrollY = bottom - magnifFrameInScreenCoords.bottom;
+ } else {
+ scrollY = 0;
+ }
+
+ final float scale = getScale();
+ offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_ID);
+ }
+ }
+
+ void getMagnifiedFrameInContentCoordsLocked(Rect outFrame) {
+ final float scale = getSentScale();
+ final float offsetX = getSentOffsetX();
+ final float offsetY = getSentOffsetY();
+ getMagnificationBounds(outFrame);
+ outFrame.offset((int) -offsetX, (int) -offsetY);
+ outFrame.scale(1.0f / scale);
+ }
+
+ /**
+ * Resets magnification if last magnifying service is disabled.
+ *
+ * @param connectionId the connection ID be disabled.
+ * @return {@code true} on success, {@code false} on failure
+ */
+ boolean resetIfNeeded(int connectionId) {
+ if (mIdOfLastServiceToMagnify == connectionId) {
+ return resetIfNeeded(true /*animate*/);
+ }
+ return false;
+ }
+
+ void setForceShowMagnifiableBounds(boolean show) {
+ if (mRegistered) {
+ mWindowManager.setForceShowMagnifiableBounds(show);
+ }
+ }
+
+ boolean reset(boolean animate) {
+ synchronized (mLock) {
+ if (!mRegistered) {
+ return false;
+ }
+ final MagnificationSpec spec = mCurrentMagnificationSpec;
+ final boolean changed = !spec.isNop();
+ if (changed) {
+ spec.clear();
+ onMagnificationChangedLocked();
+ }
+ mIdOfLastServiceToMagnify = INVALID_ID;
+ sendSpecToAnimation(spec, animate);
+ return changed;
+ }
+ }
+
+
+ boolean setScale(float scale, float pivotX, float pivotY,
+ boolean animate, int id) {
+
+ synchronized (mLock) {
+ if (!mRegistered) {
+ return false;
+ }
+ // Constrain scale immediately for use in the pivot calculations.
+ scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+
+ final Rect viewport = mTempRect;
+ mMagnificationRegion.getBounds(viewport);
+ final MagnificationSpec spec = mCurrentMagnificationSpec;
+ final float oldScale = spec.scale;
+ final float oldCenterX
+ = (viewport.width() / 2.0f - spec.offsetX + viewport.left) / oldScale;
+ final float oldCenterY
+ = (viewport.height() / 2.0f - spec.offsetY + viewport.top) / oldScale;
+ final float normPivotX = (pivotX - spec.offsetX) / oldScale;
+ final float normPivotY = (pivotY - spec.offsetY) / oldScale;
+ final float offsetX = (oldCenterX - normPivotX) * (oldScale / scale);
+ final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
+ final float centerX = normPivotX + offsetX;
+ final float centerY = normPivotY + offsetY;
+ mIdOfLastServiceToMagnify = id;
+
+ return setScaleAndCenter(scale, centerX, centerY, animate, id);
+ }
+ }
- // Flag indicating that we are registered with window manager.
- @VisibleForTesting boolean mRegistered;
+ boolean setScaleAndCenter(float scale, float centerX, float centerY,
+ boolean animate, int id) {
- private boolean mUnregisterPending;
+ synchronized (mLock) {
+ if (!mRegistered) {
+ return false;
+ }
+ if (DEBUG) {
+ Slog.i(LOG_TAG,
+ "setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX
+ + ", centerY = " + centerY + ", animate = " + animate
+ + ", id = " + id
+ + ")");
+ }
+ final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
+ sendSpecToAnimation(mCurrentMagnificationSpec, animate);
+ if (isMagnifying() && (id != INVALID_ID)) {
+ mIdOfLastServiceToMagnify = id;
+ }
+ return changed;
+ }
+ }
+
+ /**
+ * Updates the current magnification spec.
+ *
+ * @param scale the magnification scale
+ * @param centerX the unscaled, screen-relative X coordinate of the center
+ * of the viewport, or {@link Float#NaN} to leave unchanged
+ * @param centerY the unscaled, screen-relative Y coordinate of the center
+ * of the viewport, or {@link Float#NaN} to leave unchanged
+ * @return {@code true} if the magnification spec changed or {@code false}
+ * otherwise
+ */
+ boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) {
+ // Handle defaults.
+ if (Float.isNaN(centerX)) {
+ centerX = getCenterX();
+ }
+ if (Float.isNaN(centerY)) {
+ centerY = getCenterY();
+ }
+ if (Float.isNaN(scale)) {
+ scale = getScale();
+ }
+
+ // Compute changes.
+ boolean changed = false;
+
+ final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+ if (Float.compare(mCurrentMagnificationSpec.scale, normScale) != 0) {
+ mCurrentMagnificationSpec.scale = normScale;
+ changed = true;
+ }
+
+ final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f
+ + mMagnificationBounds.left - centerX * normScale;
+ final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f
+ + mMagnificationBounds.top - centerY * normScale;
+ changed |= updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY);
+
+ if (changed) {
+ onMagnificationChangedLocked();
+ }
+
+ return changed;
+ }
+
+ void offsetMagnifiedRegion(float offsetX, float offsetY, int id) {
+ synchronized (mLock) {
+ if (!mRegistered) {
+ return;
+ }
+
+ final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
+ final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
+ if (updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY)) {
+ onMagnificationChangedLocked();
+ }
+ if (id != INVALID_ID) {
+ mIdOfLastServiceToMagnify = id;
+ }
+ sendSpecToAnimation(mCurrentMagnificationSpec, false);
+ }
+ }
+
+ boolean updateCurrentSpecWithOffsetsLocked(float nonNormOffsetX, float nonNormOffsetY) {
+ if (DEBUG) {
+ Slog.i(LOG_TAG,
+ "updateCurrentSpecWithOffsetsLocked(nonNormOffsetX = " + nonNormOffsetX
+ + ", nonNormOffsetY = " + nonNormOffsetY + ")");
+ }
+ boolean changed = false;
+ final float offsetX = MathUtils.constrain(
+ nonNormOffsetX, getMinOffsetXLocked(), getMaxOffsetXLocked());
+ if (Float.compare(mCurrentMagnificationSpec.offsetX, offsetX) != 0) {
+ mCurrentMagnificationSpec.offsetX = offsetX;
+ changed = true;
+ }
+ final float offsetY = MathUtils.constrain(
+ nonNormOffsetY, getMinOffsetYLocked(), getMaxOffsetYLocked());
+ if (Float.compare(mCurrentMagnificationSpec.offsetY, offsetY) != 0) {
+ mCurrentMagnificationSpec.offsetY = offsetY;
+ changed = true;
+ }
+ return changed;
+ }
+
+ float getMinOffsetXLocked() {
+ final float viewportWidth = mMagnificationBounds.width();
+ final float viewportLeft = mMagnificationBounds.left;
+ return (viewportLeft + viewportWidth) -
+ (viewportLeft + viewportWidth) * mCurrentMagnificationSpec.scale;
+ }
+
+ float getMaxOffsetXLocked() {
+ return mMagnificationBounds.left -
+ mMagnificationBounds.left * mCurrentMagnificationSpec.scale;
+ }
+
+ float getMinOffsetYLocked() {
+ final float viewportHeight = mMagnificationBounds.height();
+ final float viewportTop = mMagnificationBounds.top;
+ return (viewportTop + viewportHeight) -
+ (viewportTop + viewportHeight) * mCurrentMagnificationSpec.scale;
+ }
+
+ float getMaxOffsetYLocked() {
+ return mMagnificationBounds.top -
+ mMagnificationBounds.top * mCurrentMagnificationSpec.scale;
+ }
+
+ @Override
+ public String toString() {
+ return "DisplayMagnification{" +
+ "mCurrentMagnificationSpec=" + mCurrentMagnificationSpec +
+ ", mMagnificationRegion=" + mMagnificationRegion +
+ ", mMagnificationBounds=" + mMagnificationBounds +
+ ", mDisplayId=" + mDisplayId +
+ ", mUserId=" + mUserId +
+ ", mIdOfLastServiceToMagnify=" + mIdOfLastServiceToMagnify +
+ ", mRegistered=" + mRegistered +
+ ", mUnregisterPending=" + mUnregisterPending +
+ '}';
+ }
+
+ }
public MagnificationController(Context context, AccessibilityManagerService ams, Object lock) {
this(context, ams, lock, null, LocalServices.getService(WindowManagerInternal.class),
new ValueAnimator(), new SettingsBridge(context.getContentResolver()));
- mHandler = new Handler(context.getMainLooper(), this);
+ mHandler = new Handler(context.getMainLooper());
}
public MagnificationController(
@@ -164,9 +630,10 @@ public class MagnificationController implements Handler.Callback {
mAms = ams;
mScreenStateObserver = new ScreenStateObserver(context, this);
mLock = lock;
- mSpecAnimationBridge = new SpecAnimationBridge(
- context, mLock, mWindowManager, valueAnimator);
mSettingsBridge = settingsBridge;
+ //TODO (multidisplay): Magnification is supported only for the default display.
+ mDisplay = new DisplayMagnification(Display.DEFAULT_DISPLAY,
+ new SpecAnimationBridge(context, mLock, mWindowManager, valueAnimator));
}
/**
@@ -178,16 +645,9 @@ public class MagnificationController implements Handler.Callback {
*/
public void register() {
synchronized (mLock) {
- if (!mRegistered) {
- mScreenStateObserver.register();
- mWindowManager.setMagnificationCallbacks(mWMCallbacks);
- mSpecAnimationBridge.setEnabled(true);
- // Obtain initial state.
- mWindowManager.getMagnificationRegion(mMagnificationRegion);
- mMagnificationRegion.getBounds(mMagnificationBounds);
- mRegistered = true;
- }
+ mScreenStateObserver.register();
}
+ mDisplay.register();
}
/**
@@ -196,33 +656,18 @@ public class MagnificationController implements Handler.Callback {
*/
public void unregister() {
synchronized (mLock) {
- if (!isMagnifying()) {
- unregisterInternalLocked();
- } else {
- mUnregisterPending = true;
- resetLocked(true);
- }
+ mScreenStateObserver.unregister();
}
+ mDisplay.unregister();
}
-
+
/**
* Check if we are registered. Note that we may be planning to unregister at any moment.
*
* @return {@code true} if the controller is registered. {@code false} otherwise.
*/
public boolean isRegisteredLocked() {
- return mRegistered;
- }
-
- private void unregisterInternalLocked() {
- if (mRegistered) {
- mSpecAnimationBridge.setEnabled(false);
- mScreenStateObserver.unregister();
- mWindowManager.setMagnificationCallbacks(null);
- mMagnificationRegion.setEmpty();
- mRegistered = false;
- }
- mUnregisterPending = false;
+ return mDisplay.isRegisteredLocked();
}
/**
@@ -230,32 +675,7 @@ public class MagnificationController implements Handler.Callback {
* is > 1, {@code false} otherwise
*/
public boolean isMagnifying() {
- return mCurrentMagnificationSpec.scale > 1.0f;
- }
-
- /**
- * Update our copy of the current magnification region
- *
- * @param magnified the magnified region
- */
- private void onMagnificationRegionChanged(Region magnified) {
- synchronized (mLock) {
- if (!mRegistered) {
- // Don't update if we've unregistered
- return;
- }
- if (!mMagnificationRegion.equals(magnified)) {
- mMagnificationRegion.set(magnified);
- mMagnificationRegion.getBounds(mMagnificationBounds);
- // It's possible that our magnification spec is invalid with the new bounds.
- // Adjust the current spec's offsets if necessary.
- if (updateCurrentSpecWithOffsetsLocked(
- mCurrentMagnificationSpec.offsetX, mCurrentMagnificationSpec.offsetY)) {
- sendSpecToAnimation(mCurrentMagnificationSpec, false);
- }
- onMagnificationChangedLocked();
- }
- }
+ return mDisplay.isMagnifying();
}
/**
@@ -268,9 +688,8 @@ public class MagnificationController implements Handler.Callback {
* magnified region, or {@code false} otherwise
*/
public boolean magnificationRegionContains(float x, float y) {
- synchronized (mLock) {
- return mMagnificationRegion.contains((int) x, (int) y);
- }
+ return mDisplay.magnificationRegionContains(x, y);
+
}
/**
@@ -282,9 +701,7 @@ public class MagnificationController implements Handler.Callback {
* region
*/
public void getMagnificationBounds(@NonNull Rect outBounds) {
- synchronized (mLock) {
- outBounds.set(mMagnificationBounds);
- }
+ mDisplay.getMagnificationBounds(outBounds);
}
/**
@@ -295,9 +712,7 @@ public class MagnificationController implements Handler.Callback {
* @param outRegion the region to populate
*/
public void getMagnificationRegion(@NonNull Region outRegion) {
- synchronized (mLock) {
- outRegion.set(mMagnificationRegion);
- }
+ mDisplay.getMagnificationRegion(outRegion);
}
/**
@@ -307,7 +722,7 @@ public class MagnificationController implements Handler.Callback {
* @return the scale
*/
public float getScale() {
- return mCurrentMagnificationSpec.scale;
+ return mDisplay.getScale();
}
/**
@@ -317,7 +732,7 @@ public class MagnificationController implements Handler.Callback {
* @return the X offset
*/
public float getOffsetX() {
- return mCurrentMagnificationSpec.offsetX;
+ return mDisplay.getOffsetX();
}
@@ -328,10 +743,7 @@ public class MagnificationController implements Handler.Callback {
* @return the X coordinate
*/
public float getCenterX() {
- synchronized (mLock) {
- return (mMagnificationBounds.width() / 2.0f
- + mMagnificationBounds.left - getOffsetX()) / getScale();
- }
+ return mDisplay.getCenterX();
}
/**
@@ -341,7 +753,7 @@ public class MagnificationController implements Handler.Callback {
* @return the Y offset
*/
public float getOffsetY() {
- return mCurrentMagnificationSpec.offsetY;
+ return mDisplay.getOffsetY();
}
/**
@@ -351,43 +763,7 @@ public class MagnificationController implements Handler.Callback {
* @return the Y coordinate
*/
public float getCenterY() {
- synchronized (mLock) {
- return (mMagnificationBounds.height() / 2.0f
- + mMagnificationBounds.top - getOffsetY()) / getScale();
- }
- }
-
- /**
- * Returns the scale currently used by the window manager. If an
- * animation is in progress, this reflects the current state of the
- * animation.
- *
- * @return the scale currently used by the window manager
- */
- private float getSentScale() {
- return mSpecAnimationBridge.mSentMagnificationSpec.scale;
- }
-
- /**
- * Returns the X offset currently used by the window manager. If an
- * animation is in progress, this reflects the current state of the
- * animation.
- *
- * @return the X offset currently used by the window manager
- */
- private float getSentOffsetX() {
- return mSpecAnimationBridge.mSentMagnificationSpec.offsetX;
- }
-
- /**
- * Returns the Y offset currently used by the window manager. If an
- * animation is in progress, this reflects the current state of the
- * animation.
- *
- * @return the Y offset currently used by the window manager
- */
- private float getSentOffsetY() {
- return mSpecAnimationBridge.mSentMagnificationSpec.offsetY;
+ return mDisplay.getCenterY();
}
/**
@@ -400,24 +776,9 @@ public class MagnificationController implements Handler.Callback {
* the spec did not change
*/
public boolean reset(boolean animate) {
- synchronized (mLock) {
- return resetLocked(animate);
- }
- }
- private boolean resetLocked(boolean animate) {
- if (!mRegistered) {
- return false;
- }
- final MagnificationSpec spec = mCurrentMagnificationSpec;
- final boolean changed = !spec.isNop();
- if (changed) {
- spec.clear();
- onMagnificationChangedLocked();
- }
- mIdOfLastServiceToMagnify = INVALID_ID;
- sendSpecToAnimation(spec, animate);
- return changed;
+ return mDisplay.reset(animate);
+
}
/**
@@ -435,30 +796,8 @@ public class MagnificationController implements Handler.Callback {
* the spec did not change
*/
public boolean setScale(float scale, float pivotX, float pivotY, boolean animate, int id) {
- synchronized (mLock) {
- if (!mRegistered) {
- return false;
- }
- // Constrain scale immediately for use in the pivot calculations.
- scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
-
- final Rect viewport = mTempRect;
- mMagnificationRegion.getBounds(viewport);
- final MagnificationSpec spec = mCurrentMagnificationSpec;
- final float oldScale = spec.scale;
- final float oldCenterX
- = (viewport.width() / 2.0f - spec.offsetX + viewport.left) / oldScale;
- final float oldCenterY
- = (viewport.height() / 2.0f - spec.offsetY + viewport.top) / oldScale;
- final float normPivotX = (pivotX - spec.offsetX) / oldScale;
- final float normPivotY = (pivotY - spec.offsetY) / oldScale;
- final float offsetX = (oldCenterX - normPivotX) * (oldScale / scale);
- final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
- final float centerX = normPivotX + offsetX;
- final float centerY = normPivotY + offsetY;
- mIdOfLastServiceToMagnify = id;
- return setScaleAndCenterLocked(scale, centerX, centerY, animate, id);
- }
+ return mDisplay.
+ setScale(scale, pivotX, pivotY, animate, id);
}
/**
@@ -471,17 +810,13 @@ public class MagnificationController implements Handler.Callback {
* center
* @param animate {@code true} to animate the transition, {@code false}
* to transition immediately
- * @param id the ID of the service requesting the change
+ * @param id the ID of the service requesting the change
* @return {@code true} if the magnification spec changed, {@code false} if
- * the spec did not change
+ * the spec did not change
*/
public boolean setCenter(float centerX, float centerY, boolean animate, int id) {
- synchronized (mLock) {
- if (!mRegistered) {
- return false;
- }
- return setScaleAndCenterLocked(Float.NaN, centerX, centerY, animate, id);
- }
+ return mDisplay.
+ setScaleAndCenter(Float.NaN, centerX, centerY, animate, id);
}
/**
@@ -502,28 +837,8 @@ public class MagnificationController implements Handler.Callback {
*/
public boolean setScaleAndCenter(
float scale, float centerX, float centerY, boolean animate, int id) {
- synchronized (mLock) {
- if (!mRegistered) {
- return false;
- }
- return setScaleAndCenterLocked(scale, centerX, centerY, animate, id);
- }
- }
-
- private boolean setScaleAndCenterLocked(float scale, float centerX, float centerY,
- boolean animate, int id) {
- if (DEBUG) {
- Slog.i(LOG_TAG,
- "setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX
- + ", centerY = " + centerY + ", animate = " + animate + ", id = " + id
- + ")");
- }
- final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
- sendSpecToAnimation(mCurrentMagnificationSpec, animate);
- if (isMagnifying() && (id != INVALID_ID)) {
- mIdOfLastServiceToMagnify = id;
- }
- return changed;
+ return mDisplay.
+ setScaleAndCenter(scale, centerX, centerY, animate, id);
}
/**
@@ -531,27 +846,14 @@ public class MagnificationController implements Handler.Callback {
* opposite direction as the offsets passed in here.
*
* @param offsetX the amount in pixels to offset the region in the X direction, in current
- * screen pixels.
+ * screen pixels.
* @param offsetY the amount in pixels to offset the region in the Y direction, in current
- * screen pixels.
- * @param id the ID of the service requesting the change
+ * screen pixels.
+ * @param id the ID of the service requesting the change
*/
public void offsetMagnifiedRegion(float offsetX, float offsetY, int id) {
- synchronized (mLock) {
- if (!mRegistered) {
- return;
- }
-
- final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
- final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
- if (updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY)) {
- onMagnificationChangedLocked();
- }
- if (id != INVALID_ID) {
- mIdOfLastServiceToMagnify = id;
- }
- sendSpecToAnimation(mCurrentMagnificationSpec, false);
- }
+ mDisplay.offsetMagnifiedRegion(offsetX, offsetY,
+ id);
}
/**
@@ -560,28 +862,26 @@ public class MagnificationController implements Handler.Callback {
* @return The id
*/
public int getIdOfLastServiceToMagnify() {
- return mIdOfLastServiceToMagnify;
- }
-
- private void onMagnificationChangedLocked() {
- mAms.notifyMagnificationChanged(mMagnificationRegion,
- getScale(), getCenterX(), getCenterY());
- if (mUnregisterPending && !isMagnifying()) {
- unregisterInternalLocked();
- }
+ return mDisplay.getIdOfLastServiceToMagnify();
}
/**
* Persists the current magnification scale to the current user's settings.
*/
public void persistScale() {
- final float scale = mCurrentMagnificationSpec.scale;
+ persistScale(Display.DEFAULT_DISPLAY);
+ }
+ /**
+ * Persists the current magnification scale to the current user's settings.
+ */
+ public void persistScale(int displayId) {
+ final float scale = mDisplay.getScale();
final int userId = mUserId;
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
- mSettingsBridge.putMagnificationScale(scale, userId);
+ mSettingsBridge.putMagnificationScale(scale, displayId, userId);
return null;
}
}.execute();
@@ -595,98 +895,7 @@ public class MagnificationController implements Handler.Callback {
* scale if none is available
*/
public float getPersistedScale() {
- return mSettingsBridge.getMagnificationScale(mUserId);
- }
-
- /**
- * Updates the current magnification spec.
- *
- * @param scale the magnification scale
- * @param centerX the unscaled, screen-relative X coordinate of the center
- * of the viewport, or {@link Float#NaN} to leave unchanged
- * @param centerY the unscaled, screen-relative Y coordinate of the center
- * of the viewport, or {@link Float#NaN} to leave unchanged
- * @return {@code true} if the magnification spec changed or {@code false}
- * otherwise
- */
- private boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) {
- // Handle defaults.
- if (Float.isNaN(centerX)) {
- centerX = getCenterX();
- }
- if (Float.isNaN(centerY)) {
- centerY = getCenterY();
- }
- if (Float.isNaN(scale)) {
- scale = getScale();
- }
-
- // Compute changes.
- boolean changed = false;
-
- final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
- if (Float.compare(mCurrentMagnificationSpec.scale, normScale) != 0) {
- mCurrentMagnificationSpec.scale = normScale;
- changed = true;
- }
-
- final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f
- + mMagnificationBounds.left - centerX * normScale;
- final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f
- + mMagnificationBounds.top - centerY * normScale;
- changed |= updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY);
-
- if (changed) {
- onMagnificationChangedLocked();
- }
-
- return changed;
- }
-
- private boolean updateCurrentSpecWithOffsetsLocked(float nonNormOffsetX, float nonNormOffsetY) {
- if (DEBUG) {
- Slog.i(LOG_TAG,
- "updateCurrentSpecWithOffsetsLocked(nonNormOffsetX = " + nonNormOffsetX
- + ", nonNormOffsetY = " + nonNormOffsetY + ")");
- }
- boolean changed = false;
- final float offsetX = MathUtils.constrain(
- nonNormOffsetX, getMinOffsetXLocked(), getMaxOffsetXLocked());
- if (Float.compare(mCurrentMagnificationSpec.offsetX, offsetX) != 0) {
- mCurrentMagnificationSpec.offsetX = offsetX;
- changed = true;
- }
- final float offsetY = MathUtils.constrain(
- nonNormOffsetY, getMinOffsetYLocked(), getMaxOffsetYLocked());
- if (Float.compare(mCurrentMagnificationSpec.offsetY, offsetY) != 0) {
- mCurrentMagnificationSpec.offsetY = offsetY;
- changed = true;
- }
- return changed;
- }
-
- private float getMinOffsetXLocked() {
- final float viewportWidth = mMagnificationBounds.width();
- final float viewportLeft = mMagnificationBounds.left;
- return (viewportLeft + viewportWidth) -
- (viewportLeft + viewportWidth) * mCurrentMagnificationSpec.scale;
- }
-
- private float getMaxOffsetXLocked() {
- return mMagnificationBounds.left -
- mMagnificationBounds.left * mCurrentMagnificationSpec.scale;
- }
-
- private float getMinOffsetYLocked() {
- final float viewportHeight = mMagnificationBounds.height();
- final float viewportTop = mMagnificationBounds.top;
- return (viewportTop + viewportHeight) -
- (viewportTop + viewportHeight) * mCurrentMagnificationSpec.scale;
- }
-
- private float getMaxOffsetYLocked() {
- return mMagnificationBounds.top -
- mMagnificationBounds.top * mCurrentMagnificationSpec.scale;
+ return mSettingsBridge.getMagnificationScale(Display.DEFAULT_DISPLAY, mUserId);
}
/**
@@ -706,20 +915,14 @@ public class MagnificationController implements Handler.Callback {
}
}
- /**
+ /**
* Resets magnification if magnification and auto-update are both enabled.
*
* @param animate whether the animate the transition
* @return whether was {@link #isMagnifying magnifying}
*/
- boolean resetIfNeeded(boolean animate) {
- synchronized (mLock) {
- if (isMagnifying()) {
- reset(animate);
- return true;
- }
- return false;
- }
+ public boolean resetIfNeeded(boolean animate) {
+ return mDisplay.resetIfNeeded(animate);
}
/**
@@ -728,132 +931,23 @@ public class MagnificationController implements Handler.Callback {
* @param connectionId the connection ID be disabled.
* @return {@code true} on success, {@code false} on failure
*/
- boolean resetIfNeeded(int connectionId) {
- if (mIdOfLastServiceToMagnify == connectionId) {
- return resetIfNeeded(true /*animate*/);
- }
- return false;
+ public boolean resetIfNeeded(int connectionId) {
+ return mDisplay.resetIfNeeded(connectionId);
}
void setForceShowMagnifiableBounds(boolean show) {
- if (mRegistered) {
- mWindowManager.setForceShowMagnifiableBounds(show);
- }
- }
-
- private void getMagnifiedFrameInContentCoordsLocked(Rect outFrame) {
- final float scale = getSentScale();
- final float offsetX = getSentOffsetX();
- final float offsetY = getSentOffsetY();
- getMagnificationBounds(outFrame);
- outFrame.offset((int) -offsetX, (int) -offsetY);
- outFrame.scale(1.0f / scale);
- }
-
- private void requestRectangleOnScreen(int left, int top, int right, int bottom) {
- synchronized (mLock) {
- final Rect magnifiedFrame = mTempRect;
- getMagnificationBounds(magnifiedFrame);
- if (!magnifiedFrame.intersects(left, top, right, bottom)) {
- return;
- }
-
- final Rect magnifFrameInScreenCoords = mTempRect1;
- getMagnifiedFrameInContentCoordsLocked(magnifFrameInScreenCoords);
-
- final float scrollX;
- final float scrollY;
- if (right - left > magnifFrameInScreenCoords.width()) {
- final int direction = TextUtils
- .getLayoutDirectionFromLocale(Locale.getDefault());
- if (direction == View.LAYOUT_DIRECTION_LTR) {
- scrollX = left - magnifFrameInScreenCoords.left;
- } else {
- scrollX = right - magnifFrameInScreenCoords.right;
- }
- } else if (left < magnifFrameInScreenCoords.left) {
- scrollX = left - magnifFrameInScreenCoords.left;
- } else if (right > magnifFrameInScreenCoords.right) {
- scrollX = right - magnifFrameInScreenCoords.right;
- } else {
- scrollX = 0;
- }
-
- if (bottom - top > magnifFrameInScreenCoords.height()) {
- scrollY = top - magnifFrameInScreenCoords.top;
- } else if (top < magnifFrameInScreenCoords.top) {
- scrollY = top - magnifFrameInScreenCoords.top;
- } else if (bottom > magnifFrameInScreenCoords.bottom) {
- scrollY = bottom - magnifFrameInScreenCoords.bottom;
- } else {
- scrollY = 0;
- }
-
- final float scale = getScale();
- offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_ID);
- }
- }
-
- private void sendSpecToAnimation(MagnificationSpec spec, boolean animate) {
- if (DEBUG) {
- Slog.i(LOG_TAG, "sendSpecToAnimation(spec = " + spec + ", animate = " + animate + ")");
- }
- if (Thread.currentThread().getId() == mMainThreadId) {
- mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
- } else {
- mHandler.obtainMessage(MSG_SEND_SPEC_TO_ANIMATION,
- animate ? 1 : 0, 0, spec).sendToTarget();
- }
+ mDisplay.setForceShowMagnifiableBounds(show);
}
private void onScreenTurnedOff() {
- mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
- }
-
- public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_SEND_SPEC_TO_ANIMATION:
- final boolean animate = msg.arg1 == 1;
- final MagnificationSpec spec = (MagnificationSpec) msg.obj;
- mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
- break;
- case MSG_SCREEN_TURNED_OFF:
- resetIfNeeded(false);
- break;
- case MSG_ON_MAGNIFIED_BOUNDS_CHANGED: {
- final SomeArgs args = (SomeArgs) msg.obj;
- final Region magnifiedBounds = (Region) args.arg1;
- onMagnificationRegionChanged(magnifiedBounds);
- magnifiedBounds.recycle();
- args.recycle();
- } break;
- case MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED: {
- final SomeArgs args = (SomeArgs) msg.obj;
- final int left = args.argi1;
- final int top = args.argi2;
- final int right = args.argi3;
- final int bottom = args.argi4;
- requestRectangleOnScreen(left, top, right, bottom);
- args.recycle();
- } break;
- case MSG_ON_USER_CONTEXT_CHANGED:
- resetIfNeeded(true);
- break;
- }
- return true;
+ final Message m = PooledLambda.obtainMessage(
+ mDisplay::resetIfNeeded, false);
+ mHandler.sendMessage(m);
}
@Override
public String toString() {
- return "MagnificationController{" +
- "mCurrentMagnificationSpec=" + mCurrentMagnificationSpec +
- ", mMagnificationRegion=" + mMagnificationRegion +
- ", mMagnificationBounds=" + mMagnificationBounds +
- ", mUserId=" + mUserId +
- ", mIdOfLastServiceToMagnify=" + mIdOfLastServiceToMagnify +
- ", mRegistered=" + mRegistered +
- ", mUnregisterPending=" + mUnregisterPending +
- '}';
+ return mDisplay.toString();
}
/**
@@ -974,6 +1068,7 @@ public class MagnificationController implements Handler.Callback {
private static class ScreenStateObserver extends BroadcastReceiver {
private final Context mContext;
private final MagnificationController mController;
+ private boolean mRegistered = false;
public ScreenStateObserver(Context context, MagnificationController controller) {
mContext = context;
@@ -981,11 +1076,17 @@ public class MagnificationController implements Handler.Callback {
}
public void register() {
- mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+ if (!mRegistered) {
+ mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+ mRegistered = true;
+ }
}
public void unregister() {
- mContext.unregisterReceiver(this);
+ if (mRegistered) {
+ mContext.unregisterReceiver(this);
+ mRegistered = false;
+ }
}
@Override
@@ -1002,14 +1103,17 @@ public class MagnificationController implements Handler.Callback {
mContentResolver = contentResolver;
}
- public void putMagnificationScale(float value, int userId) {
+ public void putMagnificationScale(float value, int displayId, int userId) {
Settings.Secure.putFloatForUser(mContentResolver,
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, value, userId);
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE + (
+ Display.DEFAULT_DISPLAY == displayId ? "" : displayId),
+ value, userId);
}
- public float getMagnificationScale(int userId) {
+ public float getMagnificationScale(int displayId, int userId) {
return Settings.Secure.getFloatForUser(mContentResolver,
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE
+ + (Display.DEFAULT_DISPLAY == displayId ? "" : displayId),
DEFAULT_MAGNIFICATION_SCALE, userId);
}
}
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 0b30ff5cc398..af9d4c8c69b6 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -54,6 +54,7 @@ import android.os.IMaintenanceActivityListener;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
+import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -116,6 +117,11 @@ import java.util.Arrays;
STATE_ACTIVE [label="STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"]
STATE_INACTIVE [label="STATE_INACTIVE\nScreen off AND Not charging"]
+ STATE_QUICK_DOZE_DELAY [
+ label="STATE_QUICK_DOZE_DELAY\n"
+ + "Screen off AND Not charging\n"
+ + "Location, motion detection, and significant motion monitoring turned off"
+ ]
STATE_IDLE_PENDING [
label="STATE_IDLE_PENDING\nSignificant motion monitoring turned on"
]
@@ -125,26 +131,40 @@ import java.util.Arrays;
]
STATE_IDLE [
label="STATE_IDLE\nLocation and motion detection turned off\n"
- + "Significant motion monitoring still on"
+ + "Significant motion monitoring state unchanged"
]
STATE_IDLE_MAINTENANCE [label="STATE_IDLE_MAINTENANCE\n"]
- STATE_ACTIVE -> STATE_INACTIVE [label="becomeInactiveIfAppropriateLocked()"]
+ STATE_ACTIVE -> STATE_INACTIVE [
+ label="becomeInactiveIfAppropriateLocked() AND Quick Doze not enabled"
+ ]
+ STATE_ACTIVE -> STATE_QUICK_DOZE_DELAY [
+ label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+ ]
STATE_INACTIVE -> STATE_ACTIVE [
label="handleMotionDetectedLocked(), becomeActiveLocked()"
]
STATE_INACTIVE -> STATE_IDLE_PENDING [label="stepIdleStateLocked()"]
+ STATE_INACTIVE -> STATE_QUICK_DOZE_DELAY [
+ label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+ ]
STATE_IDLE_PENDING -> STATE_ACTIVE [
label="handleMotionDetectedLocked(), becomeActiveLocked()"
]
STATE_IDLE_PENDING -> STATE_SENSING [label="stepIdleStateLocked()"]
+ STATE_IDLE_PENDING -> STATE_QUICK_DOZE_DELAY [
+ label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+ ]
STATE_SENSING -> STATE_ACTIVE [
label="handleMotionDetectedLocked(), becomeActiveLocked()"
]
STATE_SENSING -> STATE_LOCATING [label="stepIdleStateLocked()"]
+ STATE_SENSING -> STATE_QUICK_DOZE_DELAY [
+ label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+ ]
STATE_SENSING -> STATE_IDLE [
label="stepIdleStateLocked()\n"
+ "No Location Manager OR (no Network provider AND no GPS provider)"
@@ -153,8 +173,16 @@ import java.util.Arrays;
STATE_LOCATING -> STATE_ACTIVE [
label="handleMotionDetectedLocked(), becomeActiveLocked()"
]
+ STATE_LOCATING -> STATE_QUICK_DOZE_DELAY [
+ label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+ ]
STATE_LOCATING -> STATE_IDLE [label="stepIdleStateLocked()"]
+ STATE_QUICK_DOZE_DELAY -> STATE_ACTIVE [
+ label="handleMotionDetectedLocked(), becomeActiveLocked()"
+ ]
+ STATE_QUICK_DOZE_DELAY -> STATE_IDLE [label="stepIdleStateLocked()"]
+
STATE_IDLE -> STATE_ACTIVE [label="handleMotionDetectedLocked(), becomeActiveLocked()"]
STATE_IDLE -> STATE_IDLE_MAINTENANCE [label="stepIdleStateLocked()"]
@@ -252,6 +280,7 @@ public class DeviceIdleController extends SystemService
private final AppStateTracker mAppStateTracker;
private boolean mLightEnabled;
private boolean mDeepEnabled;
+ private boolean mQuickDozeActivated;
private boolean mForceIdle;
private boolean mNetworkConnected;
private boolean mScreenOn;
@@ -287,6 +316,12 @@ public class DeviceIdleController extends SystemService
/** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
@VisibleForTesting
static final int STATE_IDLE_MAINTENANCE = 6;
+ /**
+ * Device is inactive and should go straight into idle (foregoing motion and location
+ * monitoring), but allow some time for current work to complete first.
+ */
+ @VisibleForTesting
+ static final int STATE_QUICK_DOZE_DELAY = 7;
@VisibleForTesting
static String stateToString(int state) {
@@ -298,6 +333,7 @@ public class DeviceIdleController extends SystemService
case STATE_LOCATING: return "LOCATING";
case STATE_IDLE: return "IDLE";
case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
+ case STATE_QUICK_DOZE_DELAY: return "QUICK_DOZE_DELAY";
default: return Integer.toString(state);
}
}
@@ -688,6 +724,7 @@ public class DeviceIdleController extends SystemService
private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
+ private static final String KEY_QUICK_DOZE_DELAY_TIMEOUT = "quick_doze_delay_to";
private static final String KEY_IDLE_TIMEOUT = "idle_to";
private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
private static final String KEY_IDLE_FACTOR = "idle_factor";
@@ -864,6 +901,15 @@ public class DeviceIdleController extends SystemService
public float IDLE_PENDING_FACTOR;
/**
+ * This is amount of time we will wait from the point where we go into
+ * STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs
+ * and other current activity to finish.
+ * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+ * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT
+ */
+ public long QUICK_DOZE_DELAY_TIMEOUT;
+
+ /**
* This is the initial time that we want to sit in the idle state before waking up
* again to return to pending idle and allowing normal work to run.
* @see Settings.Global#DEVICE_IDLE_CONSTANTS
@@ -999,6 +1045,8 @@ public class DeviceIdleController extends SystemService
!COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
2f);
+ QUICK_DOZE_DELAY_TIMEOUT = mParser.getDurationMillis(
+ KEY_QUICK_DOZE_DELAY_TIMEOUT, !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L);
IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT,
!COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT,
@@ -1093,6 +1141,10 @@ public class DeviceIdleController extends SystemService
pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
pw.println(IDLE_PENDING_FACTOR);
+ pw.print(" "); pw.print(KEY_QUICK_DOZE_DELAY_TIMEOUT); pw.print("=");
+ TimeUtils.formatDuration(QUICK_DOZE_DELAY_TIMEOUT, pw);
+ pw.println();
+
pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
pw.println();
@@ -1738,6 +1790,16 @@ public class DeviceIdleController extends SystemService
mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
+ mLocalPowerManager.registerLowPowerModeObserver(ServiceType.QUICK_DOZE,
+ state -> {
+ synchronized (DeviceIdleController.this) {
+ updateQuickDozeFlagLocked(state.batterySaverEnabled);
+ }
+ });
+ updateQuickDozeFlagLocked(
+ mLocalPowerManager.getLowPowerState(
+ ServiceType.QUICK_DOZE).batterySaverEnabled);
+
mLocalActivityTaskManager.registerScreenObserver(mScreenObserver);
passWhiteListsToForceAppStandbyTrackerLocked();
@@ -2211,7 +2273,9 @@ public class DeviceIdleController extends SystemService
@VisibleForTesting
boolean isScreenOn() {
- return mScreenOn;
+ synchronized (this) {
+ return mScreenOn;
+ }
}
void updateInteractivityLocked() {
@@ -2235,7 +2299,9 @@ public class DeviceIdleController extends SystemService
@VisibleForTesting
boolean isCharging() {
- return mCharging;
+ synchronized (this) {
+ return mCharging;
+ }
}
void updateChargingLocked(boolean charging) {
@@ -2253,6 +2319,27 @@ public class DeviceIdleController extends SystemService
}
}
+ @VisibleForTesting
+ boolean isQuickDozeEnabled() {
+ synchronized (this) {
+ return mQuickDozeActivated;
+ }
+ }
+
+ /** Updates the quick doze flag and enters deep doze if appropriate. */
+ @VisibleForTesting
+ void updateQuickDozeFlagLocked(boolean enabled) {
+ if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled);
+ mQuickDozeActivated = enabled;
+ if (enabled) {
+ // If Quick Doze is enabled, see if we should go straight into it.
+ becomeInactiveIfAppropriateLocked();
+ }
+ // Going from Deep Doze to Light Idle (if quick doze becomes disabled) is tricky and
+ // probably not worth the overhead, so leave in deep doze if that's the case until the
+ // next natural time to come out of it.
+ }
+
void keyguardShowingLocked(boolean showing) {
if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
if (mScreenLocked != showing) {
@@ -2304,14 +2391,34 @@ public class DeviceIdleController extends SystemService
void becomeInactiveIfAppropriateLocked() {
if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
if ((!mScreenOn && !mCharging) || mForceIdle) {
- // Screen has turned off; we are now going to become inactive and start
- // waiting to see if we will ultimately go idle.
- if (mState == STATE_ACTIVE && mDeepEnabled) {
- mState = STATE_INACTIVE;
- if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
- resetIdleManagementLocked();
- scheduleAlarmLocked(mInactiveTimeout, false);
- EventLogTags.writeDeviceIdle(mState, "no activity");
+ // Become inactive and determine if we will ultimately go idle.
+ if (mDeepEnabled) {
+ if (mQuickDozeActivated) {
+ if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
+ || mState == STATE_IDLE_MAINTENANCE) {
+ // Already "idling". Don't want to restart the process.
+ // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3
+ // values, so returning here is safe.
+ return;
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "Moved from "
+ + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY");
+ }
+ mState = STATE_QUICK_DOZE_DELAY;
+ // Make sure any motion sensing or locating is stopped.
+ resetIdleManagementLocked();
+ // Wait a small amount of time in case something (eg: background service from
+ // recently closed app) needs to finish running.
+ scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
+ EventLogTags.writeDeviceIdle(mState, "no activity");
+ } else if (mState == STATE_ACTIVE) {
+ mState = STATE_INACTIVE;
+ if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
+ resetIdleManagementLocked();
+ scheduleAlarmLocked(mInactiveTimeout, false);
+ EventLogTags.writeDeviceIdle(mState, "no activity");
+ }
}
if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
mLightState = LIGHT_STATE_INACTIVE;
@@ -2473,9 +2580,6 @@ public class DeviceIdleController extends SystemService
// for motion and sleep some more while doing so.
startMonitoringMotionLocked();
scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
- // Reset the upcoming idle delays.
- mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
- mNextIdleDelay = mConstants.IDLE_TIMEOUT;
mState = STATE_IDLE_PENDING;
if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
EventLogTags.writeDeviceIdle(mState, reason);
@@ -2528,6 +2632,13 @@ public class DeviceIdleController extends SystemService
cancelLocatingLocked();
mAnyMotionDetector.stop();
+ // Intentional fallthrough -- time to go into IDLE state.
+ case STATE_QUICK_DOZE_DELAY:
+ // Reset the upcoming idle delays.
+ mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
+ mNextIdleDelay = mConstants.IDLE_TIMEOUT;
+
+ // Everything is in place to go into IDLE state.
case STATE_IDLE_MAINTENANCE:
scheduleAlarmLocked(mNextIdleDelay, true);
if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
@@ -2782,11 +2893,15 @@ public class DeviceIdleController extends SystemService
void scheduleAlarmLocked(long delay, boolean idleUntil) {
if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
- if (mMotionSensor == null) {
+ if (mMotionSensor == null && !(mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
+ || mState == STATE_IDLE_MAINTENANCE)) {
// If there is no motion sensor on this device, then we won't schedule
// alarms, because we can't determine if the device is not moving. This effectively
// turns off normal execution of device idling, although it is still possible to
// manually poke it by pretending like the alarm is going off.
+ // STATE_QUICK_DOZE_DELAY skips the motion sensing so if the state is past the motion
+ // sensing stage (ie, is QUICK_DOZE_DELAY, IDLE, or IDLE_MAINTENANCE), then idling
+ // can continue until the user interacts with the device.
return;
}
mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
@@ -3215,6 +3330,7 @@ public class DeviceIdleController extends SystemService
case "light": pw.println(lightStateToString(mLightState)); break;
case "deep": pw.println(stateToString(mState)); break;
case "force": pw.println(mForceIdle); break;
+ case "quick": pw.println(mQuickDozeActivated); break;
case "screen": pw.println(mScreenOn); break;
case "charging": pw.println(mCharging); break;
case "network": pw.println(mNetworkConnected); break;
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 7c67596d92b4..858dcedd03cc 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3150,10 +3150,10 @@ class StorageManagerService extends IStorageManager.Stub
if (toSystem) {
// Everything else goes into sandbox.
- return device + "Android/sandbox/" + sandboxId.replace(':', '/') + "/" + devicePath;
+ return device + "Android/sandbox/" + sandboxId + "/" + devicePath;
} else {
// Does path belong to this sandbox? If so, leave sandbox.
- final String sandboxPrefix = "Android/sandbox/" + sandboxId.replace(':', '/') + "/";
+ final String sandboxPrefix = "Android/sandbox/" + sandboxId + "/";
if (devicePath.startsWith(sandboxPrefix)) {
return device + devicePath.substring(sandboxPrefix.length());
}
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 9a47553bf446..ede13ef66ac4 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -873,6 +873,52 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
return null;
}
+ ActivityRecord topRunningActivity() {
+ return topRunningActivity(false /* considerKeyguardState */);
+ }
+
+ /**
+ * Returns the top running activity in the focused stack. In the case the focused stack has no
+ * such activity, the next focusable stack on this display is returned.
+ *
+ * @param considerKeyguardState Indicates whether the locked state should be considered. if
+ * {@code true} and the keyguard is locked, only activities that
+ * can be shown on top of the keyguard will be considered.
+ * @return The top running activity. {@code null} if none is available.
+ */
+ ActivityRecord topRunningActivity(boolean considerKeyguardState) {
+ ActivityRecord topRunning = null;
+ final ActivityStack focusedStack = getFocusedStack();
+ if (focusedStack != null) {
+ topRunning = focusedStack.topRunningActivityLocked();
+ }
+
+ // Look in other focusable stacks.
+ if (topRunning == null) {
+ for (int i = mStacks.size() - 1; i >= 0; --i) {
+ final ActivityStack stack = mStacks.get(i);
+ // Only consider focusable stacks other than the current focused one.
+ if (stack == focusedStack || !stack.isFocusable()) {
+ continue;
+ }
+ topRunning = stack.topRunningActivityLocked();
+ if (topRunning != null) {
+ break;
+ }
+ }
+ }
+
+ // This activity can be considered the top running activity if we are not considering
+ // the locked state, the keyguard isn't locked, or we can show when locked.
+ if (topRunning != null && considerKeyguardState
+ && mSupervisor.getKeyguardController().isKeyguardLocked()
+ && !topRunning.canShowWhenLocked()) {
+ return null;
+ }
+
+ return topRunning;
+ }
+
int getIndexOf(ActivityStack stack) {
return mStacks.indexOf(stack);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index afb7a7211eb4..7a0a742bfae7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -22,6 +22,8 @@ import static android.Manifest.permission.FILTER_EVENTS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.REMOVE_TASKS;
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
@@ -462,10 +464,6 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
- // Disable hidden API checks for the newly started instrumentation.
- // Must be kept in sync with Am.
- private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
-
public static final int MY_PID = myPid();
static final String[] EMPTY_STRING_ARRAY = new String[0];
@@ -7133,13 +7131,13 @@ public class ActivityManagerService extends IActivityManager.Stub
final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
String abiOverride) {
return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
- abiOverride);
+ false /* mountExtStorageFull */, abiOverride);
}
// TODO: Move to ProcessList?
@GuardedBy("this")
final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
- boolean disableHiddenApiChecks, String abiOverride) {
+ boolean disableHiddenApiChecks, boolean mountExtStorageFull, String abiOverride) {
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
@@ -7172,7 +7170,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mPersistentStartingProcesses.add(app);
mProcessList.startProcessLocked(app, "added application",
customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
- abiOverride);
+ mountExtStorageFull, abiOverride);
}
return app;
@@ -14698,11 +14696,13 @@ public class ActivityManagerService extends IActivityManager.Stub
activeInstr.mResultClass = className;
boolean disableHiddenApiChecks = ai.usesNonSdkApi()
- || (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
+ || (flags & INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
if (disableHiddenApiChecks) {
enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
"disable hidden API checks");
}
+ final boolean mountExtStorageFull = isCallerShell()
+ && (flags & INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL) != 0;
final long origId = Binder.clearCallingIdentity();
// Instrumentation can kill and relaunch even persistent processes
@@ -14715,7 +14715,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
- abiOverride);
+ mountExtStorageFull, abiOverride);
app.setActiveInstrumentation(activeInstr);
activeInstr.mFinished = false;
activeInstr.mRunningProcesses.add(app);
@@ -14728,6 +14728,11 @@ public class ActivityManagerService extends IActivityManager.Stub
return true;
}
+ private boolean isCallerShell() {
+ final int callingUid = Binder.getCallingUid();
+ return callingUid == SHELL_UID || callingUid == ROOT_UID;
+ }
+
/**
* Report errors that occur while attempting to start Instrumentation. Always writes the
* error to the logs, but if somebody is watching, send the report there too. This enables
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 692b2d433dbc..96601a20471b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -17,14 +17,13 @@
package com.android.server.am;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
import static android.app.ActivityTaskManager.RESIZE_MODE_USER;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
@@ -2902,6 +2901,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
+ pw.println(" [--no-isolated-storage]");
pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
@@ -2920,6 +2920,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
pw.println(" current user if not specified.");
pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
+ pw.println(" --no-isolated-storage: don't use isolated storage sandbox and ");
+ pw.println(" mount full external storage");
pw.println(" --no-window-animation: turn off window animations while running.");
pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
pw.println(" This assumes that the process supports the selected ABI.");
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 12ed726eca77..026c5cc3017d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3877,8 +3877,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
// The activity that we are finishing may be over the lock screen. In this case, we do not
// want to consider activities that cannot be shown on the lock screen as running and should
// proceed with finishing the activity if there is no valid next top running activity.
- final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */);
+ final ActivityDisplay display = getDisplay();
+ final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible) {
@@ -3902,23 +3902,25 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
r.setState(FINISHING, "finishCurrentActivityLocked");
- final boolean finishingActivityInNonFocusedStack
- = r.getStack() != mStackSupervisor.getTopDisplayFocusedStack()
- && prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;
+ final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE
+ && prevState == PAUSED && (r.getStack() != display.getFocusedStack()
+ || (next == null && display.topRunningActivity() == null));
if (mode == FINISH_IMMEDIATELY
|| (prevState == PAUSED
&& (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
- || finishingActivityInNonFocusedStack
+ || finishingInNonFocusedStackOrNoRunning
|| prevState == STOPPING
|| prevState == STOPPED
|| prevState == ActivityState.INITIALIZING) {
r.makeFinishingLocked();
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);
- if (finishingActivityInNonFocusedStack) {
+ if (finishingInNonFocusedStackOrNoRunning) {
// Finishing activity that was in paused state and it was in not currently focused
- // stack, need to make something visible in its place.
+ // stack, need to make something visible in its place. Also if the display does not
+ // have running activity, the configuration may need to be updated for restoring
+ // original orientation of the display.
mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 90e2f5bcd1b4..257a0042b510 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1214,75 +1214,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
ActivityRecord topRunningActivityLocked() {
- return topRunningActivityLocked(false /* considerKeyguardState */);
- }
-
- /**
- * Returns the top running activity in the focused stack. In the case the focused stack has no
- * such activity, the next focusable stack on top of a display is returned.
- * @param considerKeyguardState Indicates whether the locked state should be considered. if
- * {@code true} and the keyguard is locked, only activities that
- * can be shown on top of the keyguard will be considered.
- * @return The top running activity. {@code null} if none is available.
- */
- ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) {
- final ActivityStack focusedStack = getTopDisplayFocusedStack();
- ActivityRecord r = focusedStack.topRunningActivityLocked();
- if (r != null && isValidTopRunningActivity(r, considerKeyguardState)) {
- return r;
- }
-
- // Look in other non-focused and non-home stacks.
for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
- final ActivityDisplay display = mActivityDisplays.get(i);
-
- // TODO: We probably want to consider the top fullscreen stack as we could have a pinned
- // stack on top.
- final ActivityStack topStack = display.getTopStack();
-
- // Only consider focusable top stacks other than the current focused one.
- if (topStack == null || !topStack.isFocusable() || topStack == focusedStack) {
- continue;
- }
-
- final ActivityRecord topActivity = topStack.topRunningActivityLocked();
-
- // Skip if no top activity.
- if (topActivity == null) {
- continue;
- }
-
-
- // This activity can be considered the top running activity if we are not
- // considering the locked state, the keyguard isn't locked, or we can show when
- // locked.
- if (isValidTopRunningActivity(topActivity, considerKeyguardState)) {
+ final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
+ if (topActivity != null) {
return topActivity;
}
}
-
return null;
}
- /**
- * Verifies an {@link ActivityRecord} can be the top activity based on keyguard state and
- * whether we are considering it.
- */
- private boolean isValidTopRunningActivity(ActivityRecord record,
- boolean considerKeyguardState) {
- if (!considerKeyguardState) {
- return true;
- }
-
- final boolean keyguardLocked = getKeyguardController().isKeyguardLocked();
-
- if (!keyguardLocked) {
- return true;
- }
-
- return record.canShowWhenLocked();
- }
-
@VisibleForTesting
void getRunningTasks(int maxNum, List<RunningTaskInfo> list,
@ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode,
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 0db77651cb7b..194aa1b7eef6 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -5878,6 +5878,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public void finishHeavyWeightApp() {
synchronized (mGlobalLock) {
+ if (mHeavyWeightProcess != null) {
+ mHeavyWeightProcess.finishActivities();
+ }
ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
mHeavyWeightProcess);
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 5fdcb9220fca..805b979b4bb7 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -18,7 +18,6 @@ package com.android.server.am;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
-import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
import static android.os.Process.FIRST_ISOLATED_UID;
import static android.os.Process.LAST_ISOLATED_UID;
@@ -28,6 +27,7 @@ import static android.os.Process.getFreeMemory;
import static android.os.Process.getTotalMemory;
import static android.os.Process.killProcessQuiet;
import static android.os.Process.startWebView;
+import static android.os.storage.StorageManager.PROP_ISOLATED_STORAGE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
@@ -45,17 +45,6 @@ import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
import static com.android.server.am.ActivityManagerService.TAG_PSS;
import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
-import dalvik.system.VMRuntime;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppProtoEnums;
@@ -64,11 +53,14 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.FactoryTest;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -77,6 +69,17 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.os.storage.StorageManagerInternal;
+import android.text.TextUtils;
+import android.util.EventLog;
+import android.util.LongSparseArray;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.StatsLog;
+import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -91,21 +94,16 @@ import com.android.server.Watchdog;
import com.android.server.pm.dex.DexManager;
import com.android.server.wm.WindowManagerService;
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.os.SystemProperties;
-import android.net.LocalSocketAddress;
-import android.net.LocalSocket;
-import android.os.Trace;
-import android.os.UserHandle;
-import android.os.storage.StorageManagerInternal;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.LongSparseArray;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.StatsLog;
-import android.view.Display;
+import dalvik.system.VMRuntime;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
/**
* Activity manager code dealing with processes.
@@ -1182,7 +1180,8 @@ public final class ProcessList {
*/
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, String hostingType,
- String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
+ String hostingNameStr, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
+ String abiOverride) {
if (app.pendingStart) {
return true;
}
@@ -1224,10 +1223,15 @@ public final class ProcessList {
final IPackageManager pm = AppGlobals.getPackageManager();
permGids = pm.getPackageGids(app.info.packageName,
MATCH_DIRECT_BOOT_AUTO, app.userId);
- StorageManagerInternal storageManagerInternal = LocalServices.getService(
- StorageManagerInternal.class);
- mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
- app.info.packageName);
+ if (SystemProperties.getBoolean(PROP_ISOLATED_STORAGE, false)
+ && mountExtStorageFull) {
+ mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
+ } else {
+ StorageManagerInternal storageManagerInternal = LocalServices.getService(
+ StorageManagerInternal.class);
+ mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
+ app.info.packageName);
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -1482,7 +1486,7 @@ public final class ProcessList {
final boolean startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr, String abiOverride) {
return startProcessLocked(app, hostingType, hostingNameStr,
- false /* disableHiddenApiChecks */, abiOverride);
+ false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
}
@GuardedBy("mService")
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 0c66c5b22d76..6989c334d876 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -55,6 +55,8 @@ import java.util.function.Predicate;
* Each app can have a different default networks or different connectivity
* status due to user-requested network policies, so we need to check
* constraints on a per-UID basis.
+ *
+ * Test: atest com.android.server.job.controllers.ConnectivityControllerTest
*/
public final class ConnectivityController extends StateController implements
ConnectivityManager.OnNetworkActiveListener {
@@ -65,8 +67,9 @@ public final class ConnectivityController extends StateController implements
private final ConnectivityManager mConnManager;
private final NetworkPolicyManager mNetPolicyManager;
+ /** List of tracked jobs keyed by source UID. */
@GuardedBy("mLock")
- private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>();
+ private final SparseArray<ArraySet<JobStatus>> mTrackedJobs = new SparseArray<>();
public ConnectivityController(JobSchedulerService service) {
super(service);
@@ -87,7 +90,12 @@ public final class ConnectivityController extends StateController implements
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
if (jobStatus.hasConnectivityConstraint()) {
updateConstraintsSatisfied(jobStatus);
- mTrackedJobs.add(jobStatus);
+ ArraySet<JobStatus> jobs = mTrackedJobs.get(jobStatus.getSourceUid());
+ if (jobs == null) {
+ jobs = new ArraySet<>();
+ mTrackedJobs.put(jobStatus.getSourceUid(), jobs);
+ }
+ jobs.add(jobStatus);
jobStatus.setTrackingController(JobStatus.TRACKING_CONNECTIVITY);
}
}
@@ -97,7 +105,10 @@ public final class ConnectivityController extends StateController implements
public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
boolean forUpdate) {
if (jobStatus.clearTrackingController(JobStatus.TRACKING_CONNECTIVITY)) {
- mTrackedJobs.remove(jobStatus);
+ ArraySet<JobStatus> jobs = mTrackedJobs.get(jobStatus.getSourceUid());
+ if (jobs != null) {
+ jobs.remove(jobStatus);
+ }
}
}
@@ -235,47 +246,26 @@ public final class ConnectivityController extends StateController implements
/**
* Update any jobs tracked by this controller that match given filters.
*
- * @param filterUid only update jobs belonging to this UID, or {@code -1} to
- * update all tracked jobs.
+ * @param filterUid only update jobs belonging to this UID, or {@code -1} to
+ * update all tracked jobs.
* @param filterNetwork only update jobs that would use this
- * {@link Network}, or {@code null} to update all tracked jobs.
+ * {@link Network}, or {@code null} to update all tracked jobs.
*/
private void updateTrackedJobs(int filterUid, Network filterNetwork) {
synchronized (mLock) {
// Since this is a really hot codepath, temporarily cache any
// answers that we get from ConnectivityManager.
- final SparseArray<Network> uidToNetwork = new SparseArray<>();
final SparseArray<NetworkCapabilities> networkToCapabilities = new SparseArray<>();
boolean changed = false;
- for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
- final JobStatus js = mTrackedJobs.valueAt(i);
- final int uid = js.getSourceUid();
-
- final boolean uidMatch = (filterUid == -1 || filterUid == uid);
- if (uidMatch) {
- Network network = uidToNetwork.get(uid);
- if (network == null) {
- network = mConnManager.getActiveNetworkForUid(uid);
- uidToNetwork.put(uid, network);
- }
-
- // Update either when we have a network match, or when the
- // job hasn't yet been evaluated against the currently
- // active network; typically when we just lost a network.
- final boolean networkMatch = (filterNetwork == null
- || Objects.equals(filterNetwork, network));
- final boolean forceUpdate = !Objects.equals(js.network, network);
- if (networkMatch || forceUpdate) {
- final int netId = network != null ? network.netId : -1;
- NetworkCapabilities capabilities = networkToCapabilities.get(netId);
- if (capabilities == null) {
- capabilities = mConnManager.getNetworkCapabilities(network);
- networkToCapabilities.put(netId, capabilities);
- }
- changed |= updateConstraintsSatisfied(js, network, capabilities);
- }
+ if (filterUid == -1) {
+ for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
+ changed |= updateTrackedJobsLocked(mTrackedJobs.valueAt(i),
+ filterNetwork, networkToCapabilities);
}
+ } else {
+ changed = updateTrackedJobsLocked(mTrackedJobs.get(filterUid),
+ filterNetwork, networkToCapabilities);
}
if (changed) {
mStateChangedListener.onControllerStateChanged();
@@ -283,6 +273,36 @@ public final class ConnectivityController extends StateController implements
}
}
+ private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork,
+ SparseArray<NetworkCapabilities> networkToCapabilities) {
+ if (jobs == null || jobs.size() == 0) {
+ return false;
+ }
+
+ final Network network = mConnManager.getActiveNetworkForUid(jobs.valueAt(0).getSourceUid());
+ final int netId = network != null ? network.netId : -1;
+ NetworkCapabilities capabilities = networkToCapabilities.get(netId);
+ if (capabilities == null) {
+ capabilities = mConnManager.getNetworkCapabilities(network);
+ networkToCapabilities.put(netId, capabilities);
+ }
+ final boolean networkMatch = (filterNetwork == null
+ || Objects.equals(filterNetwork, network));
+
+ boolean changed = false;
+ for (int i = jobs.size() - 1; i >= 0; i--) {
+ final JobStatus js = jobs.valueAt(i);
+
+ // Update either when we have a network match, or when the
+ // job hasn't yet been evaluated against the currently
+ // active network; typically when we just lost a network.
+ if (networkMatch || !Objects.equals(js.network, network)) {
+ changed |= updateConstraintsSatisfied(js, network, capabilities);
+ }
+ }
+ return changed;
+ }
+
/**
* We know the network has just come up. We want to run any jobs that are ready.
*/
@@ -290,12 +310,15 @@ public final class ConnectivityController extends StateController implements
public void onNetworkActive() {
synchronized (mLock) {
for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
- final JobStatus js = mTrackedJobs.valueAt(i);
- if (js.isReady()) {
- if (DEBUG) {
- Slog.d(TAG, "Running " + js + " due to network activity.");
+ final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
+ for (int j = jobs.size() - 1; j >= 0; j--) {
+ final JobStatus js = jobs.valueAt(j);
+ if (js.isReady()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Running " + js + " due to network activity.");
+ }
+ mStateChangedListener.onRunJobNow(js);
}
- mStateChangedListener.onRunJobNow(js);
}
}
}
@@ -334,8 +357,12 @@ public final class ConnectivityController extends StateController implements
public void dumpControllerStateLocked(IndentingPrintWriter pw,
Predicate<JobStatus> predicate) {
for (int i = 0; i < mTrackedJobs.size(); i++) {
- final JobStatus js = mTrackedJobs.valueAt(i);
- if (predicate.test(js)) {
+ final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
+ for (int j = 0; j < jobs.size(); j++) {
+ final JobStatus js = jobs.valueAt(j);
+ if (!predicate.test(js)) {
+ continue;
+ }
pw.print("#");
js.printUniqueId(pw);
pw.print(" from ");
@@ -355,20 +382,26 @@ public final class ConnectivityController extends StateController implements
final long mToken = proto.start(StateControllerProto.CONNECTIVITY);
for (int i = 0; i < mTrackedJobs.size(); i++) {
- final JobStatus js = mTrackedJobs.valueAt(i);
- if (!predicate.test(js)) {
- continue;
- }
- final long jsToken = proto.start(StateControllerProto.ConnectivityController.TRACKED_JOBS);
- js.writeToShortProto(proto, StateControllerProto.ConnectivityController.TrackedJob.INFO);
- proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
- js.getSourceUid());
- NetworkRequest rn = js.getJob().getRequiredNetwork();
- if (rn != null) {
- rn.writeToProto(proto,
- StateControllerProto.ConnectivityController.TrackedJob.REQUIRED_NETWORK);
+ final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
+ for (int j = 0; j < jobs.size(); j++) {
+ final JobStatus js = jobs.valueAt(j);
+ if (!predicate.test(js)) {
+ continue;
+ }
+ final long jsToken = proto.start(
+ StateControllerProto.ConnectivityController.TRACKED_JOBS);
+ js.writeToShortProto(proto,
+ StateControllerProto.ConnectivityController.TrackedJob.INFO);
+ proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
+ js.getSourceUid());
+ NetworkRequest rn = js.getJob().getRequiredNetwork();
+ if (rn != null) {
+ rn.writeToProto(proto,
+ StateControllerProto.ConnectivityController.TrackedJob
+ .REQUIRED_NETWORK);
+ }
+ proto.end(jsToken);
}
- proto.end(jsToken);
}
proto.end(mToken);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 348b8e69ab96..93b83ae72cca 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3622,7 +3622,7 @@ public class NotificationManagerService extends SystemService {
INotificationListener token, String pkg, UserHandle user,
NotificationChannelGroup group) throws RemoteException {
Preconditions.checkNotNull(user);
- verifyPrivilegedListener(token, user);
+ verifyPrivilegedListener(token, user, false);
createNotificationChannelGroup(
pkg, getUidForPackageAndUser(pkg, user), group, false, true);
savePolicyFile();
@@ -3635,7 +3635,7 @@ public class NotificationManagerService extends SystemService {
Preconditions.checkNotNull(pkg);
Preconditions.checkNotNull(user);
- verifyPrivilegedListener(token, user);
+ verifyPrivilegedListener(token, user, false);
updateNotificationChannelInt(pkg, getUidForPackageAndUser(pkg, user), channel, true);
}
@@ -3644,7 +3644,7 @@ public class NotificationManagerService extends SystemService {
INotificationListener token, String pkg, UserHandle user) throws RemoteException {
Preconditions.checkNotNull(pkg);
Preconditions.checkNotNull(user);
- verifyPrivilegedListener(token, user);
+ verifyPrivilegedListener(token, user, true);
return mPreferencesHelper.getNotificationChannels(pkg, getUidForPackageAndUser(pkg, user),
false /* includeDeleted */);
@@ -3656,7 +3656,7 @@ public class NotificationManagerService extends SystemService {
INotificationListener token, String pkg, UserHandle user) throws RemoteException {
Preconditions.checkNotNull(pkg);
Preconditions.checkNotNull(user);
- verifyPrivilegedListener(token, user);
+ verifyPrivilegedListener(token, user, true);
List<NotificationChannelGroup> groups = new ArrayList<>();
groups.addAll(mPreferencesHelper.getNotificationChannelGroups(
@@ -3664,13 +3664,18 @@ public class NotificationManagerService extends SystemService {
return new ParceledListSlice<>(groups);
}
- private void verifyPrivilegedListener(INotificationListener token, UserHandle user) {
+ private void verifyPrivilegedListener(INotificationListener token, UserHandle user,
+ boolean assistantAllowed) {
ManagedServiceInfo info;
synchronized (mNotificationLock) {
info = mListeners.checkServiceTokenLocked(token);
}
if (!hasCompanionDevice(info)) {
- throw new SecurityException(info + " does not have access");
+ synchronized (mNotificationLock) {
+ if (!assistantAllowed || !mAssistants.isServiceTokenValidLocked(info.service)) {
+ throw new SecurityException(info + " does not have access");
+ }
+ }
}
if (!info.enabledAndUserMatches(user.getIdentifier())) {
throw new SecurityException(info + " does not have access");
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 19a62d91dbf7..e9f2718fe2b3 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -753,10 +753,10 @@ public final class NotificationRecord {
protected void calculateImportance() {
mImportance = calculateInitialImportance();
mImportanceExplanation = "app";
- if (getChannel().isImportanceLocked()) {
+ if (getChannel().hasUserSetImportance()) {
mImportanceExplanation = "user";
}
- if (!getChannel().isImportanceLocked() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
+ if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
mImportance = mAssistantImportance;
mImportanceExplanation = "asst";
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1180af87ae34..9399ebf5b413 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9539,7 +9539,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
}
- if (deleteSandboxData) {
+ if (deleteSandboxData && getStorageManagerInternal() != null) {
getStorageManagerInternal().destroySandboxForApp(pkg.packageName, realUserId);
}
} catch (PackageManagerException e) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6a7e65400fa7..e2818b70deb1 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2634,6 +2634,10 @@ public final class Settings {
writeKernelMappingLPr(ps);
}
+ for (final SharedUserSetting sus : mSharedUsers.values()) {
+ knownSet.remove(sus.getSandboxName());
+ }
+
// Remove any unclaimed mappings
for (int i = 0; i < knownSet.size(); i++) {
final String name = knownSet.valueAt(i);
@@ -2644,30 +2648,42 @@ public final class Settings {
}
}
+ void writeKernelMappingLPr(SharedUserSetting sus) {
+ if (mKernelMappingFilename == null || sus == null || sus.name == null) return;
+
+ writeKernelMappingLPr(sus.getSandboxName(), sus.userId, sus.getNotInstalledUserIds());
+ }
+
void writeKernelMappingLPr(PackageSetting ps) {
if (mKernelMappingFilename == null || ps == null || ps.name == null) return;
- KernelPackageState cur = mKernelMapping.get(ps.name);
+ writeKernelMappingLPr(ps.name, ps.appId, ps.getNotInstalledUserIds());
+ if (ps.sharedUser != null) {
+ writeKernelMappingLPr(ps.sharedUser);
+ }
+ }
+
+ void writeKernelMappingLPr(String name, int appId, int[] excludedUserIds) {
+ KernelPackageState cur = mKernelMapping.get(name);
final boolean firstTime = cur == null;
- int[] excludedUserIds = ps.getNotInstalledUserIds();
final boolean userIdsChanged = firstTime
|| !Arrays.equals(excludedUserIds, cur.excludedUserIds);
// Package directory
- final File dir = new File(mKernelMappingFilename, ps.name);
+ final File dir = new File(mKernelMappingFilename, name);
if (firstTime) {
dir.mkdir();
// Create a new mapping state
cur = new KernelPackageState();
- mKernelMapping.put(ps.name, cur);
+ mKernelMapping.put(name, cur);
}
// If mapping is incorrect or non-existent, write the appid file
- if (cur.appId != ps.appId) {
+ if (cur.appId != appId) {
final File appIdFile = new File(dir, "appid");
- writeIntToFile(appIdFile, ps.appId);
- if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + ps.name + " to " + ps.appId);
+ writeIntToFile(appIdFile, appId);
+ if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + name + " to " + appId);
}
if (userIdsChanged) {
@@ -2677,7 +2693,7 @@ public final class Settings {
excludedUserIds[i])) {
writeIntToFile(new File(dir, "excluded_userids"), excludedUserIds[i]);
if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + excludedUserIds[i] + " to "
- + ps.name + "/excluded_userids");
+ + name + "/excluded_userids");
}
}
// Build the inclusion list -- the ids to remove from the exclusion list
@@ -2687,7 +2703,7 @@ public final class Settings {
writeIntToFile(new File(dir, "clear_userid"),
cur.excludedUserIds[i]);
if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + cur.excludedUserIds[i] + " to "
- + ps.name + "/clear_userid");
+ + name + "/clear_userid");
}
}
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index 1a8b2af5a3a9..32826e51f0a4 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -23,6 +23,10 @@ import android.service.pm.PackageServiceDumpProto;
import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.util.ArrayUtils;
+
+import libcore.util.EmptyArray;
+
import java.util.ArrayList;
import java.util.List;
@@ -144,6 +148,28 @@ public final class SharedUserSetting extends SettingBase {
}
}
+ /** Returns userIds which doesn't have any packages with this sharedUserId */
+ public int[] getNotInstalledUserIds() {
+ int[] excludedUserIds = null;
+ for (PackageSetting ps : packages) {
+ final int[] userIds = ps.getNotInstalledUserIds();
+ if (excludedUserIds == null) {
+ excludedUserIds = userIds;
+ } else {
+ for (int userId : excludedUserIds) {
+ if (!ArrayUtils.contains(userIds, userId)) {
+ excludedUserIds = ArrayUtils.removeInt(excludedUserIds, userId);
+ }
+ }
+ }
+ }
+ return excludedUserIds == null ? EmptyArray.INT : excludedUserIds;
+ }
+
+ public String getSandboxName() {
+ return "shared:" + name;
+ }
+
/** Updates all fields in this shared user setting from another. */
public SharedUserSetting updateFrom(SharedUserSetting sharedUser) {
copyFrom(sharedUser);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dae7b012b9b8..c5cee32f1596 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6864,37 +6864,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public int getUserRotationMode() {
- return Settings.System.getIntForUser(mContext.getContentResolver(),
- Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
- WindowManagerPolicy.USER_ROTATION_FREE :
- WindowManagerPolicy.USER_ROTATION_LOCKED;
- }
-
- // User rotation: to be used when all else fails in assigning an orientation to the device
- @Override
- public void setUserRotationMode(int mode, int rot) {
- ContentResolver res = mContext.getContentResolver();
-
- // mUserRotationMode and mUserRotation will be assigned by the content observer
- if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
- Settings.System.putIntForUser(res,
- Settings.System.USER_ROTATION,
- rot,
- UserHandle.USER_CURRENT);
- Settings.System.putIntForUser(res,
- Settings.System.ACCELEROMETER_ROTATION,
- 0,
- UserHandle.USER_CURRENT);
- } else {
- Settings.System.putIntForUser(res,
- Settings.System.ACCELEROMETER_ROTATION,
- 1,
- UserHandle.USER_CURRENT);
- }
- }
-
- @Override
public void setSafeMode(boolean safeMode) {
mSafeMode = safeMode;
if (safeMode) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 2a8e523f04c2..db13cbccf993 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -82,7 +82,6 @@ import android.view.IApplicationToken;
import android.view.IWindowManager;
import android.view.InputEventReceiver;
import android.view.KeyEvent;
-import android.view.Surface;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants;
@@ -1483,26 +1482,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
public void keepScreenOnStoppedLw();
/**
- * Gets the current user rotation mode.
- *
- * @return The rotation mode.
- *
- * @see #USER_ROTATION_LOCKED
- * @see #USER_ROTATION_FREE
- */
- @UserRotationMode
- public int getUserRotationMode();
-
- /**
- * Inform the policy that the user has chosen a preferred orientation ("rotation lock").
- *
- * @param mode One of {@link #USER_ROTATION_LOCKED} or {@link #USER_ROTATION_FREE}.
- * @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
- * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
- */
- public void setUserRotationMode(@UserRotationMode int mode, @Surface.Rotation int rotation);
-
- /**
* Called when a new system UI visibility is being reported, allowing
* the policy to adjust what is actually reported.
* @param visibility The raw visibility reported by the status bar.
diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java
index ed2b79e7380c..4f8e6b650e24 100644
--- a/services/core/java/com/android/server/power/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java
@@ -75,6 +75,8 @@ public class BatterySaverPolicy extends ContentObserver {
private static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
private static final String KEY_OPTIONAL_SENSORS_DISABLED = "optional_sensors_disabled";
private static final String KEY_AOD_DISABLED = "aod_disabled";
+ // Go into deep Doze as soon as the screen turns off.
+ private static final String KEY_QUICK_DOZE_ENABLED = "quick_doze_enabled";
private static final String KEY_SEND_TRON_LOG = "send_tron_log";
private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
@@ -228,6 +230,12 @@ public class BatterySaverPolicy extends ContentObserver {
private boolean mAodDisabled;
/**
+ * Whether Quick Doze is enabled or not.
+ */
+ @GuardedBy("mLock")
+ private boolean mQuickDozeEnabled;
+
+ /**
* Whether BatterySavingStats should send tron events.
*/
@GuardedBy("mLock")
@@ -392,6 +400,7 @@ public class BatterySaverPolicy extends ContentObserver {
mForceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, true);
mOptionalSensorsDisabled = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED, true);
mAodDisabled = parser.getBoolean(KEY_AOD_DISABLED, true);
+ mQuickDozeEnabled = parser.getBoolean(KEY_QUICK_DOZE_ENABLED, false);
mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, false);
// Get default value from Settings.Secure
@@ -434,6 +443,7 @@ public class BatterySaverPolicy extends ContentObserver {
if (mLaunchBoostDisabled) sb.append("l");
if (mOptionalSensorsDisabled) sb.append("S");
if (mAodDisabled) sb.append("o");
+ if (mQuickDozeEnabled) sb.append("q");
if (mSendTronLog) sb.append("t");
sb.append(mGpsMode);
@@ -502,6 +512,9 @@ public class BatterySaverPolicy extends ContentObserver {
case ServiceType.AOD:
return builder.setBatterySaverEnabled(mAodDisabled)
.build();
+ case ServiceType.QUICK_DOZE:
+ return builder.setBatterySaverEnabled(mQuickDozeEnabled)
+ .build();
default:
return builder.setBatterySaverEnabled(realMode)
.build();
@@ -562,6 +575,7 @@ public class BatterySaverPolicy extends ContentObserver {
pw.println(" " + KEY_FORCE_BACKGROUND_CHECK + "=" + mForceBackgroundCheck);
pw.println(" " + KEY_OPTIONAL_SENSORS_DISABLED + "=" + mOptionalSensorsDisabled);
pw.println(" " + KEY_AOD_DISABLED + "=" + mAodDisabled);
+ pw.println(" " + KEY_QUICK_DOZE_ENABLED + "=" + mQuickDozeEnabled);
pw.println(" " + KEY_SEND_TRON_LOG + "=" + mSendTronLog);
pw.println();
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index be24c7125969..5569822300b9 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -243,7 +243,7 @@ public class BatterySaverController implements BatterySaverPolicyListener {
}
/**
- * Called by {@link PowerManagerService} to update the battery saver stete.
+ * Called by {@link PowerManagerService} to update the battery saver state.
*/
public void enableBatterySaver(boolean enable, int reason) {
synchronized (mLock) {
@@ -290,8 +290,8 @@ public class BatterySaverController implements BatterySaverPolicyListener {
* This method is called only in the following cases:
* - When battery saver becomes activated.
* - When battery saver becomes deactivated.
- * - When battery saver is on the interactive state changes.
- * - When battery saver is on the battery saver policy changes.
+ * - When battery saver is on and the interactive state changes.
+ * - When battery saver is on and the battery saver policy changes.
*/
void handleBatterySaverStateChanged(boolean sendBroadcast, int reason) {
final LowPowerModeListener[] listeners;
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 6db7e4f1a800..c162afbf3e61 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -88,7 +88,6 @@ import com.android.internal.os.KernelWakelockReader;
import com.android.internal.os.KernelWakelockStats;
import com.android.internal.os.LooperStats;
import com.android.internal.os.PowerProfile;
-import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.StoragedUidIoStatsReader;
import com.android.internal.util.DumpUtils;
import com.android.server.BinderCallsStatsService;
@@ -195,8 +194,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private static IThermalService sThermalService;
private File mBaseDir =
new File(SystemServiceManager.ensureSystemDir(), "stats_companion");
- @GuardedBy("this")
- ProcessCpuTracker mProcessCpuTracker = null;
public StatsCompanionService(Context context) {
super();
@@ -1423,34 +1420,12 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
});
}
- private void pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- synchronized (this) {
- if (mProcessCpuTracker == null) {
- mProcessCpuTracker = new ProcessCpuTracker(false);
- mProcessCpuTracker.init();
- }
- mProcessCpuTracker.update();
- for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
- ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
- wallClockNanos);
- e.writeInt(st.uid);
- e.writeString(st.name);
- e.writeLong(st.base_utime);
- e.writeLong(st.base_stime);
- pulledData.add(e);
- }
- }
- }
-
/**
* Pulls various data.
*/
@Override // Binder call
public StatsLogEventWrapper[] pullData(int tagId) {
enforceCallingPermission();
-
if (DEBUG) {
Slog.d(TAG, "Pulling " + tagId);
}
@@ -1563,8 +1538,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
break;
}
case StatsLog.PROC_STATS: {
- pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos,
- ret);
+ pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.PROC_STATS_PKG_PROC: {
@@ -1580,10 +1554,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pullPowerProfile(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
- case StatsLog.PROCESS_CPU_TIME: {
- pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
default:
Slog.w(TAG, "No such tagId data as " + tagId);
return null;
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index bd82553b804b..847cff9c6646 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -55,6 +55,7 @@ public class DisplayRotation {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;
private final WindowManagerService mService;
+ private final DisplayContent mDisplayContent;
private final DisplayPolicy mDisplayPolicy;
private final Context mContext;
private final Object mLock;
@@ -106,6 +107,7 @@ public class DisplayRotation {
DisplayRotation(WindowManagerService service, DisplayContent displayContent,
DisplayPolicy displayPolicy, Context context, Object lock) {
mService = service;
+ mDisplayContent = displayContent;
mDisplayPolicy = displayPolicy;
mContext = context;
mLock = lock;
@@ -225,6 +227,70 @@ public class DisplayRotation {
}
}
+ void restoreUserRotation(int userRotationMode, int userRotation) {
+ if (userRotationMode != WindowManagerPolicy.USER_ROTATION_FREE
+ && userRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) {
+ Slog.w(TAG, "Trying to restore an invalid user rotation mode " + userRotationMode
+ + " for " + mDisplayContent);
+ userRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+ }
+ if (userRotation < Surface.ROTATION_0 || userRotation > Surface.ROTATION_270) {
+ Slog.w(TAG, "Trying to restore an invalid user rotation " + userRotation
+ + " for " + mDisplayContent);
+ userRotation = Surface.ROTATION_0;
+ }
+ mUserRotationMode = userRotationMode;
+ mUserRotation = userRotation;
+ }
+
+ private void setUserRotation(int userRotationMode, int userRotation) {
+ if (isDefaultDisplay) {
+ // We'll be notified via settings listener, so we don't need to update internal values.
+ final ContentResolver res = mContext.getContentResolver();
+ final int accelerometerRotation =
+ userRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED ? 0 : 1;
+ Settings.System.putIntForUser(res, Settings.System.ACCELEROMETER_ROTATION,
+ accelerometerRotation, UserHandle.USER_CURRENT);
+ Settings.System.putIntForUser(res, Settings.System.USER_ROTATION, userRotation,
+ UserHandle.USER_CURRENT);
+ return;
+ }
+
+ boolean changed = false;
+ if (mUserRotationMode != userRotationMode) {
+ mUserRotationMode = userRotationMode;
+ changed = true;
+ }
+ if (mUserRotation != userRotation) {
+ mUserRotation = userRotation;
+ changed = true;
+ }
+ mService.mDisplaySettings.setUserRotation(mDisplayContent, userRotationMode, userRotation);
+ if (changed) {
+ mService.updateRotation(true /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ mService.mDisplaySettings.writeSettingsLocked();
+ }
+ }
+
+ void freezeRotation(int rotation) {
+ rotation = (rotation == -1) ? mDisplayContent.getRotation() : rotation;
+ setUserRotation(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation);
+ }
+
+ void thawRotation() {
+ setUserRotation(WindowManagerPolicy.USER_ROTATION_FREE, mUserRotation);
+ }
+
+ boolean isRotationFrozen() {
+ if (!isDefaultDisplay) {
+ return mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED;
+ }
+
+ return Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) == 0;
+ }
+
/** @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true. */
boolean isDefaultOrientationForced() {
return mForceDefaultOrientation;
@@ -381,9 +447,6 @@ public class DisplayRotation {
* @param orientation An orientation constant, such as
* {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
* @param lastRotation The most recently used rotation.
- * @param defaultDisplay Flag indicating whether the rotation is computed for the default
- * display. Currently for all non-default displays sensors, docking mode,
- * rotation lock and other factors are ignored.
* @return The surface rotation to use.
*/
int rotationForOrientation(int orientation, int lastRotation) {
@@ -418,8 +481,8 @@ public class DisplayRotation {
final int preferredRotation;
if (!isDefaultDisplay) {
// For secondary displays we ignore things like displays sensors, docking mode and
- // rotation lock, and always prefer a default rotation.
- preferredRotation = Surface.ROTATION_0;
+ // rotation lock, and always prefer user rotation.
+ preferredRotation = mUserRotation;
} else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
// Ignore sensor when lid switch is open and rotation is forced.
preferredRotation = mLidOpenRotation;
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index bbb690f6a34a..28dc008fda9b 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -20,20 +20,23 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.app.WindowConfiguration;
-import android.content.Context;
-import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Environment;
-import android.provider.Settings;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
+import com.android.server.policy.WindowManagerPolicy;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.FileInputStream;
@@ -43,10 +46,6 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
/**
* Current persistent settings about a display
*/
@@ -58,15 +57,25 @@ class DisplaySettings {
private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>();
private static class Entry {
- private final String name;
- private int overscanLeft;
- private int overscanTop;
- private int overscanRight;
- private int overscanBottom;
- private int windowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+ private final String mName;
+ private int mOverscanLeft;
+ private int mOverscanTop;
+ private int mOverscanRight;
+ private int mOverscanBottom;
+ private int mWindowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+ private int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+ private int mUserRotation = Surface.ROTATION_0;
private Entry(String _name) {
- name = _name;
+ mName = _name;
+ }
+
+ private boolean isEmpty() {
+ return mOverscanLeft == 0 && mOverscanTop == 0 && mOverscanRight == 0
+ && mOverscanBottom == 0
+ && mWindowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED
+ && mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+ && mUserRotation == Surface.ROTATION_0;
}
}
@@ -90,13 +99,30 @@ class DisplaySettings {
return entry;
}
+ private Entry getOrCreateEntry(String uniqueId, String name) {
+ Entry entry = getEntry(uniqueId, name);
+ if (entry == null) {
+ entry = new Entry(uniqueId);
+ mEntries.put(uniqueId, entry);
+ }
+ return entry;
+ }
+
+ private void removeEntryIfEmpty(String uniqueId, String name) {
+ final Entry entry = getEntry(uniqueId, name);
+ if (entry.isEmpty()) {
+ mEntries.remove(uniqueId);
+ mEntries.remove(name);
+ }
+ }
+
private void getOverscanLocked(String name, String uniqueId, Rect outRect) {
final Entry entry = getEntry(name, uniqueId);
if (entry != null) {
- outRect.left = entry.overscanLeft;
- outRect.top = entry.overscanTop;
- outRect.right = entry.overscanRight;
- outRect.bottom = entry.overscanBottom;
+ outRect.left = entry.mOverscanLeft;
+ outRect.top = entry.mOverscanTop;
+ outRect.right = entry.mOverscanRight;
+ outRect.bottom = entry.mOverscanBottom;
} else {
outRect.set(0, 0, 0, 0);
}
@@ -104,28 +130,22 @@ class DisplaySettings {
void setOverscanLocked(String uniqueId, String name, int left, int top, int right,
int bottom) {
- if (left == 0 && top == 0 && right == 0 && bottom == 0) {
- // Right now all we are storing is overscan; if there is no overscan,
- // we have no need for the entry.
- mEntries.remove(uniqueId);
- // Legacy name might have been in used, so we need to clear it.
- mEntries.remove(name);
- return;
- }
Entry entry = mEntries.get(uniqueId);
- if (entry == null) {
- entry = new Entry(uniqueId);
- mEntries.put(uniqueId, entry);
+ if (left == 0 && top == 0 && right == 0 && bottom == 0 && entry == null) {
+ // All default value, no action needed.
+ return;
}
- entry.overscanLeft = left;
- entry.overscanTop = top;
- entry.overscanRight = right;
- entry.overscanBottom = bottom;
+ entry = getOrCreateEntry(uniqueId, name);
+ entry.mOverscanLeft = left;
+ entry.mOverscanTop = top;
+ entry.mOverscanRight = right;
+ entry.mOverscanBottom = bottom;
+ removeEntryIfEmpty(uniqueId, name);
}
private int getWindowingModeLocked(String name, String uniqueId, int displayId) {
final Entry entry = getEntry(name, uniqueId);
- int windowingMode = entry != null ? entry.windowingMode
+ int windowingMode = entry != null ? entry.mWindowingMode
: WindowConfiguration.WINDOWING_MODE_UNDEFINED;
// This display used to be in freeform, but we don't support freeform anymore, so fall
// back to fullscreen.
@@ -148,6 +168,36 @@ class DisplaySettings {
return windowingMode;
}
+ void setUserRotation(DisplayContent dc, int rotationMode, int rotation) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+
+ final String uniqueId = displayInfo.uniqueId;
+ final String name = displayInfo.name;
+ Entry entry = getEntry(displayInfo.name, uniqueId);
+ if (rotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+ && rotation == Surface.ROTATION_0 && entry == null) {
+ // All default values. No action needed.
+ return;
+ }
+
+ entry = getOrCreateEntry(uniqueId, name);
+ entry.mUserRotationMode = rotationMode;
+ entry.mUserRotation = rotation;
+ removeEntryIfEmpty(uniqueId, name);
+ }
+
+ private void restoreUserRotation(DisplayContent dc) {
+ final DisplayInfo info = dc.getDisplayInfo();
+
+ final Entry entry = getEntry(info.name, info.uniqueId);
+ final int userRotationMode = entry != null ? entry.mUserRotationMode
+ : WindowManagerPolicy.USER_ROTATION_FREE;
+ final int userRotation = entry != null ? entry.mUserRotation
+ : Surface.ROTATION_0;
+
+ dc.getDisplayRotation().restoreUserRotation(userRotationMode, userRotation);
+ }
+
void applySettingsToDisplayLocked(DisplayContent dc) {
final DisplayInfo displayInfo = dc.getDisplayInfo();
@@ -161,6 +211,8 @@ class DisplaySettings {
displayInfo.overscanTop = rect.top;
displayInfo.overscanRight = rect.right;
displayInfo.overscanBottom = rect.bottom;
+
+ restoreUserRotation(dc);
}
void readSettingsLocked() {
@@ -244,12 +296,16 @@ class DisplaySettings {
String name = parser.getAttributeValue(null, "name");
if (name != null) {
Entry entry = new Entry(name);
- entry.overscanLeft = getIntAttribute(parser, "overscanLeft");
- entry.overscanTop = getIntAttribute(parser, "overscanTop");
- entry.overscanRight = getIntAttribute(parser, "overscanRight");
- entry.overscanBottom = getIntAttribute(parser, "overscanBottom");
- entry.windowingMode = getIntAttribute(parser, "windowingMode",
+ entry.mOverscanLeft = getIntAttribute(parser, "overscanLeft");
+ entry.mOverscanTop = getIntAttribute(parser, "overscanTop");
+ entry.mOverscanRight = getIntAttribute(parser, "overscanRight");
+ entry.mOverscanBottom = getIntAttribute(parser, "overscanBottom");
+ entry.mWindowingMode = getIntAttribute(parser, "windowingMode",
WindowConfiguration.WINDOWING_MODE_UNDEFINED);
+ entry.mUserRotationMode = getIntAttribute(parser, "userRotationMode",
+ WindowManagerPolicy.USER_ROTATION_FREE);
+ entry.mUserRotation = getIntAttribute(parser, "userRotation",
+ Surface.ROTATION_0);
mEntries.put(name, entry);
}
XmlUtils.skipCurrentTag(parser);
@@ -272,21 +328,28 @@ class DisplaySettings {
for (Entry entry : mEntries.values()) {
out.startTag(null, "display");
- out.attribute(null, "name", entry.name);
- if (entry.overscanLeft != 0) {
- out.attribute(null, "overscanLeft", Integer.toString(entry.overscanLeft));
+ out.attribute(null, "name", entry.mName);
+ if (entry.mOverscanLeft != 0) {
+ out.attribute(null, "overscanLeft", Integer.toString(entry.mOverscanLeft));
+ }
+ if (entry.mOverscanTop != 0) {
+ out.attribute(null, "overscanTop", Integer.toString(entry.mOverscanTop));
+ }
+ if (entry.mOverscanRight != 0) {
+ out.attribute(null, "overscanRight", Integer.toString(entry.mOverscanRight));
}
- if (entry.overscanTop != 0) {
- out.attribute(null, "overscanTop", Integer.toString(entry.overscanTop));
+ if (entry.mOverscanBottom != 0) {
+ out.attribute(null, "overscanBottom", Integer.toString(entry.mOverscanBottom));
}
- if (entry.overscanRight != 0) {
- out.attribute(null, "overscanRight", Integer.toString(entry.overscanRight));
+ if (entry.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
+ out.attribute(null, "windowingMode", Integer.toString(entry.mWindowingMode));
}
- if (entry.overscanBottom != 0) {
- out.attribute(null, "overscanBottom", Integer.toString(entry.overscanBottom));
+ if (entry.mUserRotationMode != WindowManagerPolicy.USER_ROTATION_FREE) {
+ out.attribute(null, "userRotationMode",
+ Integer.toString(entry.mUserRotationMode));
}
- if (entry.windowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- out.attribute(null, "windowingMode", Integer.toString(entry.windowingMode));
+ if (entry.mUserRotation != Surface.ROTATION_0) {
+ out.attribute(null, "userRotation", Integer.toString(entry.mUserRotation));
}
out.endTag(null, "display");
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index b7507a42485c..ef63b9b70b3b 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -29,13 +29,13 @@ import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
+import android.graphics.RenderNode;
import android.os.Environment;
import android.os.Handler;
import android.util.ArraySet;
import android.util.Slog;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
import android.view.SurfaceControl;
import android.view.ThreadedRenderer;
import android.view.WindowManager.LayoutParams;
@@ -371,7 +371,7 @@ class TaskSnapshotController {
final RenderNode node = RenderNode.create("TaskSnapshotController", null);
node.setLeftTopRightBottom(0, 0, width, height);
node.setClipToBounds(false);
- final DisplayListCanvas c = node.start(width, height);
+ final RecordingCanvas c = node.start(width, height);
c.drawColor(color);
decorPainter.setInsets(mainWindow.getContentInsets(), mainWindow.getStableInsets());
decorPainter.drawDecors(c, null /* statusBarExcludeFrame */);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 056e92e3b654..5642b1f91700 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3668,14 +3668,19 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ @Override
+ public void freezeRotation(int rotation) {
+ freezeDisplayRotation(Display.DEFAULT_DISPLAY, rotation);
+ }
+
/**
* Freeze rotation changes. (Enable "rotation lock".)
* Persists across reboots.
- * @param rotation The desired rotation to freeze to, or -1 to use the
- * current rotation.
+ * @param displayId The ID of the display to freeze.
+ * @param rotation The desired rotation to freeze to, or -1 to use the current rotation.
*/
@Override
- public void freezeRotation(int rotation) {
+ public void freezeDisplayRotation(int displayId, int rotation) {
// TODO(multi-display): Track which display is rotated.
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"freezeRotation()")) {
@@ -3686,14 +3691,16 @@ public class WindowManagerService extends IWindowManager.Stub
+ "rotation constant.");
}
- final int defaultDisplayRotation = getDefaultDisplayRotation();
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "freezeRotation: mRotation="
- + defaultDisplayRotation);
-
long origId = Binder.clearCallingIdentity();
try {
- mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
- rotation == -1 ? defaultDisplayRotation : rotation);
+ synchronized (mWindowMap) {
+ final DisplayContent display = mRoot.getDisplayContent(displayId);
+ if (display == null) {
+ Slog.w(TAG, "Trying to freeze rotation for a missing display.");
+ return;
+ }
+ display.getDisplayRotation().freezeRotation(rotation);
+ }
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -3701,12 +3708,17 @@ public class WindowManagerService extends IWindowManager.Stub
updateRotationUnchecked(false, false);
}
+ @Override
+ public void thawRotation() {
+ thawDisplayRotation(Display.DEFAULT_DISPLAY);
+ }
+
/**
* Thaw rotation changes. (Disable "rotation lock".)
* Persists across reboots.
*/
@Override
- public void thawRotation() {
+ public void thawDisplayRotation(int displayId) {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"thawRotation()")) {
throw new SecurityException("Requires SET_ORIENTATION permission");
@@ -3717,8 +3729,14 @@ public class WindowManagerService extends IWindowManager.Stub
long origId = Binder.clearCallingIdentity();
try {
- mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
- 777); // rot not used
+ synchronized (mWindowMap) {
+ final DisplayContent display = mRoot.getDisplayContent(displayId);
+ if (display == null) {
+ Slog.w(TAG, "Trying to thaw rotation for a missing display.");
+ return;
+ }
+ display.getDisplayRotation().thawRotation();
+ }
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -3726,6 +3744,23 @@ public class WindowManagerService extends IWindowManager.Stub
updateRotationUnchecked(false, false);
}
+ @Override
+ public boolean isRotationFrozen() {
+ return isDisplayRotationFrozen(Display.DEFAULT_DISPLAY);
+ }
+
+ @Override
+ public boolean isDisplayRotationFrozen(int displayId) {
+ synchronized (mWindowMap) {
+ final DisplayContent display = mRoot.getDisplayContent(displayId);
+ if (display == null) {
+ Slog.w(TAG, "Trying to thaw rotation for a missing display.");
+ return false;
+ }
+ return display.getDisplayRotation().isRotationFrozen();
+ }
+ }
+
/**
* Recalculate the current rotation.
*
@@ -3795,11 +3830,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public boolean isRotationFrozen() {
- return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
- }
-
- @Override
public int watchRotation(IRotationWatcher watcher, int displayId) {
final DisplayContent displayContent;
synchronized (mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 831418b4b2b4..bf2d0df2bec3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -26,6 +26,7 @@ import android.os.UserHandle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.IWindowManager;
+import android.view.Surface;
import java.io.PrintWriter;
import java.util.regex.Matcher;
@@ -73,6 +74,8 @@ public class WindowManagerShellCommand extends ShellCommand {
// trace files can be written.
return mInternal.mWindowTracing.onShellCommand(this,
getNextArgRequired());
+ case "set-user-rotation":
+ return runSetDisplayUserRotation(pw);
default:
return handleDefaultCommands(cmd);
}
@@ -262,6 +265,36 @@ public class WindowManagerShellCommand extends ShellCommand {
return Integer.parseInt(s);
}
+ private int runSetDisplayUserRotation(PrintWriter pw) {
+ final String lockMode = getNextArgRequired();
+
+ int displayId = Display.DEFAULT_DISPLAY;
+ String arg = getNextArg();
+ if ("-d".equals(arg)) {
+ displayId = Integer.parseInt(getNextArgRequired());
+ arg = getNextArg();
+ }
+
+ if ("free".equals(lockMode)) {
+ mInternal.thawDisplayRotation(displayId);
+ return 0;
+ }
+
+ if (!lockMode.equals("lock")) {
+ getErrPrintWriter().println("Error: lock mode needs to be either free or lock.");
+ return -1;
+ }
+
+ try {
+ final int rotation = arg != null ? Integer.parseInt(arg) : Surface.ROTATION_0;
+ mInternal.freezeDisplayRotation(displayId, rotation);
+ return 0;
+ } catch (IllegalArgumentException e) {
+ getErrPrintWriter().println("Error: " + e.getMessage());
+ return -1;
+ }
+ }
+
@Override
public void onHelp() {
PrintWriter pw = getOutPrintWriter();
@@ -279,6 +312,8 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" Set display scaling mode.");
pw.println(" dismiss-keyguard");
pw.println(" Dismiss the keyguard, prompting user for auth if necessary.");
+ pw.println(" set-user-rotation [free|lock] [-d DISPLAY_ID] [rotation]");
+ pw.println(" Set user rotation mode and user rotation.");
if (!IS_USER) {
pw.println(" tracing (start | stop)");
pw.println(" Start or stop window tracing.");
diff --git a/services/tests/mockingservicestests/Android.mk b/services/tests/mockingservicestests/Android.mk
index b83a79fc232c..e6cbb5badb9e 100644
--- a/services/tests/mockingservicestests/Android.mk
+++ b/services/tests/mockingservicestests/Android.mk
@@ -23,7 +23,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
frameworks-base-testutils \
services.core \
services.net \
- androidx-test \
+ androidx.test.runner \
mockito-target-extended-minus-junit4 \
platform-test-annotations \
ShortcutManagerTestUtils \
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index de3d285cd23a..877c8fad3086 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -58,6 +58,8 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.annotations.GuardedBy;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -67,8 +69,6 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoSession;
-import javax.annotation.concurrent.GuardedBy;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class AlarmManagerServiceTest {
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 8afd788256c1..04a84081bad8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -36,35 +36,36 @@ import static com.android.server.DeviceIdleController.STATE_IDLE_MAINTENANCE;
import static com.android.server.DeviceIdleController.STATE_IDLE_PENDING;
import static com.android.server.DeviceIdleController.STATE_INACTIVE;
import static com.android.server.DeviceIdleController.STATE_LOCATING;
+import static com.android.server.DeviceIdleController.STATE_QUICK_DOZE_DELAY;
import static com.android.server.DeviceIdleController.STATE_SENSING;
import static com.android.server.DeviceIdleController.lightStateToString;
import static com.android.server.DeviceIdleController.stateToString;
import static org.junit.Assert.assertEquals;
-
-import android.net.NetworkInfo;
-
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
-import android.net.ConnectivityManager;
-import android.content.Intent;
import android.app.IActivityManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.hardware.SensorManager;
import android.location.LocationManager;
import android.location.LocationProvider;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
+import android.os.PowerSaveState;
import android.os.SystemClock;
import androidx.test.runner.AndroidJUnit4;
@@ -105,6 +106,8 @@ public class DeviceIdleControllerTest {
private PowerManager mPowerManager;
@Mock
private PowerManager.WakeLock mWakeLock;
+ @Mock
+ private PowerManagerInternal mPowerManagerInternal;
class InjectorForTest extends DeviceIdleController.Injector {
ConnectivityService connectivityService;
@@ -204,12 +207,15 @@ public class DeviceIdleControllerTest {
.when(() -> LocalServices.getService(ActivityManagerInternal.class));
doReturn(mock(ActivityTaskManagerInternal.class))
.when(() -> LocalServices.getService(ActivityTaskManagerInternal.class));
- doReturn(mock(PowerManagerInternal.class))
+ doReturn(mPowerManagerInternal)
.when(() -> LocalServices.getService(PowerManagerInternal.class));
+ when(mPowerManagerInternal.getLowPowerState(anyInt())).thenReturn(
+ mock(PowerSaveState.class));
doReturn(mock(NetworkPolicyManagerInternal.class))
.when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class));
when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
doNothing().when(mWakeLock).acquire();
+ doNothing().when(mAlarmManager).set(anyInt(), anyLong(), anyString(), any(), any());
mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
mAnyMotionDetector = new AnyMotionDetectorForTest();
mInjector = new InjectorForTest(getContext());
@@ -336,6 +342,28 @@ public class DeviceIdleControllerTest {
}
@Test
+ public void testUpdateQuickDozeFlagLocked() {
+ mDeviceIdleController.updateQuickDozeFlagLocked(false);
+ assertFalse(mDeviceIdleController.isQuickDozeEnabled());
+
+ // Make sure setting false when quick doze is already off doesn't change anything.
+ mDeviceIdleController.updateQuickDozeFlagLocked(false);
+ assertFalse(mDeviceIdleController.isQuickDozeEnabled());
+
+ // Test changing from quick doze off to quick doze on.
+ mDeviceIdleController.updateQuickDozeFlagLocked(true);
+ assertTrue(mDeviceIdleController.isQuickDozeEnabled());
+
+ // Make sure setting true when quick doze is already on doesn't change anything.
+ mDeviceIdleController.updateQuickDozeFlagLocked(true);
+ assertTrue(mDeviceIdleController.isQuickDozeEnabled());
+
+ // Test changing from quick doze on to quick doze off.
+ mDeviceIdleController.updateQuickDozeFlagLocked(false);
+ assertFalse(mDeviceIdleController.isQuickDozeEnabled());
+ }
+
+ @Test
public void testStateActiveToStateInactive_ConditionsNotMet() {
mDeviceIdleController.becomeActiveLocked("testing", 0);
verifyStateConditions(STATE_ACTIVE);
@@ -416,6 +444,46 @@ public class DeviceIdleControllerTest {
}
@Test
+ public void testTransitionFromAnyStateToStateQuickDozeDelay() {
+ enterDeepState(STATE_ACTIVE);
+ setQuickDozeEnabled(true);
+ setChargingOn(false);
+ setScreenOn(false);
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_INACTIVE);
+ setQuickDozeEnabled(true);
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_IDLE_PENDING);
+ setQuickDozeEnabled(true);
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_SENSING);
+ setQuickDozeEnabled(true);
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_LOCATING);
+ setQuickDozeEnabled(true);
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ // IDLE should stay as IDLE.
+ enterDeepState(STATE_IDLE);
+ setQuickDozeEnabled(true);
+ verifyStateConditions(STATE_IDLE);
+
+ // IDLE_MAINTENANCE should stay as IDLE_MAINTENANCE.
+ enterDeepState(STATE_IDLE_MAINTENANCE);
+ setQuickDozeEnabled(true);
+ verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+ }
+
+ @Test
public void testStepIdleStateLocked_InvalidStates() {
mDeviceIdleController.becomeActiveLocked("testing", 0);
mDeviceIdleController.stepIdleStateLocked("testing");
@@ -425,49 +493,77 @@ public class DeviceIdleControllerTest {
}
@Test
+ public void testStepIdleStateLocked_ValidStates_QuickDoze() {
+ setAlarmSoon(false);
+
+ // Quick doze should go directly into IDLE.
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_IDLE);
+
+ // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_IDLE);
+
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_IDLE_MAINTENANCE);
+ }
+
+ @Test
public void testStepIdleStateLocked_ValidStates_WithWakeFromIdleAlarmSoon() {
enterDeepState(STATE_ACTIVE);
// Return that there's an alarm coming soon.
- doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
- mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(true);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_ACTIVE);
// Everything besides ACTIVE should end up as INACTIVE since the screen would be off.
enterDeepState(STATE_INACTIVE);
- doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
- mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(true);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_IDLE_PENDING);
- doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
- mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(true);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_SENSING);
- doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
- mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(true);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_LOCATING);
- doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
- mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(true);
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_INACTIVE);
+
+ // With quick doze enabled, we should end up in QUICK_DOZE_DELAY instead of INACTIVE.
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ setQuickDozeEnabled(true);
+ setAlarmSoon(true);
+ mDeviceIdleController.stepIdleStateLocked("testing");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ // With quick doze disabled, we should end up in INACTIVE instead of QUICK_DOZE_DELAY.
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ setQuickDozeEnabled(false);
+ setAlarmSoon(true);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_IDLE);
- doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
- mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(true);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_IDLE_MAINTENANCE);
- doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
- mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(true);
mDeviceIdleController.stepIdleStateLocked("testing");
verifyStateConditions(STATE_INACTIVE);
}
@@ -476,7 +572,7 @@ public class DeviceIdleControllerTest {
public void testStepIdleStateLocked_ValidStates_NoLocationManager() {
mInjector.locationManager = null;
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
- doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(false);
// Set state to INACTIVE.
mDeviceIdleController.becomeActiveLocked("testing", 0);
setChargingOn(false);
@@ -508,7 +604,7 @@ public class DeviceIdleControllerTest {
@Test
public void testStepIdleStateLocked_ValidStates_WithLocationManager_NoProviders() {
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
- doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(false);
// Set state to INACTIVE.
mDeviceIdleController.becomeActiveLocked("testing", 0);
setChargingOn(false);
@@ -543,7 +639,7 @@ public class DeviceIdleControllerTest {
mInjector.locationManager = mLocationManager;
doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
// Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
- doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(false);
// Set state to INACTIVE.
mDeviceIdleController.becomeActiveLocked("testing", 0);
setChargingOn(false);
@@ -729,6 +825,8 @@ public class DeviceIdleControllerTest {
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
}
+ ///////////////// EXIT conditions ///////////////////
+
@Test
public void testExitMaintenanceEarlyIfNeededLocked_deep_noActiveOps() {
mDeviceIdleController.setJobsActive(false);
@@ -766,6 +864,10 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.setActiveIdleOpsForTest(0);
mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
verifyStateConditions(STATE_IDLE);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
}
@Test
@@ -803,6 +905,10 @@ public class DeviceIdleControllerTest {
enterDeepState(STATE_IDLE_MAINTENANCE);
mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
}
@Test
@@ -840,6 +946,10 @@ public class DeviceIdleControllerTest {
enterDeepState(STATE_IDLE_MAINTENANCE);
mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
}
@Test
@@ -877,6 +987,10 @@ public class DeviceIdleControllerTest {
enterDeepState(STATE_IDLE_MAINTENANCE);
mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
}
@Test
@@ -1030,39 +1144,100 @@ public class DeviceIdleControllerTest {
}
@Test
- public void testHandleMotionDetectedLocked_deep() {
+ public void testHandleMotionDetectedLocked_deep_quickDoze_off() {
enterDeepState(STATE_ACTIVE);
+ setQuickDozeEnabled(false);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
verifyStateConditions(STATE_ACTIVE);
// Anything that wasn't ACTIVE before motion detection should end up in the INACTIVE state.
enterDeepState(STATE_INACTIVE);
+ setQuickDozeEnabled(false);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_IDLE_PENDING);
+ setQuickDozeEnabled(false);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_SENSING);
+ setQuickDozeEnabled(false);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_LOCATING);
+ setQuickDozeEnabled(false);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_IDLE);
+ setQuickDozeEnabled(false);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
verifyStateConditions(STATE_INACTIVE);
enterDeepState(STATE_IDLE_MAINTENANCE);
+ setQuickDozeEnabled(false);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_INACTIVE);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ setQuickDozeEnabled(false);
+ // Disabling quick doze doesn't immediately change the state as coming out is harder than
+ // going in.
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
verifyStateConditions(STATE_INACTIVE);
}
@Test
+ public void testHandleMotionDetectedLocked_deep_quickDoze_on() {
+ enterDeepState(STATE_ACTIVE);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_ACTIVE);
+
+ // Anything that wasn't ACTIVE before motion detection should end up in the
+ // QUICK_DOZE_DELAY state since quick doze is enabled.
+
+ enterDeepState(STATE_INACTIVE);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_IDLE_PENDING);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_SENSING);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_LOCATING);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_IDLE);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_IDLE_MAINTENANCE);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ setQuickDozeEnabled(true);
+ mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+ verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+ }
+
+ @Test
public void testHandleMotionDetectedLocked_light() {
enterLightState(LIGHT_STATE_ACTIVE);
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
@@ -1128,6 +1303,10 @@ public class DeviceIdleControllerTest {
enterDeepState(STATE_IDLE_MAINTENANCE);
mDeviceIdleController.becomeActiveLocked("test", 1000);
verifyStateConditions(STATE_ACTIVE);
+
+ enterDeepState(STATE_QUICK_DOZE_DELAY);
+ mDeviceIdleController.becomeActiveLocked("test", 1000);
+ verifyStateConditions(STATE_ACTIVE);
}
@Test
@@ -1169,6 +1348,14 @@ public class DeviceIdleControllerTest {
setScreenOn(true);
mDeviceIdleController.becomeActiveLocked("testing", 0);
break;
+ case STATE_QUICK_DOZE_DELAY:
+ // Start off from ACTIVE in case we're already past the desired state.
+ enterDeepState(STATE_ACTIVE);
+ setQuickDozeEnabled(true);
+ setScreenOn(false);
+ setChargingOn(false);
+ mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+ break;
case STATE_LOCATING:
mInjector.locationManager = mLocationManager;
doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(
@@ -1180,8 +1367,11 @@ public class DeviceIdleControllerTest {
case STATE_IDLE_MAINTENANCE:
// Make sure the controller doesn't think there's a wake-from-idle alarm coming
// soon.
- doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+ setAlarmSoon(false);
case STATE_INACTIVE:
+ // Start off from ACTIVE in case we're already past the desired state.
+ enterDeepState(STATE_ACTIVE);
+ setQuickDozeEnabled(false);
setScreenOn(false);
setChargingOn(false);
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
@@ -1211,6 +1401,8 @@ public class DeviceIdleControllerTest {
case LIGHT_STATE_INACTIVE:
case LIGHT_STATE_IDLE:
case LIGHT_STATE_IDLE_MAINTENANCE:
+ // Start off from ACTIVE in case we're already past the desired state.
+ enterLightState(LIGHT_STATE_ACTIVE);
setScreenOn(false);
setChargingOn(false);
int count = 0;
@@ -1256,6 +1448,19 @@ public class DeviceIdleControllerTest {
mDeviceIdleController.updateConnectivityState(null);
}
+ private void setQuickDozeEnabled(boolean on) {
+ mDeviceIdleController.updateQuickDozeFlagLocked(on);
+ }
+
+ private void setAlarmSoon(boolean isSoon) {
+ if (isSoon) {
+ doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
+ mAlarmManager).getNextWakeFromIdleTime();
+ } else {
+ doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+ }
+ }
+
private void verifyStateConditions(int expectedState) {
int curState = mDeviceIdleController.getState();
assertEquals(
@@ -1292,7 +1497,9 @@ public class DeviceIdleControllerTest {
assertFalse(mDeviceIdleController.isScreenOn());
break;
case STATE_IDLE:
- assertTrue(mDeviceIdleController.mMotionListener.isActive());
+ assertTrue(mDeviceIdleController.mMotionListener.isActive()
+ // If quick doze is enabled, the motion listener should NOT be active.
+ || mDeviceIdleController.isQuickDozeEnabled());
assertFalse(mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
assertFalse(mDeviceIdleController.isScreenOn());
@@ -1300,7 +1507,16 @@ public class DeviceIdleControllerTest {
verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
break;
case STATE_IDLE_MAINTENANCE:
- assertTrue(mDeviceIdleController.mMotionListener.isActive());
+ assertTrue(mDeviceIdleController.mMotionListener.isActive()
+ // If quick doze is enabled, the motion listener should NOT be active.
+ || mDeviceIdleController.isQuickDozeEnabled());
+ assertFalse(mAnyMotionDetector.isMonitoring);
+ assertFalse(mDeviceIdleController.isCharging());
+ assertFalse(mDeviceIdleController.isScreenOn());
+ break;
+ case STATE_QUICK_DOZE_DELAY:
+ // If quick doze is enabled, the motion listener should NOT be active.
+ assertFalse(mDeviceIdleController.mMotionListener.isActive());
assertFalse(mAnyMotionDetector.isMonitoring);
assertFalse(mDeviceIdleController.isCharging());
assertFalse(mDeviceIdleController.isScreenOn());
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 2957267d2e5b..878179bb251d 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -24,7 +24,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
services.net \
services.usage \
guava \
- androidx-test \
+ androidx.test.runner \
+ androidx.test.rules \
mockito-target-minus-junit4 \
platform-test-annotations \
ShortcutManagerTestUtils \
diff --git a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
index 43438b99edef..802253280614 100644
--- a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
@@ -124,7 +124,7 @@ public class StorageManagerServiceTest {
"/storage/emulated/0/Android/sandbox/com.grey/foo.jpg",
"/storage/emulated/0/foo.jpg", PKG_GREY);
assertTranslation(
- "/storage/emulated/0/Android/sandbox/shared/colors/foo.jpg",
+ "/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg",
"/storage/emulated/0/foo.jpg", PKG_RED);
}
@@ -134,7 +134,7 @@ public class StorageManagerServiceTest {
"/storage/0000-0000/Android/sandbox/com.grey/foo/bar.jpg",
"/storage/0000-0000/foo/bar.jpg", PKG_GREY);
assertTranslation(
- "/storage/0000-0000/Android/sandbox/shared/colors/foo/bar.jpg",
+ "/storage/0000-0000/Android/sandbox/shared:colors/foo/bar.jpg",
"/storage/0000-0000/foo/bar.jpg", PKG_RED);
}
@@ -147,7 +147,7 @@ public class StorageManagerServiceTest {
// Accessing other package paths goes into sandbox
assertTranslation(
- "/storage/emulated/0/Android/sandbox/shared/colors/"
+ "/storage/emulated/0/Android/sandbox/shared:colors/"
+ "Android/data/com.grey/foo.jpg",
"/storage/emulated/0/Android/data/com.grey/foo.jpg", PKG_RED);
}
@@ -192,7 +192,7 @@ public class StorageManagerServiceTest {
// Sandboxes can't see paths in other sandboxes
try {
mService.translateSystemToApp(
- "/storage/emulated/0/Android/sandbox/shared/colors/foo.jpg",
+ "/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg",
PKG_GREY, UserHandle.USER_SYSTEM);
fail();
} catch (SecurityException expected) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
index c88b87328809..feffeef3f044 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
@@ -86,12 +86,8 @@ public class MagnificationControllerTest {
final AccessibilityManagerService mMockAms = mock(AccessibilityManagerService.class);
final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
final MessageCapturingHandler mMessageCapturingHandler =
- new MessageCapturingHandler(new Handler.Callback() {
- @Override
- public boolean handleMessage(Message msg) {
- return mMagnificationController.handleMessage(msg);
- }
- });
+ new MessageCapturingHandler(null);
+
final ValueAnimator mMockValueAnimator = mock(ValueAnimator.class);
MagnificationController.SettingsBridge mMockSettingsBridge;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
index 79e4d705db19..032074a7e398 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
@@ -29,9 +29,11 @@ import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.content.Context;
import android.os.Message;
@@ -44,7 +46,9 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
+import com.android.server.wm.WindowManagerInternal;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -101,8 +105,15 @@ public class MagnificationGestureHandlerTest {
public static final float DEFAULT_Y = 299;
private Context mContext;
- private AccessibilityManagerService mAms;
- private MagnificationController mMagnificationController;
+ final AccessibilityManagerService mMockAms = mock(AccessibilityManagerService.class);
+ final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
+ final MessageCapturingHandler mMessageCapturingHandler =
+ new MessageCapturingHandler(null);
+ final ValueAnimator mMockValueAnimator = mock(ValueAnimator.class);
+ MagnificationController.SettingsBridge mMockSettingsBridge =
+ mock(MagnificationController.SettingsBridge.class);
+ MagnificationController mMagnificationController;
+
private OffsettableClock mClock;
private MagnificationGestureHandler mMgh;
private TestHandler mHandler;
@@ -112,9 +123,9 @@ public class MagnificationGestureHandlerTest {
@Before
public void setUp() {
mContext = InstrumentationRegistry.getContext();
- mAms = new AccessibilityManagerService(mContext);
- mMagnificationController = new MagnificationController(
- mContext, mAms, /* lock */ new Object()) {
+ mMagnificationController = new MagnificationController(mContext, mMockAms, new Object(),
+ mMessageCapturingHandler, mMockWindowManager, mMockValueAnimator,
+ mMockSettingsBridge) {
@Override
public boolean magnificationRegionContains(float x, float y) {
return true;
@@ -123,7 +134,7 @@ public class MagnificationGestureHandlerTest {
@Override
void setForceShowMagnifiableBounds(boolean show) {}
};
- mMagnificationController.mRegistered = true;
+ mMagnificationController.register();
mClock = new OffsettableClock.Stopped();
boolean detectTripleTap = true;
@@ -131,6 +142,11 @@ public class MagnificationGestureHandlerTest {
mMgh = newInstance(detectTripleTap, detectShortcutTrigger);
}
+ @After
+ public void tearDown() {
+ mMagnificationController.unregister();
+ }
+
@NonNull
private MagnificationGestureHandler newInstance(boolean detectTripleTap,
boolean detectShortcutTrigger) {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
index ea90ffd0792f..0da574239666 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
@@ -20,11 +20,14 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
import android.platform.test.annotations.Presubmit;
@@ -131,4 +134,57 @@ public class ActivityDisplayTests extends ActivityTestsBase {
new ActivityBuilder(mService).setTask(fullscreenTask).build();
return fullscreenStack;
}
+
+ /**
+ * Verifies the correct activity is returned when querying the top running activity.
+ */
+ @Test
+ public void testTopRunningActivity() {
+ // Create stack to hold focus.
+ final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+ final ActivityStack emptyStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+ final KeyguardController keyguard = mSupervisor.getKeyguardController();
+ final ActivityStack stack = mSupervisor.getDefaultDisplay().createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
+ .setStack(stack).build();
+
+ // Make sure the top running activity is not affected when keyguard is not locked.
+ assertTopRunningActivity(activity, display);
+
+ // Check to make sure activity not reported when it cannot show on lock and lock is on.
+ doReturn(true).when(keyguard).isKeyguardLocked();
+ assertEquals(activity, display.topRunningActivity());
+ assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+ // Change focus to stack with activity.
+ stack.moveToFront("focusChangeToTestStack");
+ assertEquals(stack, display.getFocusedStack());
+ assertEquals(activity, display.topRunningActivity());
+ assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+ // Add activity that should be shown on the keyguard.
+ final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .setStack(stack)
+ .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
+ .build();
+
+ // Ensure the show when locked activity is returned.
+ assertTopRunningActivity(showWhenLockedActivity, display);
+
+ // Change focus back to empty stack.
+ emptyStack.moveToFront("focusChangeToEmptyStack");
+ assertEquals(emptyStack, display.getFocusedStack());
+ // If there is no running activity in focused stack, the running activity in next focusable
+ // stack should be returned.
+ assertTopRunningActivity(showWhenLockedActivity, display);
+ }
+
+ private static void assertTopRunningActivity(ActivityRecord top, ActivityDisplay display) {
+ assertEquals(top, display.topRunningActivity());
+ assertEquals(top, display.topRunningActivity(true /* considerKeyguardState */));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index cc7a24d5700e..2c993d32c20c 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -25,7 +25,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
@@ -307,62 +306,6 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
}
/**
- * Verifies the correct activity is returned when querying the top running activity.
- */
- @Test
- public void testTopRunningActivity() throws Exception {
- // Create stack to hold focus
- final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
- final ActivityStack emptyStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
- ACTIVITY_TYPE_STANDARD, true /* onTop */);
-
- final KeyguardController keyguard = mSupervisor.getKeyguardController();
- final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
- .setStack(stack).build();
-
- // Make sure the top running activity is not affected when keyguard is not locked
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Check to make sure activity not reported when it cannot show on lock and lock is on.
- doReturn(true).when(keyguard).isKeyguardLocked();
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Change focus to stack with activity.
- stack.moveToFront("focusChangeToTestStack");
- assertEquals(stack, display.getFocusedStack());
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Add activity that should be shown on the keyguard.
- final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
- .setCreateTask(true)
- .setStack(stack)
- .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
- .build();
-
- // Ensure the show when locked activity is returned.
- assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Change focus back to empty stack
- emptyStack.moveToFront("focusChangeToEmptyStack");
- assertEquals(emptyStack, display.getFocusedStack());
- // Looking for running activity only in top and focused stack, so nothing should be returned
- // from empty stack.
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
- }
-
- /**
* Verify that split-screen primary stack will be chosen if activity is launched that targets
* split-screen secondary, but a matching existing instance is found on top of split-screen
* primary stack.
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index 5fcd2aa35e05..53f67afb629e 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -26,6 +26,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
@@ -35,10 +38,14 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import android.content.pm.ActivityInfo;
import android.os.UserHandle;
@@ -655,6 +662,39 @@ public class ActivityStackTests extends ActivityTestsBase {
}
@Test
+ public void testFinishCurrentActivity() {
+ // Create 2 activities on a new display.
+ final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+ final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+ // There is still an activity1 in stack1 so the activity2 should be added to finishing list
+ // that will be destroyed until idle.
+ final ActivityRecord activity2 = finishCurrentActivity(stack2);
+ assertEquals(FINISHING, activity2.getState());
+ assertTrue(mSupervisor.mFinishingActivities.contains(activity2));
+
+ // The display becomes empty. Since there is no next activity to be idle, the activity
+ // should be destroyed immediately with updating configuration to restore original state.
+ final ActivityRecord activity1 = finishCurrentActivity(stack1);
+ assertEquals(DESTROYING, activity1.getState());
+ verify(mSupervisor).ensureVisibilityAndConfig(eq(null) /* starting */,
+ eq(display.mDisplayId), anyBoolean(), anyBoolean());
+ }
+
+ private ActivityRecord finishCurrentActivity(ActivityStack stack) {
+ final ActivityRecord activity = stack.topRunningActivityLocked();
+ assertNotNull(activity);
+ activity.setState(PAUSED, "finishCurrentActivity");
+ activity.makeFinishingLocked();
+ stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
+ false /* oomAdj */, "finishCurrentActivity");
+ return activity;
+ }
+
+ @Test
public void testShouldSleepActivities() throws Exception {
// When focused activity and keyguard is going away, we should not sleep regardless
// of the display state
diff --git a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
index bd4a356fcb5c..77f6a23c26b1 100644
--- a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
@@ -58,7 +58,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
+ "adjust_brightness_factor=0.7,"
+ "fullbackup_deferred=true,"
+ "keyvaluebackup_deferred=false,"
- + "gps_mode=0";
+ + "gps_mode=0,"
+ + "quick_doze_enabled=true";
private static final String BATTERY_SAVER_INCORRECT_CONSTANTS = "vi*,!=,,true";
private class BatterySaverPolicyForTest extends BatterySaverPolicy {
@@ -102,48 +103,48 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
@SmallTest
public void testGetBatterySaverPolicy_PolicyNull_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.NULL);
+ testServiceDefaultValue_On(ServiceType.NULL);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyVibration_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.VIBRATION);
+ testServiceDefaultValue_On(ServiceType.VIBRATION);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyVibration_WithAccessibilityEnabled() {
mBatterySaverPolicy.setAccessibilityEnabledForTest(true);
- testServiceDefaultValue_unchanged(ServiceType.VIBRATION);
+ testServiceDefaultValue_Off(ServiceType.VIBRATION);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicySound_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.SOUND);
+ testServiceDefaultValue_On(ServiceType.SOUND);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyFullBackup_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.FULL_BACKUP);
+ testServiceDefaultValue_On(ServiceType.FULL_BACKUP);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyKeyValueBackup_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.KEYVALUE_BACKUP);
+ testServiceDefaultValue_On(ServiceType.KEYVALUE_BACKUP);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyAnimation_DefaultValueCorrect() {
- testServiceDefaultValue_unchanged(ServiceType.ANIMATION);
+ testServiceDefaultValue_Off(ServiceType.ANIMATION);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyBatteryStats_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.BATTERY_STATS);
+ testServiceDefaultValue_On(ServiceType.BATTERY_STATS);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyNetworkFirewall_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.NETWORK_FIREWALL);
+ testServiceDefaultValue_On(ServiceType.NETWORK_FIREWALL);
}
@SmallTest
@@ -160,12 +161,12 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
@SmallTest
public void testGetBatterySaverPolicy_PolicyScreenBrightness_DefaultValueCorrect() {
- testServiceDefaultValue_unchanged(ServiceType.SCREEN_BRIGHTNESS);
+ testServiceDefaultValue_Off(ServiceType.SCREEN_BRIGHTNESS);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyGps_DefaultValueCorrect() {
- testServiceDefaultValue(ServiceType.GPS);
+ testServiceDefaultValue_On(ServiceType.GPS);
PowerSaveState stateOn =
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.GPS, true);
@@ -173,6 +174,11 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
}
@SmallTest
+ public void testGetBatterySaverPolicy_PolicyQuickDoze_DefaultValueCorrect() {
+ testServiceDefaultValue_Off(ServiceType.QUICK_DOZE);
+ }
+
+ @SmallTest
public void testUpdateConstants_getCorrectData() {
mBatterySaverPolicy.updateConstantsLocked(BATTERY_SAVER_CONSTANTS, "");
@@ -214,6 +220,10 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.GPS, BATTERY_SAVER_ON);
assertThat(gpsState.batterySaverEnabled).isTrue();
assertThat(gpsState.gpsMode).isEqualTo(GPS_MODE);
+
+ final PowerSaveState quickDozeState = mBatterySaverPolicy.getBatterySaverPolicy(
+ ServiceType.QUICK_DOZE, BATTERY_SAVER_ON);
+ assertThat(quickDozeState.batterySaverEnabled).isTrue();
}
@SmallTest
@@ -223,7 +233,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
mBatterySaverPolicy.updateConstantsLocked(null, "");
}
- private void testServiceDefaultValue(@ServiceType int type) {
+ private void testServiceDefaultValue_On(@ServiceType int type) {
mBatterySaverPolicy.updateConstantsLocked("", "");
final PowerSaveState batterySaverStateOn =
mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_ON);
@@ -234,7 +244,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertThat(batterySaverStateOff.batterySaverEnabled).isFalse();
}
- private void testServiceDefaultValue_unchanged(@ServiceType int type) {
+ private void testServiceDefaultValue_Off(@ServiceType int type) {
mBatterySaverPolicy.updateConstantsLocked("", "");
final PowerSaveState batterySaverStateOn =
mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_ON);
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 869f8fa0c2fa..caaa0bbe6c60 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -43,6 +43,7 @@ import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
import android.appwidget.AppWidgetManager;
@@ -92,6 +93,8 @@ public class AppStandbyControllerTests {
private static final int USER_ID = 0;
private static final int USER_ID2 = 10;
+ private static final String PACKAGE_UNKNOWN = "com.example.unknown";
+
private static final String ADMIN_PKG = "com.android.admin";
private static final String ADMIN_PKG2 = "com.android.admin2";
private static final String ADMIN_PKG3 = "com.android.admin3";
@@ -106,6 +109,9 @@ public class AppStandbyControllerTests {
// Short STABLE_CHARGING_THRESHOLD for testing purposes
private static final long STABLE_CHARGING_THRESHOLD = 2000;
+ /** Mock variable used in {@link MyInjector#isPackageInstalled(String, int, int)} */
+ private static boolean isPackageInstalled = true;
+
private MyInjector mInjector;
private AppStandbyController mController;
@@ -183,6 +189,12 @@ public class AppStandbyControllerTests {
}
@Override
+ boolean isPackageInstalled(String packageName, int flags, int userId) {
+ // Should always return true (default value) unless testing for an uninstalled app
+ return isPackageInstalled;
+ }
+
+ @Override
int[] getRunningUserIds() {
return new int[] {USER_ID};
}
@@ -403,30 +415,30 @@ public class AppStandbyControllerTests {
false));
}
- private void reportEvent(AppStandbyController controller, int eventType,
- long elapsedTime) {
+ private void reportEvent(AppStandbyController controller, int eventType, long elapsedTime,
+ String packageName) {
// Back to ACTIVE on event
mInjector.mElapsedRealtime = elapsedTime;
UsageEvents.Event ev = new UsageEvents.Event();
- ev.mPackage = PACKAGE_1;
+ ev.mPackage = packageName;
ev.mEventType = eventType;
controller.reportEvent(ev, elapsedTime, USER_ID);
}
- private int getStandbyBucket(AppStandbyController controller) {
- return controller.getAppStandbyBucket(PACKAGE_1, USER_ID, mInjector.mElapsedRealtime,
+ private int getStandbyBucket(AppStandbyController controller, String packageName) {
+ return controller.getAppStandbyBucket(packageName, USER_ID, mInjector.mElapsedRealtime,
true);
}
private void assertBucket(int bucket) {
- assertEquals(bucket, getStandbyBucket(mController));
+ assertEquals(bucket, getStandbyBucket(mController, PACKAGE_1));
}
@Test
public void testBuckets() throws Exception {
assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
// ACTIVE bucket
assertTimeout(mController, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
@@ -443,7 +455,7 @@ public class AppStandbyControllerTests {
// RARE bucket
assertTimeout(mController, RARE_THRESHOLD + 1, STANDBY_BUCKET_RARE);
- reportEvent(mController, USER_INTERACTION, RARE_THRESHOLD + 1);
+ reportEvent(mController, USER_INTERACTION, RARE_THRESHOLD + 1, PACKAGE_1);
assertTimeout(mController, RARE_THRESHOLD + 1, STANDBY_BUCKET_ACTIVE);
@@ -452,12 +464,48 @@ public class AppStandbyControllerTests {
}
@Test
+ public void testSetAppStandbyBucket() throws Exception {
+ // For a known package, standby bucket should be set properly
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
+ mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
+ REASON_MAIN_TIMEOUT, HOUR_MS);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
+
+ // For an unknown package, standby bucket should not be set, hence NEVER is returned
+ // Ensure the unknown package is not already in history by removing it
+ mController.clearAppIdleForPackage(PACKAGE_UNKNOWN, USER_ID);
+ isPackageInstalled = false; // Mock package is not installed
+ mController.setAppStandbyBucket(PACKAGE_UNKNOWN, USER_ID, STANDBY_BUCKET_ACTIVE,
+ REASON_MAIN_TIMEOUT, HOUR_MS);
+ isPackageInstalled = true; // Reset mocked variable for other tests
+ assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_UNKNOWN));
+ }
+
+ @Test
+ public void testAppStandbyBucketOnInstallAndUninstall() throws Exception {
+ // On package install, standby bucket should be ACTIVE
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_UNKNOWN);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_UNKNOWN));
+
+ // On uninstall, package should not exist in history and should return a NEVER bucket
+ mController.clearAppIdleForPackage(PACKAGE_UNKNOWN, USER_ID);
+ assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_UNKNOWN));
+ // Ensure uninstalled app is not in history
+ List<AppStandbyInfo> buckets = mController.getAppStandbyBuckets(USER_ID);
+ for(AppStandbyInfo bucket : buckets) {
+ if (bucket.mPackageName.equals(PACKAGE_UNKNOWN)) {
+ fail("packageName found in app idle history after uninstall.");
+ }
+ }
+ }
+
+ @Test
public void testScreenTimeAndBuckets() throws Exception {
mInjector.setDisplayOn(false);
assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
// ACTIVE bucket
assertTimeout(mController, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
@@ -468,7 +516,7 @@ public class AppStandbyControllerTests {
// RARE bucket, should fail because the screen wasn't ON.
mInjector.mElapsedRealtime = RARE_THRESHOLD + 1;
mController.checkIdleStates(USER_ID);
- assertNotEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+ assertNotEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
mInjector.setDisplayOn(true);
assertTimeout(mController, RARE_THRESHOLD * 2 + 2, STANDBY_BUCKET_RARE);
@@ -477,7 +525,7 @@ public class AppStandbyControllerTests {
@Test
public void testForcedIdle() throws Exception {
mController.forceIdleState(PACKAGE_1, USER_ID, true);
- assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0));
mController.forceIdleState(PACKAGE_1, USER_ID, false);
@@ -488,35 +536,35 @@ public class AppStandbyControllerTests {
@Test
public void testNotificationEvent() throws Exception {
- reportEvent(mController, USER_INTERACTION, 0);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
mInjector.mElapsedRealtime = 1;
- reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime, PACKAGE_1);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
mController.forceIdleState(PACKAGE_1, USER_ID, true);
- reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
- assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
+ reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime, PACKAGE_1);
+ assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
}
@Test
public void testSlicePinnedEvent() throws Exception {
- reportEvent(mController, USER_INTERACTION, 0);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
mInjector.mElapsedRealtime = 1;
- reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime, PACKAGE_1);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
mController.forceIdleState(PACKAGE_1, USER_ID, true);
- reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime);
- assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
+ reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime, PACKAGE_1);
+ assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
}
@Test
public void testSlicePinnedPrivEvent() throws Exception {
mController.forceIdleState(PACKAGE_1, USER_ID, true);
- reportEvent(mController, SLICE_PINNED_PRIV, mInjector.mElapsedRealtime);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ reportEvent(mController, SLICE_PINNED_PRIV, mInjector.mElapsedRealtime, PACKAGE_1);
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
}
@Test
@@ -524,28 +572,28 @@ public class AppStandbyControllerTests {
// Set it to timeout or usage, so that prediction can override it
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
REASON_MAIN_TIMEOUT, HOUR_MS);
- assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_PREDICTED, HOUR_MS);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
// Fast forward 12 hours
mInjector.mElapsedRealtime += WORKING_SET_THRESHOLD;
mController.checkIdleStates(USER_ID);
// Should still be in predicted bucket, since prediction timeout is 1 day since prediction
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
// Fast forward two more hours
mInjector.mElapsedRealtime += 2 * HOUR_MS;
mController.checkIdleStates(USER_ID);
// Should have now applied prediction timeout
- assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
// Fast forward RARE bucket
mInjector.mElapsedRealtime += RARE_THRESHOLD;
mController.checkIdleStates(USER_ID);
// Should continue to apply prediction timeout
- assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
}
@Test
@@ -553,33 +601,33 @@ public class AppStandbyControllerTests {
// Can force to NEVER
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
REASON_MAIN_FORCED, 1 * HOUR_MS);
- assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));
// Prediction can't override FORCED reason
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
REASON_MAIN_FORCED, 1 * HOUR_MS);
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
REASON_MAIN_PREDICTED, 1 * HOUR_MS);
- assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController, PACKAGE_1));
// Prediction can't override NEVER
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
REASON_MAIN_DEFAULT, 2 * HOUR_MS);
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_PREDICTED, 2 * HOUR_MS);
- assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));
// Prediction can't set to NEVER
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_USAGE, 2 * HOUR_MS);
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
REASON_MAIN_PREDICTED, 2 * HOUR_MS);
- assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+ assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
}
@Test
public void testTimeout() throws Exception {
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
mInjector.mElapsedRealtime = 2000;
@@ -601,10 +649,10 @@ public class AppStandbyControllerTests {
@Test
public void testCascadingTimeouts() throws Exception {
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
- reportEvent(mController, NOTIFICATION_SEEN, 1000);
+ reportEvent(mController, NOTIFICATION_SEEN, 1000, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
@@ -622,14 +670,15 @@ public class AppStandbyControllerTests {
@Test
public void testOverlappingTimeouts() throws Exception {
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
- reportEvent(mController, NOTIFICATION_SEEN, 1000);
+ reportEvent(mController, NOTIFICATION_SEEN, 1000, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
// Overlapping USER_INTERACTION before previous one times out
- reportEvent(mController, USER_INTERACTION, mController.mStrongUsageTimeoutMillis - 1000);
+ reportEvent(mController, USER_INTERACTION, mController.mStrongUsageTimeoutMillis - 1000,
+ PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
// Still in ACTIVE after first USER_INTERACTION times out
@@ -654,14 +703,14 @@ public class AppStandbyControllerTests {
public void testSystemInteractionTimeout() throws Exception {
setChargingState(mController, false);
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
// Fast forward to RARE
mInjector.mElapsedRealtime = RARE_THRESHOLD + 100;
mController.checkIdleStates(USER_ID);
assertBucket(STANDBY_BUCKET_RARE);
// Trigger a SYSTEM_INTERACTION and verify bucket
- reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime);
+ reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
// Verify it's still in ACTIVE close to end of timeout
@@ -677,11 +726,11 @@ public class AppStandbyControllerTests {
@Test
public void testPredictionNotOverridden() throws Exception {
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
mInjector.mElapsedRealtime = WORKING_SET_THRESHOLD - 1000;
- reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
+ reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
// Falls back to WORKING_SET
@@ -703,7 +752,7 @@ public class AppStandbyControllerTests {
@Test
public void testPredictionStrikesBack() throws Exception {
- reportEvent(mController, USER_INTERACTION, 0);
+ reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
// Predict to FREQUENT
@@ -714,7 +763,7 @@ public class AppStandbyControllerTests {
// Add a short timeout event
mInjector.mElapsedRealtime += 1000;
- reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime);
+ reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
mInjector.mElapsedRealtime += 1000;
mController.checkIdleStates(USER_ID);
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
index 07eafa5c4be4..a028d5eeb02e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
@@ -18,23 +18,34 @@
package com.android.server.wm;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
import android.app.WindowConfiguration;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.Surface;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.policy.WindowManagerPolicy;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
+/**
+ * Tests for the {@link DisplaySettings} class.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:com.android.server.wm.DisplaySettingsTests
+ */
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
@@ -155,6 +166,71 @@ public class DisplaySettingsTests extends WindowTestsBase {
assertOverscan(mPrimaryDisplay, 1 /* left */, 2 /* top */, 3 /* right */, 4 /* bottom */);
}
+ @Test
+ public void testDefaultToFreeUserRotation() {
+ mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+ final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
+ assertEquals(WindowManagerPolicy.USER_ROTATION_FREE, rotation.getUserRotationMode());
+ assertFalse(rotation.isRotationFrozen());
+ }
+
+ @Test
+ public void testDefaultTo0DegRotation() {
+ mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+ assertEquals(Surface.ROTATION_0, mSecondaryDisplay.getDisplayRotation().getUserRotation());
+ }
+
+ @Test
+ public void testPersistUserRotationModeInSameInstance() {
+ mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+ Surface.ROTATION_90);
+
+ mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+ final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
+ assertEquals(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation.getUserRotationMode());
+ assertTrue(rotation.isRotationFrozen());
+ }
+
+ @Test
+ public void testPersistUserRotationInSameInstance() {
+ mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+ Surface.ROTATION_90);
+
+ mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+ assertEquals(Surface.ROTATION_90, mSecondaryDisplay.getDisplayRotation().getUserRotation());
+ }
+
+ @Test
+ public void testPersistUserRotationModeAcrossInstances() {
+ mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+ Surface.ROTATION_270);
+ mTarget.writeSettingsLocked();
+
+ DisplaySettings target = new DisplaySettings(sWm, mTestFolder);
+ target.readSettingsLocked();
+
+ target.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+ final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
+ assertEquals(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation.getUserRotationMode());
+ assertTrue(rotation.isRotationFrozen());
+ }
+
+ @Test
+ public void testPersistUserRotationAcrossInstances() {
+ mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+ Surface.ROTATION_270);
+
+ mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+ assertEquals(Surface.ROTATION_270,
+ mSecondaryDisplay.getDisplayRotation().getUserRotation());
+ }
+
private static void assertOverscan(DisplayContent display, int left, int top, int right,
int bottom) {
final DisplayInfo info = display.getDisplayInfo();
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 474e5b75e5d8..51595514624c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -432,17 +432,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
}
@Override
- public int getUserRotationMode() {
- return 0;
- }
-
- @Override
- public void setUserRotationMode(int mode,
- int rotation) {
-
- }
-
- @Override
public int adjustSystemUiVisibilityLw(int visibility) {
return 0;
}
diff --git a/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk b/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
index 7e7decfa8e3b..ab222b941e94 100644
--- a/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
+++ b/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
@@ -20,7 +20,7 @@ LOCAL_MODULE_TAGS := tests
LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_STATIC_JAVA_LIBRARIES := androidx-test ub-uiautomator
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.runner ub-uiautomator
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_SRC_FILES += ../../src/com/android/server/pm/SuspendPackagesTest.java
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 4e007c2d9929..3266b8b92a19 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -1689,7 +1689,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
+ public void testGetNotificationChannelFromPrivilegedListener_cdm_success() throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
List<String> associations = new ArrayList<>();
associations.add("a");
@@ -1703,7 +1703,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
+ public void testGetNotificationChannelFromPrivilegedListener_cdm_noAccess() throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
List<String> associations = new ArrayList<>();
when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
@@ -1721,6 +1721,38 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testGetNotificationChannelFromPrivilegedListener_assistant_success()
+ throws Exception {
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(new ArrayList<>());
+ when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
+
+ mBinderService.getNotificationChannelsFromPrivilegedListener(
+ null, PKG, Process.myUserHandle());
+
+ verify(mPreferencesHelper, times(1)).getNotificationChannels(
+ anyString(), anyInt(), anyBoolean());
+ }
+
+ @Test
+ public void testGetNotificationChannelFromPrivilegedListener_assistant_noAccess() throws Exception {
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(new ArrayList<>());
+ when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(false);
+
+ try {
+ mBinderService.getNotificationChannelsFromPrivilegedListener(
+ null, PKG, Process.myUserHandle());
+ fail("listeners that don't have a companion device shouldn't be able to call this");
+ } catch (SecurityException e) {
+ // pass
+ }
+
+ verify(mPreferencesHelper, never()).getNotificationChannels(
+ anyString(), anyInt(), anyBoolean());
+ }
+
+ @Test
public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
List<String> associations = new ArrayList<>();
diff --git a/services/tests/wmtests/Android.mk b/services/tests/wmtests/Android.mk
index 0f8b18ab92cf..c095ae0dd2ff 100644
--- a/services/tests/wmtests/Android.mk
+++ b/services/tests/wmtests/Android.mk
@@ -14,7 +14,7 @@ LOCAL_SRC_FILES := \
$(call all-java-files-under, ../servicestests/utils)
LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx-test \
+ androidx.test.runner \
mockito-target-minus-junit4 \
platform-test-annotations \
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index 4e997323a30e..bc54a5d2c499 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -320,14 +320,7 @@ public class AppIdleHistory {
ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
AppUsageHistory appUsageHistory =
getPackageHistory(userHistory, packageName, elapsedRealtime, true);
- if (appUsageHistory == null) {
- return false; // Default to not idle
- } else {
- return appUsageHistory.currentBucket >= STANDBY_BUCKET_RARE;
- // Whether or not it's passed will now be externally calculated and the
- // bucket will be pushed to the history using setAppStandbyBucket()
- //return hasPassedThresholds(appUsageHistory, elapsedRealtime);
- }
+ return appUsageHistory.currentBucket >= STANDBY_BUCKET_RARE;
}
public AppUsageHistory getAppUsageHistory(String packageName, int userId,
@@ -404,17 +397,19 @@ public class AppIdleHistory {
public long getTimeSinceLastJobRun(String packageName, int userId, long elapsedRealtime) {
ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
AppUsageHistory appUsageHistory =
- getPackageHistory(userHistory, packageName, elapsedRealtime, true);
+ getPackageHistory(userHistory, packageName, elapsedRealtime, false);
// Don't adjust the default, else it'll wrap around to a positive value
- if (appUsageHistory.lastJobRunTime == Long.MIN_VALUE) return Long.MAX_VALUE;
+ if (appUsageHistory == null || appUsageHistory.lastJobRunTime == Long.MIN_VALUE) {
+ return Long.MAX_VALUE;
+ }
return getElapsedTime(elapsedRealtime) - appUsageHistory.lastJobRunTime;
}
public int getAppStandbyBucket(String packageName, int userId, long elapsedRealtime) {
ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
AppUsageHistory appUsageHistory =
- getPackageHistory(userHistory, packageName, elapsedRealtime, true);
- return appUsageHistory.currentBucket;
+ getPackageHistory(userHistory, packageName, elapsedRealtime, false);
+ return appUsageHistory == null ? STANDBY_BUCKET_NEVER : appUsageHistory.currentBucket;
}
public ArrayList<AppStandbyInfo> getAppStandbyBuckets(int userId, boolean appIdleEnabled) {
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 02ad3a8772f8..6a74564367b8 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -1161,6 +1161,10 @@ public class AppStandbyController {
void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
int reason, long elapsedRealtime, boolean resetTimeout) {
synchronized (mAppIdleLock) {
+ // If the package is not installed, don't allow the bucket to be set.
+ if (!mInjector.isPackageInstalled(packageName, 0, userId)) {
+ return;
+ }
AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
userId, elapsedRealtime);
boolean predicted = (reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED;
@@ -1594,6 +1598,10 @@ public class AppStandbyController {
return mPackageManagerInternal.isPackageEphemeral(userId, packageName);
}
+ boolean isPackageInstalled(String packageName, int flags, int userId) {
+ return mPackageManagerInternal.getPackageUid(packageName, flags, userId) >= 0;
+ }
+
int[] getRunningUserIds() throws RemoteException {
return ActivityManager.getService().getRunningUserIds();
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java
index 5bc8934279d6..571f623aea99 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java
@@ -22,9 +22,9 @@ import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Paint;
import android.graphics.Paint.Style;
+import android.graphics.RecordingCanvas;
import android.os.Bundle;
import android.os.Trace;
-import android.view.DisplayListCanvas;
import android.view.RenderNodeAnimator;
import android.view.View;
import android.widget.LinearLayout;
@@ -88,8 +88,8 @@ public class CirclePropActivity extends Activity {
super.onDraw(canvas);
if (canvas.isHardwareAccelerated()) {
- DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
- displayListCanvas.drawCircle(mX, mY, mRadius, mPaint);
+ RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
+ recordingCanvas.drawCircle(mX, mY, mRadius, mPaint);
}
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
index af8e10bc07ae..220016aa8ab7 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
@@ -16,25 +16,13 @@
package com.android.test.hwui;
-import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
-import static android.graphics.GraphicBuffer.USAGE_SW_READ_NEVER;
-import static android.graphics.GraphicBuffer.USAGE_SW_WRITE_NEVER;
-import static android.graphics.GraphicBuffer.USAGE_SW_WRITE_RARELY;
-
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.GraphicBuffer;
import android.graphics.Paint;
import android.graphics.Picture;
-import android.graphics.PixelFormat;
-import android.graphics.SurfaceTexture;
import android.os.Bundle;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-import android.view.Surface;
-import android.view.ThreadedRenderer;
import android.widget.ImageView;
public class DrawIntoHwBitmapActivity extends Activity {
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java
index 7713f5da36ed..e7d7f2b11801 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java
@@ -21,12 +21,12 @@ import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
+import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.view.DisplayListCanvas;
import android.view.ThreadedRenderer;
-import android.view.RenderNode;
+import android.graphics.RenderNode;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
@@ -206,7 +206,7 @@ public class MultiProducerActivity extends Activity implements OnClickListener {
}
// Draw frame
- DisplayListCanvas canvas = nodeFrame.start(currentFrameBounds.width(),
+ RecordingCanvas canvas = nodeFrame.start(currentFrameBounds.width(),
currentFrameBounds.height());
mFrameContent.draw(canvas);
nodeFrame.end(canvas);
@@ -228,7 +228,7 @@ public class MultiProducerActivity extends Activity implements OnClickListener {
}
// Draw Backdrop
- DisplayListCanvas canvas = nodeBack.start(currentBackBounds.width(),
+ RecordingCanvas canvas = nodeBack.start(currentBackBounds.width(),
currentBackBounds.height());
mBackContent.draw(canvas);
nodeBack.end(canvas);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
index be5d7f98783d..4eb40722f6dd 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
@@ -8,9 +8,8 @@ import android.os.Bundle;
import android.app.Activity;
import android.util.AttributeSet;
-import android.view.RenderNode;
+import android.graphics.RenderNode;
import android.view.View;
-import android.widget.LinearLayout;
public class ProjectionActivity extends Activity {
/**
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
index 2ae960bd08db..9abd7ea5f361 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
@@ -1,13 +1,7 @@
package com.android.test.hwui;
import android.app.Activity;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.RenderNode;
import android.view.View;
public class ProjectionClippingActivity extends Activity {
diff --git a/tests/Internal/res/xml/livewallpaper.xml b/tests/Internal/res/xml/livewallpaper.xml
index 6b5e84e8f9ad..36e7e4182c31 100644
--- a/tests/Internal/res/xml/livewallpaper.xml
+++ b/tests/Internal/res/xml/livewallpaper.xml
@@ -16,4 +16,5 @@
-->
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
- android:supportsAmbientMode="true"/> \ No newline at end of file
+ android:settingsSliceUri="content://com.android.internal.tests/slice"
+ android:supportsAmbientMode="true"/>
diff --git a/tests/Internal/src/android/app/WallpaperInfoTest.java b/tests/Internal/src/android/app/WallpaperInfoTest.java
index 98045ae98541..7f06f2cb7aeb 100644
--- a/tests/Internal/src/android/app/WallpaperInfoTest.java
+++ b/tests/Internal/src/android/app/WallpaperInfoTest.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.net.Uri;
import android.os.Parcel;
import android.service.wallpaper.WallpaperService;
import android.support.test.InstrumentationRegistry;
@@ -64,5 +65,31 @@ public class WallpaperInfoTest {
fromParcel.supportsAmbientMode());
parcel.recycle();
}
+
+ @Test
+ public void testGetSettingsSliceUri() throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
+
+ Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
+ intent.setPackage("com.android.internal.tests");
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> result = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
+ assertEquals(1, result.size());
+ ResolveInfo info = result.get(0);
+ WallpaperInfo wallpaperInfo = new WallpaperInfo(context, info);
+
+ // This expected Uri must be the same as that in livewallpaper.xml
+ Uri expectedUri = Uri.parse("content://com.android.internal.tests/slice");
+ Uri settingsUri = wallpaperInfo.getSettingsSliceUri();
+ assertEquals("The loaded URI should equal to the string in livewallpaper.xml",
+ 0, expectedUri.compareTo(settingsUri));
+ Parcel parcel = Parcel.obtain();
+ wallpaperInfo.writeToParcel(parcel, 0 /* flags */);
+ parcel.setDataPosition(0);
+ WallpaperInfo fromParcel = WallpaperInfo.CREATOR.createFromParcel(parcel);
+ assertEquals("settingsSliceUri should be restorable from parcelable",
+ 0, expectedUri.compareTo(fromParcel.getSettingsSliceUri()));
+ parcel.recycle();
+ }
}
diff --git a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java
index 6500428253f6..18cdf96c7131 100644
--- a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java
+++ b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java
@@ -34,7 +34,7 @@ public class Cujs {
// Do an explicit GC in the system server process as part of the test
// case to reduce GC-related sources of noise.
// SIGUSR1 = 10 is the magic signal to trigger the GC.
- int pid = mDevice.getPidForProcess("system_server");
+ int pid = mDevice.getProcessPid("system_server");
mDevice.executeShellCommand("kill -10 " + pid);
// Invoke the Device Cujs instrumentation to run the cujs.
diff --git a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java
index 03503cec5fec..26146ca0ea6c 100644
--- a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java
+++ b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java
@@ -19,9 +19,6 @@ package com.android.tests.sysmem.host;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import java.util.InputMismatchException;
-import java.util.Scanner;
-
/**
* Wrapper around ITestDevice exposing useful device functions.
*/
@@ -58,29 +55,15 @@ class Device {
/**
* Returns the pid for the process with the given name.
*/
- public int getPidForProcess(String name) throws TestException {
- String psout = executeShellCommand("ps -A -o PID,CMD");
- Scanner sc = new Scanner(psout);
+ public int getProcessPid(String name) throws TestException {
try {
- // ps output is of the form:
- // PID CMD
- // 1 init
- // 2 kthreadd
- // ...
- // 9693 ps
- sc.nextLine();
- while (sc.hasNextLine()) {
- int pid = sc.nextInt();
- String cmd = sc.next();
-
- if (name.equals(cmd)) {
- return pid;
- }
+ String pid = mDevice.getProcessPid(name);
+ if (pid == null) {
+ throw new TestException("failed to get pid for " + name);
}
- } catch (InputMismatchException e) {
- throw new TestException("unexpected ps output format: " + psout, e);
+ return Integer.parseInt(pid);
+ } catch (DeviceNotAvailableException e) {
+ throw new TestException(e);
}
-
- throw new TestException("failed to get pid for process " + name);
}
}
diff --git a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java
index b408a81d8f93..b46e642b5e92 100644
--- a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java
+++ b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java
@@ -79,7 +79,7 @@ class Metrics {
// adb root access is required to get showmap
mDevice.enableAdbRoot();
- int pid = mDevice.getPidForProcess("system_server");
+ int pid = mDevice.getProcessPid("system_server");
// Read showmap for system server and add it as a test log
String showmap = mDevice.executeShellCommand("showmap " + pid);
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 59ba8e7a6177..9adbe67c1553 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -3754,6 +3754,13 @@ public class WifiManager {
mCallback.onProvisioningFailure(status);
});
}
+
+ @Override
+ public void onProvisioningComplete() {
+ mHandler.post(() -> {
+ mCallback.onProvisioningComplete();
+ });
+ }
}
/**
diff --git a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
index c2cb16ab847c..a6bdd5b6bfff 100644
--- a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
@@ -32,5 +32,10 @@ oneway interface IProvisioningCallback
* Service to manager callback providing Provisioning status
*/
void onProvisioningStatus(int status);
+
+ /**
+ * Service to manager callback providing completion of Provisioning/Remediation flow
+ */
+ void onProvisioningComplete();
}
diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
index 6076175ce9d1..4b76526cbb59 100644
--- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
+++ b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
@@ -108,6 +108,48 @@ public abstract class ProvisioningCallback {
public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15;
/**
+ * The reason code for provisioning failure when there is no PPS MO.
+ * MO.
+ */
+ public static final int OSU_FAILURE_NO_PPS_MO = 16;
+
+ /**
+ * The reason code for provisioning failure when there is no AAAServerTrustRoot node in a PPS
+ * MO.
+ */
+ public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17;
+
+ /**
+ * The reason code for provisioning failure when there is no TrustRoot node for remediation
+ * server in a PPS MO.
+ */
+ public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18;
+
+ /**
+ * The reason code for provisioning failure when there is no TrustRoot node for policy server in
+ * a PPS MO.
+ */
+ public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19;
+
+ /**
+ * The reason code for provisioning failure when failing to retrieve trust root certificates
+ * used for validating server certificate for AAA, Remediation and Policy server.
+ */
+ public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20;
+
+ /**
+ * The reason code for provisioning failure when there is no trust root certificate for AAA
+ * server.
+ */
+ public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21;
+
+ /**
+ * The reason code for provisioning failure when a {@link PasspointConfiguration} is failed to
+ * install.
+ */
+ public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22;
+
+ /**
* The status code for provisioning flow to indicate connecting to OSU AP
*/
public static final int OSU_STATUS_AP_CONNECTING = 1;
@@ -158,6 +200,12 @@ public abstract class ProvisioningCallback {
public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10;
/**
+ * The status code for provisioning flow to indicate starting a step retrieving trust root
+ * certs.
+ */
+ public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11;
+
+ /**
* Provisioning status for OSU failure
*
* @param status indicates error condition
@@ -170,5 +218,10 @@ public abstract class ProvisioningCallback {
* @param status indicates status of OSU flow
*/
public abstract void onProvisioningStatus(int status);
+
+ /**
+ * Provisioning complete when provisioning/remediation flow completes
+ */
+ public abstract void onProvisioningComplete();
}