summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp5
-rw-r--r--StubLibraries.bp4
-rw-r--r--apct-tests/perftests/core/src/android/view/CutoutSpecificationBenchmark.java240
-rw-r--r--apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java5
-rw-r--r--apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java26
-rw-r--r--apex/statsd/framework/Android.bp20
-rw-r--r--apex/statsd/framework/java/android/app/StatsManager.java20
-rw-r--r--apex/statsd/framework/java/android/os/StatsDimensionsValue.java24
-rw-r--r--apex/statsd/framework/java/android/util/StatsLog.java29
-rw-r--r--apex/statsd/service/Android.bp21
-rw-r--r--cmds/statsd/src/atoms.proto4
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java10
-rw-r--r--core/java/android/content/pm/parsing/AndroidPackage.java2
-rw-r--r--core/java/android/content/pm/parsing/ApkParseUtils.java20
-rw-r--r--core/java/android/content/pm/parsing/PackageImpl.java14
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackage.java2
-rw-r--r--core/java/android/view/CutoutSpecification.java486
-rw-r--r--core/java/android/view/DisplayCutout.java101
-rw-r--r--core/java/android/view/WindowManagerImpl.java2
-rw-r--r--core/jni/Android.bp2
-rw-r--r--core/res/res/values-af/strings.xml2
-rw-r--r--core/res/res/values-am/strings.xml2
-rw-r--r--core/res/res/values-ar/strings.xml6
-rw-r--r--core/res/res/values-as/strings.xml2
-rw-r--r--core/res/res/values-az/strings.xml2
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml2
-rw-r--r--core/res/res/values-be/strings.xml2
-rw-r--r--core/res/res/values-bg/strings.xml2
-rw-r--r--core/res/res/values-bn/strings.xml4
-rw-r--r--core/res/res/values-bs/strings.xml2
-rw-r--r--core/res/res/values-ca/strings.xml24
-rw-r--r--core/res/res/values-cs/strings.xml2
-rw-r--r--core/res/res/values-da/strings.xml2
-rw-r--r--core/res/res/values-de/strings.xml2
-rw-r--r--core/res/res/values-el/strings.xml2
-rw-r--r--core/res/res/values-en-rAU/strings.xml2
-rw-r--r--core/res/res/values-en-rCA/strings.xml2
-rw-r--r--core/res/res/values-en-rGB/strings.xml2
-rw-r--r--core/res/res/values-en-rIN/strings.xml2
-rw-r--r--core/res/res/values-en-rXC/strings.xml2
-rw-r--r--core/res/res/values-es-rUS/strings.xml2
-rw-r--r--core/res/res/values-es/strings.xml4
-rw-r--r--core/res/res/values-et/strings.xml2
-rw-r--r--core/res/res/values-eu/strings.xml4
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-fi/strings.xml2
-rw-r--r--core/res/res/values-fr-rCA/strings.xml2
-rw-r--r--core/res/res/values-fr/strings.xml2
-rw-r--r--core/res/res/values-gl/strings.xml2
-rw-r--r--core/res/res/values-gu/strings.xml2
-rw-r--r--core/res/res/values-hi/strings.xml2
-rw-r--r--core/res/res/values-hr/strings.xml2
-rw-r--r--core/res/res/values-hu/strings.xml2
-rw-r--r--core/res/res/values-hy/strings.xml2
-rw-r--r--core/res/res/values-in/strings.xml2
-rw-r--r--core/res/res/values-is/strings.xml2
-rw-r--r--core/res/res/values-it/strings.xml2
-rw-r--r--core/res/res/values-iw/strings.xml2
-rw-r--r--core/res/res/values-ja/strings.xml2
-rw-r--r--core/res/res/values-ka/strings.xml2
-rw-r--r--core/res/res/values-kk/strings.xml2
-rw-r--r--core/res/res/values-km/strings.xml2
-rw-r--r--core/res/res/values-kn/strings.xml2
-rw-r--r--core/res/res/values-ko/strings.xml2
-rw-r--r--core/res/res/values-ky/strings.xml4
-rw-r--r--core/res/res/values-lo/strings.xml2
-rw-r--r--core/res/res/values-lt/strings.xml2
-rw-r--r--core/res/res/values-lv/strings.xml2
-rw-r--r--core/res/res/values-mk/strings.xml2
-rw-r--r--core/res/res/values-ml/strings.xml2
-rw-r--r--core/res/res/values-mn/strings.xml2
-rw-r--r--core/res/res/values-mr/strings.xml2
-rw-r--r--core/res/res/values-ms/strings.xml2
-rw-r--r--core/res/res/values-my/strings.xml2
-rw-r--r--core/res/res/values-nb/strings.xml2
-rw-r--r--core/res/res/values-ne/strings.xml2
-rw-r--r--core/res/res/values-nl/strings.xml2
-rw-r--r--core/res/res/values-or/strings.xml2
-rw-r--r--core/res/res/values-pa/strings.xml2
-rw-r--r--core/res/res/values-pl/strings.xml2
-rw-r--r--core/res/res/values-pt-rBR/strings.xml6
-rw-r--r--core/res/res/values-pt-rPT/strings.xml2
-rw-r--r--core/res/res/values-pt/strings.xml6
-rw-r--r--core/res/res/values-ro/strings.xml2
-rw-r--r--core/res/res/values-ru/strings.xml4
-rw-r--r--core/res/res/values-si/strings.xml2
-rw-r--r--core/res/res/values-sk/strings.xml4
-rw-r--r--core/res/res/values-sl/strings.xml2
-rw-r--r--core/res/res/values-sq/strings.xml2
-rw-r--r--core/res/res/values-sr/strings.xml2
-rw-r--r--core/res/res/values-sv/strings.xml2
-rw-r--r--core/res/res/values-sw/strings.xml2
-rw-r--r--core/res/res/values-ta/strings.xml2
-rw-r--r--core/res/res/values-te/strings.xml2
-rw-r--r--core/res/res/values-th/strings.xml2
-rw-r--r--core/res/res/values-tl/strings.xml2
-rw-r--r--core/res/res/values-tr/strings.xml2
-rw-r--r--core/res/res/values-uk/strings.xml2
-rw-r--r--core/res/res/values-ur/strings.xml2
-rw-r--r--core/res/res/values-uz/strings.xml2
-rw-r--r--core/res/res/values-vi/strings.xml2
-rw-r--r--core/res/res/values-zh-rCN/strings.xml2
-rw-r--r--core/res/res/values-zh-rHK/strings.xml2
-rw-r--r--core/res/res/values-zh-rTW/strings.xml2
-rw-r--r--core/res/res/values-zu/strings.xml2
-rw-r--r--core/res/res/values/attrs_manifest.xml3
-rw-r--r--core/tests/coretests/Android.bp5
-rw-r--r--core/tests/coretests/src/android/view/CutoutSpecificationTest.java262
-rw-r--r--libs/hwui/Android.bp2
-rw-r--r--libs/hwui/hwui/AnimatedImageDrawable.cpp6
-rw-r--r--media/java/android/media/ExifInterface.java20
-rw-r--r--media/java/android/media/MediaRouter2Manager.java14
-rw-r--r--media/java/android/media/session/MediaSession.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java103
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java184
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java85
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java161
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineViewController.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableViewController.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ActivatableNotificationViewModule.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/AppName.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java122
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationKey.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java81
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java10
-rw-r--r--packages/Tethering/Android.bp29
-rw-r--r--packages/Tethering/jni/android_net_util_TetheringUtils.cpp110
-rw-r--r--packages/Tethering/src/android/net/util/TetheringUtils.java8
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java113
-rw-r--r--packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java8
-rw-r--r--packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java38
-rw-r--r--services/Android.bp1
-rw-r--r--services/core/java/com/android/server/media/MediaButtonReceiverHolder.java360
-rw-r--r--services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java6
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java19
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java189
-rw-r--r--services/core/java/com/android/server/pm/AppsFilter.java63
-rw-r--r--services/core/java/com/android/server/rollback/AppDataRollbackHelper.java7
-rw-r--r--services/core/java/com/android/server/rollback/Rollback.java3
-rw-r--r--services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java23
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java12
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java8
-rw-r--r--services/core/java/com/android/server/wm/Task.java32
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java79
-rw-r--r--tools/aapt2/link/ManifestFixer.cpp1
161 files changed, 2929 insertions, 933 deletions
diff --git a/Android.bp b/Android.bp
index e18e493fcdf5..df852bda4904 100644
--- a/Android.bp
+++ b/Android.bp
@@ -458,7 +458,7 @@ java_library {
libs: [
"framework-appsearch-stubs",
"framework-sdkextensions-stubs-systemapi",
- "framework-statsd", // TODO(b/146167933): Use framework-statsd-stubs
+ "framework-statsd-stubs-module_libs_api",
"framework-permission-stubs-systemapi",
"framework-wifi-stubs",
"ike-stubs",
@@ -511,8 +511,7 @@ java_library {
"framework-mediaprovider-stubs-systemapi",
"framework-permission-stubs-systemapi",
"framework-sdkextensions-stubs-systemapi",
- // TODO(b/146167933): Use framework-statsd-stubs instead.
- "framework-statsd",
+ "framework-statsd-stubs-module_libs_api",
"framework-wifi-stubs",
"ike-stubs",
"framework-tethering-stubs",
diff --git a/StubLibraries.bp b/StubLibraries.bp
index d4db7373504b..9b9311f6c3c2 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -190,7 +190,6 @@ droidstubs {
droidstubs {
name: "module-lib-api",
defaults: ["metalava-api-stubs-default"],
- libs: ["framework-all"],
arg_files: ["core/res/AndroidManifest.xml"],
args: metalava_framework_docs_args + module_libs,
check_api: {
@@ -222,7 +221,6 @@ droidstubs {
droidstubs {
name: "module-lib-api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
- libs: ["framework-all"],
arg_files: ["core/res/AndroidManifest.xml"],
args: metalava_framework_docs_args + priv_apps + module_libs,
}
@@ -299,12 +297,12 @@ java_library_static {
],
libs: [
"stub-annotations",
- "framework-all",
],
static_libs: [
"private-stub-annotations-jar",
],
defaults: ["framework-stubs-default"],
+ sdk_version: "core_current",
}
/////////////////////////////////////////////////////////////////////
diff --git a/apct-tests/perftests/core/src/android/view/CutoutSpecificationBenchmark.java b/apct-tests/perftests/core/src/android/view/CutoutSpecificationBenchmark.java
new file mode 100644
index 000000000000..14282bfbd24e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/view/CutoutSpecificationBenchmark.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2020 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.view;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.PathParser;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CutoutSpecificationBenchmark {
+ private static final String TAG = "CutoutSpecificationBenchmark";
+
+ private static final String BOTTOM_MARKER = "@bottom";
+ private static final String DP_MARKER = "@dp";
+ private static final String RIGHT_MARKER = "@right";
+ private static final String LEFT_MARKER = "@left";
+
+ private static final String DOUBLE_CUTOUT_SPEC = "M 0,0\n"
+ + "L -72, 0\n"
+ + "L -69.9940446283, 20.0595537175\n"
+ + "C -69.1582133885, 28.4178661152 -65.2, 32.0 -56.8, 32.0\n"
+ + "L 56.8, 32.0\n"
+ + "C 65.2, 32.0 69.1582133885, 28.4178661152 69.9940446283, 20.0595537175\n"
+ + "L 72, 0\n"
+ + "Z\n"
+ + "@bottom\n"
+ + "M 0,0\n"
+ + "L -72, 0\n"
+ + "L -69.9940446283, -20.0595537175\n"
+ + "C -69.1582133885, -28.4178661152 -65.2, -32.0 -56.8, -32.0\n"
+ + "L 56.8, -32.0\n"
+ + "C 65.2, -32.0 69.1582133885, -28.4178661152 69.9940446283, -20.0595537175\n"
+ + "L 72, 0\n"
+ + "Z\n"
+ + "@dp";
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ private Context mContext;
+ private DisplayMetrics mDisplayMetrics;
+
+ /**
+ * Setup the necessary member field used by test methods.
+ */
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ mDisplayMetrics = new DisplayMetrics();
+ mContext.getDisplay().getRealMetrics(mDisplayMetrics);
+ }
+
+
+ private static void toRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) {
+ final RectF rectF = new RectF();
+ p.computeBounds(rectF, false /* unused */);
+ rectF.round(inoutRect);
+ inoutRegion.op(inoutRect, Region.Op.UNION);
+ }
+
+ private static void oldMethodParsingSpec(String spec, int displayWidth, int displayHeight,
+ float density) {
+ Path p = null;
+ Rect boundTop = null;
+ Rect boundBottom = null;
+ Rect safeInset = new Rect();
+ String bottomSpec = null;
+ if (!TextUtils.isEmpty(spec)) {
+ spec = spec.trim();
+ final float offsetX;
+ if (spec.endsWith(RIGHT_MARKER)) {
+ offsetX = displayWidth;
+ spec = spec.substring(0, spec.length() - RIGHT_MARKER.length()).trim();
+ } else if (spec.endsWith(LEFT_MARKER)) {
+ offsetX = 0;
+ spec = spec.substring(0, spec.length() - LEFT_MARKER.length()).trim();
+ } else {
+ offsetX = displayWidth / 2f;
+ }
+ final boolean inDp = spec.endsWith(DP_MARKER);
+ if (inDp) {
+ spec = spec.substring(0, spec.length() - DP_MARKER.length());
+ }
+
+ if (spec.contains(BOTTOM_MARKER)) {
+ String[] splits = spec.split(BOTTOM_MARKER, 2);
+ spec = splits[0].trim();
+ bottomSpec = splits[1].trim();
+ }
+
+ final Matrix m = new Matrix();
+ final Region r = Region.obtain();
+ if (!spec.isEmpty()) {
+ try {
+ p = PathParser.createPathFromPathData(spec);
+ } catch (Throwable e) {
+ Log.wtf(TAG, "Could not inflate cutout: ", e);
+ }
+
+ if (p != null) {
+ if (inDp) {
+ m.postScale(density, density);
+ }
+ m.postTranslate(offsetX, 0);
+ p.transform(m);
+
+ boundTop = new Rect();
+ toRectAndAddToRegion(p, r, boundTop);
+ safeInset.top = boundTop.bottom;
+ }
+ }
+
+ if (bottomSpec != null) {
+ int bottomInset = 0;
+ Path bottomPath = null;
+ try {
+ bottomPath = PathParser.createPathFromPathData(bottomSpec);
+ } catch (Throwable e) {
+ Log.wtf(TAG, "Could not inflate bottom cutout: ", e);
+ }
+
+ if (bottomPath != null) {
+ // Keep top transform
+ m.postTranslate(0, displayHeight);
+ bottomPath.transform(m);
+ p.addPath(bottomPath);
+ boundBottom = new Rect();
+ toRectAndAddToRegion(bottomPath, r, boundBottom);
+ bottomInset = displayHeight - boundBottom.top;
+ }
+ safeInset.bottom = bottomInset;
+ }
+ }
+ }
+
+ @Test
+ public void parseByOldMethodForDoubleCutout() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ oldMethodParsingSpec(DOUBLE_CUTOUT_SPEC, mDisplayMetrics.widthPixels,
+ mDisplayMetrics.heightPixels, mDisplayMetrics.density);
+ }
+ }
+
+ @Test
+ public void parseByNewMethodForDoubleCutout() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ new CutoutSpecification.Parser(mDisplayMetrics.density,
+ mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)
+ .parse(DOUBLE_CUTOUT_SPEC);
+ }
+ }
+
+ @Test
+ public void parseLongEdgeCutout() {
+ final String spec = "M 0,0\n"
+ + "H 48\n"
+ + "V 48\n"
+ + "H -48\n"
+ + "Z\n"
+ + "@left\n"
+ + "@center_vertical\n"
+ + "M 0,0\n"
+ + "H 48\n"
+ + "V 48\n"
+ + "H -48\n"
+ + "Z\n"
+ + "@left\n"
+ + "@center_vertical\n"
+ + "M 0,0\n"
+ + "H -48\n"
+ + "V 48\n"
+ + "H 48\n"
+ + "Z\n"
+ + "@right\n"
+ + "@dp";
+
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ new CutoutSpecification.Parser(mDisplayMetrics.density,
+ mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels).parse(spec);
+ }
+ }
+
+ @Test
+ public void parseShortEdgeCutout() {
+ final String spec = "M 0,0\n"
+ + "H 48\n"
+ + "V 48\n"
+ + "H -48\n"
+ + "Z\n"
+ + "@bottom\n"
+ + "M 0,0\n"
+ + "H 48\n"
+ + "V -48\n"
+ + "H -48\n"
+ + "Z\n"
+ + "@dp";
+
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ new CutoutSpecification.Parser(mDisplayMetrics.density,
+ mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels).parse(spec);
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
index b6e39e14602a..8633c9613138 100644
--- a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
@@ -125,7 +125,9 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase {
final WindowManager.LayoutParams mParams;
final int mWidth;
final int mHeight;
+ final Point mOutSurfaceSize = new Point();
final SurfaceControl mOutSurfaceControl;
+ final SurfaceControl mOutBlastSurfaceControl = new SurfaceControl();
final IntSupplier mViewVisibility;
@@ -150,7 +152,8 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase {
mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame,
mOutContentInsets, mOutVisibleInsets, mOutStableInsets,
mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration,
- mOutSurfaceControl, mOutInsetsState, new Point(), new SurfaceControl());
+ mOutSurfaceControl, mOutInsetsState, mOutSurfaceSize,
+ mOutBlastSurfaceControl);
}
}
}
diff --git a/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
index 62e9ba84530c..9e17e940a06b 100644
--- a/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
+++ b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
@@ -20,15 +20,19 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import android.app.Activity;
import android.app.UiAutomation;
+import android.content.Context;
import android.content.Intent;
+import android.os.BatteryManager;
import android.os.ParcelFileDescriptor;
import android.perftests.utils.PerfTestActivity;
+import android.provider.Settings;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.lifecycle.ActivityLifecycleCallback;
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import androidx.test.runner.lifecycle.Stage;
+import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@@ -52,18 +56,36 @@ public class WindowManagerPerfTestBase {
*/
static final File BASE_OUT_PATH = new File("/data/local/CorePerfTests");
+ private static int sOriginalStayOnWhilePluggedIn;
+
@BeforeClass
public static void setUpOnce() {
+ final Context context = getInstrumentation().getContext();
+ sOriginalStayOnWhilePluggedIn = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
+ // Keep the device awake during testing.
+ setStayOnWhilePluggedIn(BatteryManager.BATTERY_PLUGGED_USB);
+
if (!BASE_OUT_PATH.exists()) {
executeShellCommand("mkdir -p " + BASE_OUT_PATH);
}
// In order to be closer to the real use case.
executeShellCommand("input keyevent KEYCODE_WAKEUP");
executeShellCommand("wm dismiss-keyguard");
- getInstrumentation().getContext().startActivity(new Intent(Intent.ACTION_MAIN)
+ context.startActivity(new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
+ @AfterClass
+ public static void tearDownOnce() {
+ setStayOnWhilePluggedIn(sOriginalStayOnWhilePluggedIn);
+ }
+
+ private static void setStayOnWhilePluggedIn(int value) {
+ executeShellCommand(String.format("settings put global %s %d",
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN, value));
+ }
+
/**
* Executes shell command with reading the output. It may also used to block until the current
* command is completed.
@@ -97,7 +119,7 @@ public class WindowManagerPerfTestBase {
*/
static class PerfTestActivityRule extends ActivityTestRule<PerfTestActivity> {
private final Intent mStartIntent =
- new Intent().putExtra(PerfTestActivity.INTENT_EXTRA_KEEP_SCREEN_ON, true);
+ new Intent(getInstrumentation().getTargetContext(), PerfTestActivity.class);
private final LifecycleListener mLifecycleListener = new LifecycleListener();
PerfTestActivityRule() {
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index e3c70d7982ac..80def475efb9 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -12,11 +12,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+genrule {
+ name: "statslog-statsd-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module statsd" +
+ " --javaPackage com.android.internal.util --javaClass StatsdStatsLog",
+ out: ["com/android/internal/util/StatsdStatsLog.java"],
+}
+
+java_library_static {
+ name: "statslog-statsd",
+ srcs: [
+ ":statslog-statsd-java-gen",
+ ],
+}
+
filegroup {
name: "framework-statsd-sources",
srcs: [
"java/**/*.java",
":statsd_java_aidl",
+ ":statslog-statsd-java-gen",
],
}
@@ -42,8 +58,7 @@ java_library {
hostdex: true, // for hiddenapi check
visibility: [
"//frameworks/base/apex/statsd:__subpackages__",
- //TODO(b/146167933) remove this when framework is built with framework-statsd-stubs
- "//frameworks/base",
+ //TODO(b/146167933) remove this
"//frameworks/opt/net/wifi/service",
],
apex_available: [
@@ -103,7 +118,6 @@ java_library {
sdk_version: "core_platform",
}
-// TODO(b/146167933): Use these stubs in frameworks/base/Android.bp
java_library {
name: "framework-statsd-stubs-systemapi",
srcs: [ ":framework-statsd-stubs-srcs-systemapi" ],
diff --git a/apex/statsd/framework/java/android/app/StatsManager.java b/apex/statsd/framework/java/android/app/StatsManager.java
index 411482b88326..526d17ff0d71 100644
--- a/apex/statsd/framework/java/android/app/StatsManager.java
+++ b/apex/statsd/framework/java/android/app/StatsManager.java
@@ -32,7 +32,7 @@ import android.os.IStatsd;
import android.os.RemoteException;
import android.os.StatsFrameworkInitializer;
import android.util.AndroidException;
-import android.util.Slog;
+import android.util.Log;
import android.util.StatsEvent;
import android.util.StatsEventParcel;
@@ -155,7 +155,7 @@ public final class StatsManager {
// can throw IllegalArgumentException
service.addConfiguration(configKey, config, mContext.getOpPackageName());
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsmanager when adding configuration");
+ Log.e(TAG, "Failed to connect to statsmanager when adding configuration");
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
throw new StatsUnavailableException(e.getMessage(), e);
@@ -191,7 +191,7 @@ public final class StatsManager {
IStatsManagerService service = getIStatsManagerServiceLocked();
service.removeConfiguration(configKey, mContext.getOpPackageName());
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsmanager when removing configuration");
+ Log.e(TAG, "Failed to connect to statsmanager when removing configuration");
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
throw new StatsUnavailableException(e.getMessage(), e);
@@ -258,7 +258,7 @@ public final class StatsManager {
mContext.getOpPackageName());
}
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsmanager when adding broadcast subscriber",
+ Log.e(TAG, "Failed to connect to statsmanager when adding broadcast subscriber",
e);
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
@@ -311,7 +311,7 @@ public final class StatsManager {
}
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsmanager when registering data listener.");
+ Log.e(TAG, "Failed to connect to statsmanager when registering data listener.");
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
throw new StatsUnavailableException(e.getMessage(), e);
@@ -348,7 +348,7 @@ public final class StatsManager {
}
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsmanager "
+ Log.e(TAG, "Failed to connect to statsmanager "
+ "when registering active configs listener.");
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
@@ -387,7 +387,7 @@ public final class StatsManager {
IStatsManagerService service = getIStatsManagerServiceLocked();
return service.getData(configKey, mContext.getOpPackageName());
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsmanager when getting data");
+ Log.e(TAG, "Failed to connect to statsmanager when getting data");
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
throw new StatsUnavailableException(e.getMessage(), e);
@@ -424,7 +424,7 @@ public final class StatsManager {
IStatsManagerService service = getIStatsManagerServiceLocked();
return service.getMetadata(mContext.getOpPackageName());
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsmanager when getting metadata");
+ Log.e(TAG, "Failed to connect to statsmanager when getting metadata");
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
throw new StatsUnavailableException(e.getMessage(), e);
@@ -464,7 +464,7 @@ public final class StatsManager {
return service.getRegisteredExperimentIds();
} catch (RemoteException e) {
if (DEBUG) {
- Slog.d(TAG,
+ Log.d(TAG,
"Failed to connect to StatsManagerService when getting "
+ "registered experiment IDs");
}
@@ -555,7 +555,7 @@ public final class StatsManager {
try {
resultReceiver.pullFinished(atomTag, success, parcels);
} catch (RemoteException e) {
- Slog.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
+ Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId);
}
});
} finally {
diff --git a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java b/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
index 71d43599fc82..35273da96413 100644
--- a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
+++ b/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
@@ -16,7 +16,7 @@
package android.os;
import android.annotation.SystemApi;
-import android.util.Slog;
+import android.util.Log;
import java.util.ArrayList;
import java.util.List;
@@ -129,7 +129,7 @@ public final class StatsDimensionsValue implements Parcelable {
mValue = values;
break;
default:
- Slog.w(TAG, "StatsDimensionsValueParcel contains bad valueType: " + mValueType);
+ Log.w(TAG, "StatsDimensionsValueParcel contains bad valueType: " + mValueType);
mValue = null;
break;
}
@@ -155,7 +155,7 @@ public final class StatsDimensionsValue implements Parcelable {
try {
if (mValueType == STRING_VALUE_TYPE) return (String) mValue;
} catch (ClassCastException e) {
- Slog.w(TAG, "Failed to successfully get value", e);
+ Log.w(TAG, "Failed to successfully get value", e);
}
return null;
}
@@ -169,7 +169,7 @@ public final class StatsDimensionsValue implements Parcelable {
try {
if (mValueType == INT_VALUE_TYPE) return (Integer) mValue;
} catch (ClassCastException e) {
- Slog.w(TAG, "Failed to successfully get value", e);
+ Log.w(TAG, "Failed to successfully get value", e);
}
return 0;
}
@@ -183,7 +183,7 @@ public final class StatsDimensionsValue implements Parcelable {
try {
if (mValueType == LONG_VALUE_TYPE) return (Long) mValue;
} catch (ClassCastException e) {
- Slog.w(TAG, "Failed to successfully get value", e);
+ Log.w(TAG, "Failed to successfully get value", e);
}
return 0;
}
@@ -198,7 +198,7 @@ public final class StatsDimensionsValue implements Parcelable {
try {
if (mValueType == BOOLEAN_VALUE_TYPE) return (Boolean) mValue;
} catch (ClassCastException e) {
- Slog.w(TAG, "Failed to successfully get value", e);
+ Log.w(TAG, "Failed to successfully get value", e);
}
return false;
}
@@ -212,7 +212,7 @@ public final class StatsDimensionsValue implements Parcelable {
try {
if (mValueType == FLOAT_VALUE_TYPE) return (Float) mValue;
} catch (ClassCastException e) {
- Slog.w(TAG, "Failed to successfully get value", e);
+ Log.w(TAG, "Failed to successfully get value", e);
}
return 0;
}
@@ -238,7 +238,7 @@ public final class StatsDimensionsValue implements Parcelable {
}
return copy;
} catch (ClassCastException e) {
- Slog.w(TAG, "Failed to successfully get value", e);
+ Log.w(TAG, "Failed to successfully get value", e);
return null;
}
}
@@ -297,7 +297,7 @@ public final class StatsDimensionsValue implements Parcelable {
}
return sb.toString();
} catch (ClassCastException e) {
- Slog.w(TAG, "Failed to successfully get value", e);
+ Log.w(TAG, "Failed to successfully get value", e);
}
return "";
}
@@ -357,11 +357,11 @@ public final class StatsDimensionsValue implements Parcelable {
return true;
}
default:
- Slog.w(TAG, "readValue of an impossible type " + valueType);
+ Log.w(TAG, "readValue of an impossible type " + valueType);
return false;
}
} catch (ClassCastException e) {
- Slog.w(TAG, "writeValue cast failed", e);
+ Log.w(TAG, "writeValue cast failed", e);
return false;
}
}
@@ -388,7 +388,7 @@ public final class StatsDimensionsValue implements Parcelable {
return values;
}
default:
- Slog.w(TAG, "readValue of an impossible type " + valueType);
+ Log.w(TAG, "readValue of an impossible type " + valueType);
return null;
}
}
diff --git a/apex/statsd/framework/java/android/util/StatsLog.java b/apex/statsd/framework/java/android/util/StatsLog.java
index e7659d88dd81..511bc01f521e 100644
--- a/apex/statsd/framework/java/android/util/StatsLog.java
+++ b/apex/statsd/framework/java/android/util/StatsLog.java
@@ -26,10 +26,10 @@ import android.annotation.SystemApi;
import android.content.Context;
import android.os.IStatsd;
import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.os.StatsFrameworkInitializer;
import android.util.proto.ProtoOutputStream;
-import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.util.StatsdStatsLog;
/**
* StatsLog provides an API for developers to send events to statsd. The events can be used to
@@ -59,17 +59,17 @@ public final class StatsLog {
IStatsd service = getIStatsdLocked();
if (service == null) {
if (DEBUG) {
- Slog.d(TAG, "Failed to find statsd when logging start");
+ Log.d(TAG, "Failed to find statsd when logging start");
}
return false;
}
service.sendAppBreadcrumbAtom(label,
- FrameworkStatsLog.APP_BREADCRUMB_REPORTED__STATE__START);
+ StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__START);
return true;
} catch (RemoteException e) {
sService = null;
if (DEBUG) {
- Slog.d(TAG, "Failed to connect to statsd when logging start");
+ Log.d(TAG, "Failed to connect to statsd when logging start");
}
return false;
}
@@ -88,17 +88,17 @@ public final class StatsLog {
IStatsd service = getIStatsdLocked();
if (service == null) {
if (DEBUG) {
- Slog.d(TAG, "Failed to find statsd when logging stop");
+ Log.d(TAG, "Failed to find statsd when logging stop");
}
return false;
}
service.sendAppBreadcrumbAtom(
- label, FrameworkStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP);
+ label, StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP);
return true;
} catch (RemoteException e) {
sService = null;
if (DEBUG) {
- Slog.d(TAG, "Failed to connect to statsd when logging stop");
+ Log.d(TAG, "Failed to connect to statsd when logging stop");
}
return false;
}
@@ -117,17 +117,17 @@ public final class StatsLog {
IStatsd service = getIStatsdLocked();
if (service == null) {
if (DEBUG) {
- Slog.d(TAG, "Failed to find statsd when logging event");
+ Log.d(TAG, "Failed to find statsd when logging event");
}
return false;
}
service.sendAppBreadcrumbAtom(
- label, FrameworkStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED);
+ label, StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED);
return true;
} catch (RemoteException e) {
sService = null;
if (DEBUG) {
- Slog.d(TAG, "Failed to connect to statsd when logging event");
+ Log.d(TAG, "Failed to connect to statsd when logging event");
}
return false;
}
@@ -162,7 +162,7 @@ public final class StatsLog {
| EXPERIMENT_IDS_FIELD_ID,
id);
}
- FrameworkStatsLog.write(FrameworkStatsLog.BINARY_PUSH_STATE_CHANGED,
+ StatsdStatsLog.write(StatsdStatsLog.BINARY_PUSH_STATE_CHANGED,
trainName,
trainVersionCode,
(options & IStatsd.FLAG_REQUIRE_STAGING) > 0,
@@ -180,7 +180,10 @@ public final class StatsLog {
if (sService != null) {
return sService;
}
- sService = IStatsd.Stub.asInterface(ServiceManager.getService("stats"));
+ sService = IStatsd.Stub.asInterface(StatsFrameworkInitializer
+ .getStatsServiceManager()
+ .getStatsdServiceRegisterer()
+ .get());
return sService;
}
diff --git a/apex/statsd/service/Android.bp b/apex/statsd/service/Android.bp
index 910384845810..0f8a151eed7c 100644
--- a/apex/statsd/service/Android.bp
+++ b/apex/statsd/service/Android.bp
@@ -1,17 +1,30 @@
// Statsd Service jar, which will eventually be put in the statsd mainline apex.
// service-statsd needs to be added to PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS.
// This jar will contain StatsCompanionService
+
+filegroup {
+ name: "service-statsd-sources",
+ srcs: [
+ "java/**/*.java",
+ ],
+}
+
java_library {
name: "service-statsd",
installable: true,
srcs: [
- "java/**/*.java",
+ ":service-statsd-sources",
],
- // TODO: link against the proper stubs (b/146084685).
+ // TODO(b/146209659): Use system_current instead once framework-statsd compiles against
+ // system_current.
+ sdk_version: "core_platform",
libs: [
- "framework-minus-apex",
- "services.core",
+ "framework-annotations-lib",
+ "framework-statsd",
+ // TODO(b/146758669): Remove this line after nullability annotations are system APIs.
+ "android_system_stubs_current",
+ "services-stubs",
],
apex_available: [
"com.android.os.statsd",
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 4288f5b18367..447775431fc7 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -127,7 +127,7 @@ message Atom {
WallClockTimeShifted wall_clock_time_shifted = 45 [(module) = "framework"];
AnomalyDetected anomaly_detected = 46;
AppBreadcrumbReported app_breadcrumb_reported =
- 47 [(allow_from_any_uid) = true, (module) = "framework"];
+ 47 [(allow_from_any_uid) = true, (module) = "statsd"];
AppStartOccurred app_start_occurred = 48 [(module) = "framework"];
AppStartCanceled app_start_canceled = 49 [(module) = "framework"];
AppStartFullyDrawn app_start_fully_drawn = 50 [(module) = "framework"];
@@ -188,7 +188,7 @@ message Atom {
ServiceStateChanged service_state_changed = 99 [(module) = "framework"];
ServiceLaunchReported service_launch_reported = 100 [(module) = "framework"];
FlagFlipUpdateOccurred flag_flip_update_occurred = 101 [(module) = "framework"];
- BinaryPushStateChanged binary_push_state_changed = 102 [(module) = "framework"];
+ BinaryPushStateChanged binary_push_state_changed = 102 [(module) = "statsd"];
DevicePolicyEvent device_policy_event = 103 [(module) = "framework"];
DocsUIFileOperationCanceledReported docs_ui_file_op_canceled = 104 [(module) = "docsui"];
DocsUIFileOperationCopyMoveModeReported docs_ui_file_op_copy_move_mode_reported =
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 759979100483..9cec514ec592 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -9462,16 +9462,6 @@ public class DevicePolicyManager {
* {@link android.os.Build.VERSION_CODES#M} the app-op matching the permission is set to
* {@link android.app.AppOpsManager#MODE_IGNORED}, but the permission stays granted.
*
- * NOTE: Starting from Android R, location-related permissions cannot be granted by the
- * admin: Calling this method with {@link #PERMISSION_GRANT_STATE_GRANTED} for any of the
- * following permissions will return false:
- *
- * <ul>
- * <li>{@code ACCESS_FINE_LOCATION}</li>
- * <li>{@code ACCESS_BACKGROUND_LOCATION}</li>
- * <li>{@code ACCESS_COARSE_LOCATION}</li>
- * </ul>
- *
* @param admin Which profile or device owner this request is associated with.
* @param packageName The application to grant or revoke a permission to.
* @param permission The permission to grant or revoke.
diff --git a/core/java/android/content/pm/parsing/AndroidPackage.java b/core/java/android/content/pm/parsing/AndroidPackage.java
index fbe5a48ad61e..da17ff3cdefc 100644
--- a/core/java/android/content/pm/parsing/AndroidPackage.java
+++ b/core/java/android/content/pm/parsing/AndroidPackage.java
@@ -286,6 +286,8 @@ public interface AndroidPackage extends Parcelable {
List<String> getQueriesPackages();
+ Set<String> getQueriesProviders();
+
String getRealPackage();
// TODO(b/135203078): Rename to getRequiredFeatures? Somewhat ambiguous whether "Req" is
diff --git a/core/java/android/content/pm/parsing/ApkParseUtils.java b/core/java/android/content/pm/parsing/ApkParseUtils.java
index 5c8c9a41a520..548d82a6ab76 100644
--- a/core/java/android/content/pm/parsing/ApkParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkParseUtils.java
@@ -96,6 +96,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.StringTokenizer;
/** @hide */
public class ApkParseUtils {
@@ -1817,6 +1818,25 @@ public class ApkParseUtils {
);
}
parsingPackage.addQueriesPackage(packageName.intern());
+ } else if (parser.getName().equals("provider")) {
+ final TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestQueriesProvider);
+ try {
+ final String authorities =
+ sa.getString(R.styleable.AndroidManifestQueriesProvider_authorities);
+ if (TextUtils.isEmpty(authorities)) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Authority missing from provider tag."
+ );
+ }
+ StringTokenizer authoritiesTokenizer = new StringTokenizer(authorities, ";");
+ while (authoritiesTokenizer.hasMoreElements()) {
+ parsingPackage.addQueriesProvider(authoritiesTokenizer.nextToken());
+ }
+ } finally {
+ sa.recycle();
+ }
}
}
return parseInput.success(parsingPackage);
diff --git a/core/java/android/content/pm/parsing/PackageImpl.java b/core/java/android/content/pm/parsing/PackageImpl.java
index fe8307c7c8cd..0df950006f43 100644
--- a/core/java/android/content/pm/parsing/PackageImpl.java
+++ b/core/java/android/content/pm/parsing/PackageImpl.java
@@ -216,6 +216,9 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
private ArrayList<String> queriesPackages;
@Nullable
+ private ArraySet<String> queriesProviders;
+
+ @Nullable
private ArrayMap<String, ComponentParseUtils.ParsedProcess> processes;
private String[] splitClassLoaderNames;
@@ -957,6 +960,12 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
}
@Override
+ public ParsingPackage addQueriesProvider(String authority) {
+ this.queriesProviders = ArrayUtils.add(this.queriesProviders, authority);
+ return this;
+ }
+
+ @Override
public PackageImpl setProcesses(ArrayMap<String, ComponentParseUtils.ParsedProcess> processes) {
this.processes = processes;
return this;
@@ -2975,6 +2984,11 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
return queriesPackages;
}
+ @Override
+ public Set<String> getQueriesProviders() {
+ return queriesProviders;
+ }
+
private static void internStringArrayList(List<String> list) {
if (list != null) {
final int N = list.size();
diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java
index 9ddcc0995fd4..a2fe064b66c3 100644
--- a/core/java/android/content/pm/parsing/ParsingPackage.java
+++ b/core/java/android/content/pm/parsing/ParsingPackage.java
@@ -100,6 +100,8 @@ public interface ParsingPackage extends AndroidPackage {
ParsingPackage addQueriesPackage(String packageName);
+ ParsingPackage addQueriesProvider(String authority);
+
ParsingPackage setProcesses(ArrayMap<String, ComponentParseUtils.ParsedProcess> processes);
ParsingPackage asSplit(
diff --git a/core/java/android/view/CutoutSpecification.java b/core/java/android/view/CutoutSpecification.java
new file mode 100644
index 000000000000..d21a9520e12c
--- /dev/null
+++ b/core/java/android/view/CutoutSpecification.java
@@ -0,0 +1,486 @@
+/*
+ * Copyright (C) 2020 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.view;
+
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.RIGHT;
+import static android.view.Gravity.TOP;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Insets;
+import android.graphics.Matrix;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.PathParser;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * In order to accept the cutout specification for all of edges in devices, the specification
+ * parsing method is extracted from
+ * {@link android.view.DisplayCutout#fromResourcesRectApproximation(Resources, int, int)} to be
+ * the specified class for parsing the specification.
+ * BNF definition:
+ * <ul>
+ * <li>Cutouts Specification = ([Cutout Delimiter],Cutout Specification) {...}, [Dp] ; </li>
+ * <li>Cutout Specification = [Vertical Position], (SVG Path Element), [Horizontal Position]
+ * [Bind Cutout] ;</li>
+ * <li>Vertical Position = "@bottom" | "@center_vertical" ;</li>
+ * <li>Horizontal Position = "@left" | "@right" ;</li>
+ * <li>Bind Cutout = "@bind_left_cutout" | "@bind_right_cutout" ;</li>
+ * <li>Cutout Delimiter = "@cutout" ;</li>
+ * <li>Dp = "@dp"</li>
+ * </ul>
+ *
+ * <ul>
+ * <li>Vertical position is top by default if there is neither "@bottom" nor "@center_vertical"
+ * </li>
+ * <li>Horizontal position is center horizontal by default if there is neither "@left" nor
+ * "@right".</li>
+ * <li>@bottom make the cutout piece bind to bottom edge.</li>
+ * <li>both of @bind_left_cutout and @bind_right_cutout are use to claim the cutout belong to
+ * left or right edge cutout.</li>
+ * </ul>
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = PACKAGE)
+public class CutoutSpecification {
+ private static final String TAG = "CutoutSpecification";
+ private static final boolean DEBUG = false;
+
+ private static final int MINIMAL_ACCEPTABLE_PATH_LENGTH = "H1V1Z".length();
+
+ private static final char MARKER_START_CHAR = '@';
+ private static final String DP_MARKER = MARKER_START_CHAR + "dp";
+
+ private static final String BOTTOM_MARKER = MARKER_START_CHAR + "bottom";
+ private static final String RIGHT_MARKER = MARKER_START_CHAR + "right";
+ private static final String LEFT_MARKER = MARKER_START_CHAR + "left";
+ private static final String CUTOUT_MARKER = MARKER_START_CHAR + "cutout";
+ private static final String CENTER_VERTICAL_MARKER = MARKER_START_CHAR + "center_vertical";
+
+ /* By default, it's top bound cutout. That's why TOP_BOUND_CUTOUT_MARKER is not defined */
+ private static final String BIND_RIGHT_CUTOUT_MARKER = MARKER_START_CHAR + "bind_right_cutout";
+ private static final String BIND_LEFT_CUTOUT_MARKER = MARKER_START_CHAR + "bind_left_cutout";
+
+ private final Path mPath;
+ private final Rect mLeftBound;
+ private final Rect mTopBound;
+ private final Rect mRightBound;
+ private final Rect mBottomBound;
+ private final Insets mInsets;
+
+ private CutoutSpecification(@NonNull Parser parser) {
+ mPath = parser.mPath;
+ mLeftBound = parser.mLeftBound;
+ mTopBound = parser.mTopBound;
+ mRightBound = parser.mRightBound;
+ mBottomBound = parser.mBottomBound;
+ mInsets = parser.mInsets;
+
+ if (DEBUG) {
+ Log.d(TAG, String.format(Locale.ENGLISH,
+ "left cutout = %s, top cutout = %s, right cutout = %s, bottom cutout = %s",
+ mLeftBound != null ? mLeftBound.toString() : "",
+ mTopBound != null ? mTopBound.toString() : "",
+ mRightBound != null ? mRightBound.toString() : "",
+ mBottomBound != null ? mBottomBound.toString() : ""));
+ }
+ }
+
+ @VisibleForTesting(visibility = PACKAGE)
+ @Nullable
+ public Path getPath() {
+ return mPath;
+ }
+
+ @VisibleForTesting(visibility = PACKAGE)
+ @Nullable
+ public Rect getLeftBound() {
+ return mLeftBound;
+ }
+
+ @VisibleForTesting(visibility = PACKAGE)
+ @Nullable
+ public Rect getTopBound() {
+ return mTopBound;
+ }
+
+ @VisibleForTesting(visibility = PACKAGE)
+ @Nullable
+ public Rect getRightBound() {
+ return mRightBound;
+ }
+
+ @VisibleForTesting(visibility = PACKAGE)
+ @Nullable
+ public Rect getBottomBound() {
+ return mBottomBound;
+ }
+
+ /**
+ * To count the safe inset according to the cutout bounds and waterfall inset.
+ *
+ * @return the safe inset.
+ */
+ @VisibleForTesting(visibility = PACKAGE)
+ @NonNull
+ public Rect getSafeInset() {
+ return mInsets.toRect();
+ }
+
+ private static int decideWhichEdge(boolean isTopEdgeShortEdge,
+ boolean isShortEdge, boolean isStart) {
+ return (isTopEdgeShortEdge)
+ ? ((isShortEdge) ? (isStart ? TOP : BOTTOM) : (isStart ? LEFT : RIGHT))
+ : ((isShortEdge) ? (isStart ? LEFT : RIGHT) : (isStart ? TOP : BOTTOM));
+ }
+
+ /**
+ * The CutoutSpecification Parser.
+ */
+ @VisibleForTesting(visibility = PACKAGE)
+ public static class Parser {
+ private final boolean mIsShortEdgeOnTop;
+ private final float mDensity;
+ private final int mDisplayWidth;
+ private final int mDisplayHeight;
+ private final Matrix mMatrix;
+ private Insets mInsets;
+ private int mSafeInsetLeft;
+ private int mSafeInsetTop;
+ private int mSafeInsetRight;
+ private int mSafeInsetBottom;
+
+ private final Rect mTmpRect = new Rect();
+ private final RectF mTmpRectF = new RectF();
+
+ private boolean mInDp;
+
+ private Path mPath;
+ private Rect mLeftBound;
+ private Rect mTopBound;
+ private Rect mRightBound;
+ private Rect mBottomBound;
+
+ private boolean mPositionFromLeft = false;
+ private boolean mPositionFromRight = false;
+ private boolean mPositionFromBottom = false;
+ private boolean mPositionFromCenterVertical = false;
+
+ private boolean mBindLeftCutout = false;
+ private boolean mBindRightCutout = false;
+ private boolean mBindBottomCutout = false;
+
+ private boolean mIsTouchShortEdgeStart;
+ private boolean mIsTouchShortEdgeEnd;
+ private boolean mIsCloserToStartSide;
+
+ /**
+ * The constructor of the CutoutSpecification parser to parse the specification of cutout.
+ * @param density the display density.
+ * @param displayWidth the display width.
+ * @param displayHeight the display height.
+ */
+ @VisibleForTesting(visibility = PACKAGE)
+ public Parser(float density, int displayWidth, int displayHeight) {
+ mDensity = density;
+ mDisplayWidth = displayWidth;
+ mDisplayHeight = displayHeight;
+ mMatrix = new Matrix();
+ mIsShortEdgeOnTop = mDisplayWidth < mDisplayHeight;
+ }
+
+ private void computeBoundsRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) {
+ mTmpRectF.setEmpty();
+ p.computeBounds(mTmpRectF, false /* unused */);
+ mTmpRectF.round(inoutRect);
+ inoutRegion.op(inoutRect, Region.Op.UNION);
+ }
+
+ private void resetStatus(StringBuilder sb) {
+ sb.setLength(0);
+ mPositionFromBottom = false;
+ mPositionFromLeft = false;
+ mPositionFromRight = false;
+ mPositionFromCenterVertical = false;
+
+ mBindLeftCutout = false;
+ mBindRightCutout = false;
+ mBindBottomCutout = false;
+ }
+
+ private void translateMatrix() {
+ final float offsetX;
+ if (mPositionFromRight) {
+ offsetX = mDisplayWidth;
+ } else if (mPositionFromLeft) {
+ offsetX = 0;
+ } else {
+ offsetX = mDisplayWidth / 2f;
+ }
+
+ final float offsetY;
+ if (mPositionFromBottom) {
+ offsetY = mDisplayHeight;
+ } else if (mPositionFromCenterVertical) {
+ offsetY = mDisplayHeight / 2f;
+ } else {
+ offsetY = 0;
+ }
+
+ mMatrix.reset();
+ if (mInDp) {
+ mMatrix.postScale(mDensity, mDensity);
+ }
+ mMatrix.postTranslate(offsetX, offsetY);
+ }
+
+ private int computeSafeInsets(int gravity, Rect rect) {
+ if (gravity == LEFT && rect.right > 0 && rect.right < mDisplayWidth) {
+ return rect.right;
+ } else if (gravity == TOP && rect.bottom > 0 && rect.bottom < mDisplayHeight) {
+ return rect.bottom;
+ } else if (gravity == RIGHT && rect.left > 0 && rect.left < mDisplayWidth) {
+ return mDisplayWidth - rect.left;
+ } else if (gravity == BOTTOM && rect.top > 0 && rect.top < mDisplayHeight) {
+ return mDisplayHeight - rect.top;
+ }
+ return 0;
+ }
+
+ private void setSafeInset(int gravity, int inset) {
+ if (gravity == LEFT) {
+ mSafeInsetLeft = inset;
+ } else if (gravity == TOP) {
+ mSafeInsetTop = inset;
+ } else if (gravity == RIGHT) {
+ mSafeInsetRight = inset;
+ } else if (gravity == BOTTOM) {
+ mSafeInsetBottom = inset;
+ }
+ }
+
+ private int getSafeInset(int gravity) {
+ if (gravity == LEFT) {
+ return mSafeInsetLeft;
+ } else if (gravity == TOP) {
+ return mSafeInsetTop;
+ } else if (gravity == RIGHT) {
+ return mSafeInsetRight;
+ } else if (gravity == BOTTOM) {
+ return mSafeInsetBottom;
+ }
+ return 0;
+ }
+
+ @NonNull
+ private Rect onSetEdgeCutout(boolean isStart, boolean isShortEdge, @NonNull Rect rect) {
+ final int gravity;
+ if (isShortEdge) {
+ gravity = decideWhichEdge(mIsShortEdgeOnTop, true, isStart);
+ } else {
+ if (mIsTouchShortEdgeStart && mIsTouchShortEdgeEnd) {
+ gravity = decideWhichEdge(mIsShortEdgeOnTop, false, isStart);
+ } else if (mIsTouchShortEdgeStart || mIsTouchShortEdgeEnd) {
+ gravity = decideWhichEdge(mIsShortEdgeOnTop, true,
+ mIsCloserToStartSide);
+ } else {
+ gravity = decideWhichEdge(mIsShortEdgeOnTop, isShortEdge, isStart);
+ }
+ }
+
+ int oldSafeInset = getSafeInset(gravity);
+ int newSafeInset = computeSafeInsets(gravity, rect);
+ if (oldSafeInset < newSafeInset) {
+ setSafeInset(gravity, newSafeInset);
+ }
+
+ return new Rect(rect);
+ }
+
+ private void setEdgeCutout(@NonNull Path newPath) {
+ if (mBindRightCutout && mRightBound == null) {
+ mRightBound = onSetEdgeCutout(false, !mIsShortEdgeOnTop, mTmpRect);
+ } else if (mBindLeftCutout && mLeftBound == null) {
+ mLeftBound = onSetEdgeCutout(true, !mIsShortEdgeOnTop, mTmpRect);
+ } else if (mBindBottomCutout && mBottomBound == null) {
+ mBottomBound = onSetEdgeCutout(false, mIsShortEdgeOnTop, mTmpRect);
+ } else if (!(mBindBottomCutout || mBindLeftCutout || mBindRightCutout)
+ && mTopBound == null) {
+ mTopBound = onSetEdgeCutout(true, mIsShortEdgeOnTop, mTmpRect);
+ } else {
+ return;
+ }
+
+ if (mPath != null) {
+ mPath.addPath(newPath);
+ } else {
+ mPath = newPath;
+ }
+ }
+
+ private void parseSvgPathSpec(Region region, String spec) {
+ if (TextUtils.length(spec) < MINIMAL_ACCEPTABLE_PATH_LENGTH) {
+ Log.e(TAG, "According to SVG definition, it shouldn't happen");
+ return;
+ }
+ spec.trim();
+ translateMatrix();
+
+ final Path newPath = PathParser.createPathFromPathData(spec);
+ newPath.transform(mMatrix);
+ computeBoundsRectAndAddToRegion(newPath, region, mTmpRect);
+
+ if (DEBUG) {
+ Log.d(TAG, String.format(Locale.ENGLISH,
+ "hasLeft = %b, hasRight = %b, hasBottom = %b, hasCenterVertical = %b",
+ mPositionFromLeft, mPositionFromRight, mPositionFromBottom,
+ mPositionFromCenterVertical));
+ Log.d(TAG, "region = " + region);
+ Log.d(TAG, "spec = \"" + spec + "\" rect = " + mTmpRect + " newPath = " + newPath);
+ }
+
+ if (mTmpRect.isEmpty()) {
+ return;
+ }
+
+ if (mIsShortEdgeOnTop) {
+ mIsTouchShortEdgeStart = mTmpRect.top <= 0;
+ mIsTouchShortEdgeEnd = mTmpRect.bottom >= mDisplayHeight;
+ mIsCloserToStartSide = mTmpRect.centerY() < mDisplayHeight / 2;
+ } else {
+ mIsTouchShortEdgeStart = mTmpRect.left <= 0;
+ mIsTouchShortEdgeEnd = mTmpRect.right >= mDisplayWidth;
+ mIsCloserToStartSide = mTmpRect.centerX() < mDisplayWidth / 2;
+ }
+
+ setEdgeCutout(newPath);
+ }
+
+ private void parseSpecWithoutDp(@NonNull String specWithoutDp) {
+ Region region = Region.obtain();
+ StringBuilder sb = null;
+ int currentIndex = 0;
+ int lastIndex = 0;
+ while ((currentIndex = specWithoutDp.indexOf(MARKER_START_CHAR, lastIndex)) != -1) {
+ if (sb == null) {
+ sb = new StringBuilder(specWithoutDp.length());
+ }
+ sb.append(specWithoutDp, lastIndex, currentIndex);
+
+ if (specWithoutDp.startsWith(LEFT_MARKER, currentIndex)) {
+ if (!mPositionFromRight) {
+ mPositionFromLeft = true;
+ }
+ currentIndex += LEFT_MARKER.length();
+ } else if (specWithoutDp.startsWith(RIGHT_MARKER, currentIndex)) {
+ if (!mPositionFromLeft) {
+ mPositionFromRight = true;
+ }
+ currentIndex += RIGHT_MARKER.length();
+ } else if (specWithoutDp.startsWith(BOTTOM_MARKER, currentIndex)) {
+ if (!mPositionFromCenterVertical) {
+ parseSvgPathSpec(region, sb.toString());
+ }
+ currentIndex += BOTTOM_MARKER.length();
+
+ /* prepare to parse the rest path */
+ resetStatus(sb);
+ mBindBottomCutout = true;
+ mPositionFromBottom = true;
+ } else if (specWithoutDp.startsWith(CENTER_VERTICAL_MARKER, currentIndex)) {
+ if (!mPositionFromBottom) {
+ parseSvgPathSpec(region, sb.toString());
+ }
+ currentIndex += CENTER_VERTICAL_MARKER.length();
+
+ /* prepare to parse the rest path */
+ resetStatus(sb);
+ mPositionFromCenterVertical = true;
+ } else if (specWithoutDp.startsWith(CUTOUT_MARKER, currentIndex)) {
+ parseSvgPathSpec(region, sb.toString());
+ currentIndex += CUTOUT_MARKER.length();
+
+ /* prepare to parse the rest path */
+ resetStatus(sb);
+ } else if (specWithoutDp.startsWith(BIND_LEFT_CUTOUT_MARKER, currentIndex)) {
+ if (!mBindBottomCutout && !mBindRightCutout) {
+ mBindLeftCutout = true;
+ }
+ currentIndex += BIND_LEFT_CUTOUT_MARKER.length();
+ } else if (specWithoutDp.startsWith(BIND_RIGHT_CUTOUT_MARKER, currentIndex)) {
+ if (!mBindBottomCutout && !mBindLeftCutout) {
+ mBindRightCutout = true;
+ }
+ currentIndex += BIND_RIGHT_CUTOUT_MARKER.length();
+ } else {
+ currentIndex += 1;
+ }
+
+ lastIndex = currentIndex;
+ }
+
+ if (sb == null) {
+ parseSvgPathSpec(region, specWithoutDp);
+ } else {
+ sb.append(specWithoutDp, lastIndex, specWithoutDp.length());
+ parseSvgPathSpec(region, sb.toString());
+ }
+
+ region.recycle();
+ }
+
+ /**
+ * To parse specification string as the CutoutSpecification.
+ *
+ * @param originalSpec the specification string
+ * @return the CutoutSpecification instance
+ */
+ @VisibleForTesting(visibility = PACKAGE)
+ public CutoutSpecification parse(@NonNull String originalSpec) {
+ Objects.requireNonNull(originalSpec);
+
+ int dpIndex = originalSpec.lastIndexOf(DP_MARKER);
+ mInDp = (dpIndex != -1);
+ final String spec;
+ if (dpIndex != -1) {
+ spec = originalSpec.substring(0, dpIndex)
+ + originalSpec.substring(dpIndex + DP_MARKER.length());
+ } else {
+ spec = originalSpec;
+ }
+
+ parseSpecWithoutDp(spec);
+
+ mInsets = Insets.of(mSafeInsetLeft, mSafeInsetTop, mSafeInsetRight, mSafeInsetBottom);
+ return new CutoutSpecification(this);
+ }
+ }
+}
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index d433591f2b3c..31fc16188814 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -31,18 +31,12 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources;
import android.graphics.Insets;
-import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Region.Op;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
-import android.util.Log;
import android.util.Pair;
-import android.util.PathParser;
import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
@@ -63,10 +57,6 @@ import java.util.List;
public final class DisplayCutout {
private static final String TAG = "DisplayCutout";
- private static final String BOTTOM_MARKER = "@bottom";
- private static final String DP_MARKER = "@dp";
- private static final String RIGHT_MARKER = "@right";
- private static final String LEFT_MARKER = "@left";
/**
* Category for overlays that allow emulating a display cutout on devices that don't have
@@ -703,77 +693,16 @@ public final class DisplayCutout {
}
}
- Path p = null;
- Rect boundTop = null;
- Rect boundBottom = null;
- Rect safeInset = new Rect();
- String bottomSpec = null;
- if (!TextUtils.isEmpty(spec)) {
- spec = spec.trim();
- final float offsetX;
- if (spec.endsWith(RIGHT_MARKER)) {
- offsetX = displayWidth;
- spec = spec.substring(0, spec.length() - RIGHT_MARKER.length()).trim();
- } else if (spec.endsWith(LEFT_MARKER)) {
- offsetX = 0;
- spec = spec.substring(0, spec.length() - LEFT_MARKER.length()).trim();
- } else {
- offsetX = displayWidth / 2f;
- }
- final boolean inDp = spec.endsWith(DP_MARKER);
- if (inDp) {
- spec = spec.substring(0, spec.length() - DP_MARKER.length());
- }
-
- if (spec.contains(BOTTOM_MARKER)) {
- String[] splits = spec.split(BOTTOM_MARKER, 2);
- spec = splits[0].trim();
- bottomSpec = splits[1].trim();
- }
+ spec = spec.trim();
- final Matrix m = new Matrix();
- final Region r = Region.obtain();
- if (!spec.isEmpty()) {
- try {
- p = PathParser.createPathFromPathData(spec);
- } catch (Throwable e) {
- Log.wtf(TAG, "Could not inflate cutout: ", e);
- }
-
- if (p != null) {
- if (inDp) {
- m.postScale(density, density);
- }
- m.postTranslate(offsetX, 0);
- p.transform(m);
+ CutoutSpecification cutoutSpec = new CutoutSpecification.Parser(density,
+ displayWidth, displayHeight).parse(spec);
+ Rect safeInset = cutoutSpec.getSafeInset();
+ final Rect boundLeft = cutoutSpec.getLeftBound();
+ final Rect boundTop = cutoutSpec.getTopBound();
+ final Rect boundRight = cutoutSpec.getRightBound();
+ final Rect boundBottom = cutoutSpec.getBottomBound();
- boundTop = new Rect();
- toRectAndAddToRegion(p, r, boundTop);
- safeInset.top = boundTop.bottom;
- }
- }
-
- if (bottomSpec != null) {
- int bottomInset = 0;
- Path bottomPath = null;
- try {
- bottomPath = PathParser.createPathFromPathData(bottomSpec);
- } catch (Throwable e) {
- Log.wtf(TAG, "Could not inflate bottom cutout: ", e);
- }
-
- if (bottomPath != null) {
- // Keep top transform
- m.postTranslate(0, displayHeight);
- bottomPath.transform(m);
- p.addPath(bottomPath);
- boundBottom = new Rect();
- toRectAndAddToRegion(bottomPath, r, boundBottom);
- bottomInset = displayHeight - boundBottom.top;
- }
- safeInset.bottom = bottomInset;
- }
- }
if (!waterfallInsets.equals(Insets.NONE)) {
safeInset.set(
@@ -784,9 +713,9 @@ public final class DisplayCutout {
}
final DisplayCutout cutout = new DisplayCutout(
- safeInset, waterfallInsets, null /* boundLeft */, boundTop,
- null /* boundRight */, boundBottom, false /* copyArguments */);
- final Pair<Path, DisplayCutout> result = new Pair<>(p, cutout);
+ safeInset, waterfallInsets, boundLeft, boundTop,
+ boundRight, boundBottom, false /* copyArguments */);
+ final Pair<Path, DisplayCutout> result = new Pair<>(cutoutSpec.getPath(), cutout);
synchronized (CACHE_LOCK) {
sCachedSpec = spec;
sCachedDisplayWidth = displayWidth;
@@ -798,14 +727,6 @@ public final class DisplayCutout {
return result;
}
- private static void toRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) {
- final RectF rectF = new RectF();
- p.computeBounds(rectF, false /* unused */);
- rectF.round(inoutRect);
- inoutRegion.op(inoutRect, Op.UNION);
- }
-
-
private static Insets loadWaterfallInset(Resources res) {
return Insets.of(
res.getDimensionPixelSize(R.dimen.waterfall_display_left_edge_size),
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 4365d1f5194a..56683dd9a5d1 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -277,7 +277,7 @@ public final class WindowManagerImpl implements WindowManager {
.setStableInsets(Insets.of(stableInsets))
.setDisplayCutout(displayCutout.get()).build();
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- return null;
}
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 76e7e191d293..8959d6fb845e 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -360,7 +360,6 @@ cc_library_static {
"android_view_RenderNode.cpp",
"android_util_PathParser.cpp",
- "android/graphics/AnimatedImageDrawable.cpp",
"android/graphics/Bitmap.cpp",
"android/graphics/BitmapFactory.cpp",
"android/graphics/ByteBufferStreamAdaptor.cpp",
@@ -436,6 +435,7 @@ cc_library_static {
"android_view_TextureLayer.cpp",
"android_view_ThreadedRenderer.cpp",
+ "android/graphics/AnimatedImageDrawable.cpp",
"android/graphics/BitmapRegionDecoder.cpp",
"android/graphics/GIFMovie.cpp",
"android/graphics/Movie.cpp",
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d6c5a1379a58..5e895336d7f3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Skakel werkprofiel aan?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Jou werkprogramme, kennisgewings, data en ander werkprofielkenmerke sal aangeskakel word"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Skakel aan"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Program is nie beskikbaar nie"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nie op die oomblik beskikbaar nie."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Hierdie program is vir \'n ouer weergawe van Android gebou en sal dalk nie behoorlik werk nie. Probeer kyk vir opdaterings, of kontak die ontwikkelaar."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kyk vir opdatering"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Jy het nuwe boodskappe"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index e9409fbf92ed..b637a637c3fe 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"የስራ መገለጫ ይብራ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"የእርስዎ የስራ መተግበሪያዎች፣ ማሳወቂያዎች፣ ውሂብ እና ሌሎች የስራ መገለጫ ባህሪያት ይበራሉ"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"አብራ"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"መተግበሪያ አይገኝም"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> አሁን አይገኝም።"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ይህ መተግበሪያ ለቆየ የAndroid ስሪት ነው የተገነባው፣ እና በአግባቡ ላይሰራ ይችላል። ዝማኔዎች ካሉ ለመመልከት ይሞክሩ፣ ወይም ደግሞ ገንቢውን ያነጋግሩ።"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ዝማኔ ካለ አረጋግጥ"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"አዲስ መልዕክቶች አለዎት"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 23ffd7b6594a..002d61e0ff80 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -915,7 +915,7 @@
<string name="factorytest_no_action" msgid="339252838115675515">"‏لم يتم العثور على أي حزمة توفر إجراء FACTORY_TEST."</string>
<string name="factorytest_reboot" msgid="2050147445567257365">"إعادة تشغيل"</string>
<string name="js_dialog_title" msgid="7464775045615023241">"تعرض الصفحة في \"<xliff:g id="TITLE">%s</xliff:g>\":"</string>
- <string name="js_dialog_title_default" msgid="3769524569903332476">"جافا سكريبت"</string>
+ <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="7012587995876771246">"تأكيد الانتقال"</string>
<string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"مغادرة هذه الصفحة"</string>
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"البقاء في هذه الصفحة"</string>
@@ -1395,7 +1395,7 @@
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"وحدة التحكّم التسلسلية مفعّلة"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"الأداء متأثر. لإيقاف وحدة التحكّم، تحقّق من برنامج الإقلاع."</string>
- <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"‏السوائل والشوائب في منفذ USB"</string>
+ <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"‏السوائل أو الشوائب في منفذ USB"</string>
<string name="usb_contaminant_detected_message" msgid="7346100585390795743">"‏تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات."</string>
<string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"‏مسموح باستخدام منفذ USB"</string>
<string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"لم يَعُد الهاتف يكتشف سوائل أو شوائب."</string>
@@ -1981,6 +1981,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"تفعيل الملف الشخصي للعمل؟"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"سيتم تفعيل تطبيقات العمل التي تستخدمها والإشعارات والبيانات وغيرها من ميزات الملف الشخصي للعمل"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"تشغيل"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"التطبيق غير متاح"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> غير متاح الآن."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏تمّ إنشاء هذا التطبيق لإصدار قديم من Android وقد لا يعمل بشكل صحيح. جرِّب البحث عن تحديثات أو الاتصال بمطوّر البرامج."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"البحث عن تحديث"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"لديك رسائل جديدة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index a09c377d45b9..bdf8fcf18718 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"কৰ্মস্থানৰ প্ৰ\'ফাইল অন কৰিবনে?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"আপোনাৰ কৰ্মস্থানৰ এপসমূহ, জাননীসমূহ, ডেটা আৰু কৰ্মস্থানৰ প্ৰ\'ফাইলৰ অইন সুবিধাসমূহ অন কৰা হ\'ব"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"অন কৰক"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"এপ্‌টো উপলব্ধ নহয়"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"এই মুহূৰ্তত <xliff:g id="APP_NAME">%1$s</xliff:g> উপলব্ধ নহয়।"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"এই এপটো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে প্ৰস্তুত কৰা হৈছিল, আৰু ই বিচৰাধৰণে কাম নকৰিবও পাৰে। ইয়াৰ আপডে’ট আছে নেকি চাওক, বা বিকাশকৰ্তাৰ সৈতে যোগাযোগ কৰক।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডে’ট আছে নেকি চাওক"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"আপুনি নতুন বার্তা লাভ কৰিছে"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index b1209b100633..6f13024ada2e 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"İş profili aktiv edilsin?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"İş tətbiqləri, bildirişləri, data və digər iş profili funksiyaları aktiv ediləcək"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivləşdirin"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Tətbiq əlçatan deyil"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hazırda əlçatan deyil."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu tətbiq köhnə Android versiyası üçün hazırlanıb və düzgün işləməyə bilər. Güncəlləməni yoxlayın və ya developer ilə əlaqə saxlayın."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncəlləməni yoxlayın"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5600882ca16f..862495a6f9bf 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1885,6 +1885,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Da uključimo profil za Work?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Uključiće se poslovne aplikacije, obaveštenja, podaci i druge funkcije profila za Work"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova aplikacija je napravljena za stariju verziju Android-a, pa možda neće raditi ispravno. Potražite ažuriranja ili kontaktirajte programera."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Potraži ažuriranje"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index fb80e4b043b9..8a02da2f3794 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Уключыць працоўны профіль?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Будуць уключаны вашы рабочыя праграмы, апавяшчэнні, даныя і іншыя функцыі працоўнага профілю"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Уключыць"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Праграма недаступная"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" цяпер недаступная."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Гэта праграма была створана для больш старой версіі Android і можа не працаваць належным чынам. Праверце наяўнасць абнаўленняў або звярніцеся да распрацоўшчыка."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць на наяўнасць абнаўленняў"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"У вас ёсць новыя паведамленні"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 2892853f0923..f7830c738dcc 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Вкл. на служ. потр. профил?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Служебните ви приложения, известия и данни, както и другите функции на служебния потребителски профил ще бъдат включени"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Включване"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Приложението не е достъпно"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"В момента няма достъп до <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Това приложение бе създадено за по-стара версия на Android и може да не работи правилно. Опитайте да проверите за актуализации или се свържете с програмиста."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за актуализация"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови съобщения"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 4c95081cc15d..af50b3357cee 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1297,7 +1297,7 @@
<string name="no_permissions" msgid="5729199278862516390">"কোনো অনুমতির প্রয়োজন নেই"</string>
<string name="perm_costs_money" msgid="749054595022779685">"এর জন্য অর্থপ্রদান করতে হতে পারে"</string>
<string name="dlg_ok" msgid="5103447663504839312">"ঠিক আছে"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"এই ডিভাইসটি USB এর মাধ্যমে চার্জ করুন"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"এই ডিভাইসটি USB দিয়ে চার্জ করা হচ্ছে"</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"সংযুক্ত ডিভাইসটি USB এর মাধ্যমে চার্জ করা হচ্ছে"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB ফাইল ট্রান্সফার চালু করা হয়েছে"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB এর মাধ্যমে PTP চালু করা হয়েছে"</string>
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"কাজের প্রোফাইল চালু করবেন?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"আপনার কাজের অ্যাপ, বিজ্ঞপ্তি, ডেটা এবং কাজের প্রোফাইলের অন্যান্য বৈশিষ্ট্য চালু করা হবে"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"চালু করুন"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"অ্যাপ পাওয়া যাচ্ছে না"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"এই মুহূর্তে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপ পাওয়া যাচ্ছে না।"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"এই অ্যাপটি Android এর একটি পুরনো ভার্সনের জন্য তৈরি করা হয়েছিল, তাই এখানে সেটি ঠিকমতো কাজ নাও করতে পারে। আপডেট পাওয়া যাচ্ছে কিনা দেখুন বা ডেভেলপারের সাথে যোগাযোগ করুন।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডেট পাওয়া যাচ্ছে কিনা দেখুন"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"আপনার নতুন মেসেজ আছে"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index eaa212dccf2f..d436c5fbc87d 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1887,6 +1887,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Uključiti radni profil?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Uključit će se poslovne aplikacije, obavještenja, podaci i druge funkcije radnog profila"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova aplikacija je pravljena za stariju verziju Androida i možda neće ispravno raditi. Provjerite jesu li dostupna ažuriranja ili kontaktirajte programera."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri je li dostupno ažuriranje"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0b58caea91b8..f3b416cee191 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -182,11 +182,11 @@
<item quantity="one">Autoritat de certificació instal·lada</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Per un tercer desconegut"</string>
- <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Per l\'administrador del teu perfil professional"</string>
+ <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Per l\'administrador del teu perfil de treball"</string>
<string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Per <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
- <string name="work_profile_deleted" msgid="5891181538182009328">"S\'ha suprimit el perfil professional"</string>
- <string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta l\'aplicació d\'administració del perfil professional o està malmesa. Com a conseqüència, s\'han suprimit el teu perfil professional i les dades relacionades. Contacta amb l\'administrador per obtenir ajuda."</string>
- <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"El teu perfil professional ja no està disponible en aquest dispositiu"</string>
+ <string name="work_profile_deleted" msgid="5891181538182009328">"S\'ha suprimit el perfil de treball"</string>
+ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta l\'aplicació d\'administració del perfil de treball o està malmesa. Com a conseqüència, s\'han suprimit el teu perfil de treball i les dades relacionades. Contacta amb l\'administrador per obtenir ajuda."</string>
+ <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"El teu perfil de treball ja no està disponible en aquest dispositiu"</string>
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Has intentat introduir la contrasenya massa vegades"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrador ha cedit el dispositiu per a ús personal"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"El dispositiu està gestionat"</string>
@@ -280,7 +280,7 @@
<string name="safeMode" msgid="8974401416068943888">"Mode segur"</string>
<string name="android_system_label" msgid="5974767339591067210">"Sistema Android"</string>
<string name="user_owner_label" msgid="8628726904184471211">"Canvia al perfil personal"</string>
- <string name="managed_profile_label" msgid="7316778766973512382">"Canvia al perfil professional"</string>
+ <string name="managed_profile_label" msgid="7316778766973512382">"Canvia al perfil de treball"</string>
<string name="permgrouplab_contacts" msgid="4254143639307316920">"Contactes"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"accedir als contactes"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"Ubicació"</string>
@@ -1406,8 +1406,8 @@
<string name="deny" msgid="6632259981847676572">"Denega"</string>
<string name="permission_request_notification_title" msgid="1810025922441048273">"Permís sol·licitat"</string>
<string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"S\'ha sol·licitat permís\nper al compte <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
- <string name="forward_intent_to_owner" msgid="4620359037192871015">"Estàs utilitzant aquesta aplicació fora del perfil professional."</string>
- <string name="forward_intent_to_work" msgid="3620262405636021151">"Estàs utilitzant l\'aplicació al perfil professional."</string>
+ <string name="forward_intent_to_owner" msgid="4620359037192871015">"Estàs utilitzant aquesta aplicació fora del perfil de treball."</string>
+ <string name="forward_intent_to_work" msgid="3620262405636021151">"Estàs utilitzant l\'aplicació al perfil de treball."</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"Mètode d\'introducció de text"</string>
<string name="sync_binding_label" msgid="469249309424662147">"Sincronització"</string>
<string name="accessibility_binding_label" msgid="1974602776545801715">"Accessibilitat"</string>
@@ -1817,7 +1817,7 @@
<string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"La sol·licitud SS s\'ha canviat per una videotrucada"</string>
<string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"La sol·licitud SS s\'ha canviat per una sol·licitud USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="132040645206514450">"S\'ha canviat a una nova sol·licitud SS"</string>
- <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Perfil professional"</string>
+ <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Perfil de treball"</string>
<string name="notification_alerted_content_description" msgid="6139691253611265992">"S\'ha enviat una alerta"</string>
<string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Desplega"</string>
<string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Replega"</string>
@@ -1850,15 +1850,17 @@
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> no està disponible en aquests moments. Aquesta opció es gestiona a <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"Més informació"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Reactiva l\'aplicació"</string>
- <string name="work_mode_off_title" msgid="5503291976647976560">"Activar el perfil professional?"</string>
- <string name="work_mode_off_message" msgid="8417484421098563803">"S\'activaran les teves aplicacions de treball, les notificacions, les dades i altres funcions del perfil professional"</string>
+ <string name="work_mode_off_title" msgid="5503291976647976560">"Activar el perfil de treball?"</string>
+ <string name="work_mode_off_message" msgid="8417484421098563803">"S\'activaran les teves aplicacions de treball, les notificacions, les dades i altres funcions del perfil de treball"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activa"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"L\'aplicació no està disponible"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Ara mateix, <xliff:g id="APP_NAME">%1$s</xliff:g> no està disponible."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Aquesta aplicació es va crear per a una versió antiga d\'Android i pot ser que no funcioni correctament. Prova de cercar actualitzacions o contacta amb el desenvolupador."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca actualitzacions"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tens missatges nous"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Obre l\'aplicació d\'SMS per veure\'ls"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algunes funcions poden ser limitades"</string>
- <string name="profile_encrypted_detail" msgid="5279730442756849055">"Perfil professional bloquejat"</string>
+ <string name="profile_encrypted_detail" msgid="5279730442756849055">"Perfil de treball bloquejat"</string>
<string name="profile_encrypted_message" msgid="1128512616293157802">"Toca per desbloquejar el perfil"</string>
<string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"S\'ha connectat a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Toca per veure els fitxers"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 5874c2493041..754a02016f8b 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Zapnout pracovní profil?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Vaše pracovní aplikace, oznámení, data a ostatní funkce pracovního účtu budou zapnuty"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Zapnout"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> v tuto chvíli není k dispozici."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Tato aplikace byla vytvořena pro starší verzi systému Android a nemusí fungovat správně. Zkuste vyhledat aktualizace, případně kontaktujte vývojáře."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Zkontrolovat aktualizace"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové zprávy"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index eb7ad1b9e48f..733c7f0e76a1 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Skal arbejdsprofilen slås til?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Dine arbejdsapps, notifikationer, data og andre funktioner til din arbejdsprofil deaktiveres"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Slå til"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgængelig"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgængelig lige nu."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Denne app er lavet til en ældre version af Android og fungerer muligvis ikke korrekt. Prøv at søge efter opdateringer, eller kontakt udvikleren."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Søg efter opdatering"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye beskeder"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 6b01af1f3b08..9a4c606f76b3 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Arbeitsprofil aktivieren?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Deine geschäftlichen Apps, Benachrichtigungen, Daten und andere Funktionen des Arbeitsprofils werden aktiviert"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivieren"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"App ist nicht verfügbar"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist derzeit nicht verfügbar."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Diese App wurde für eine ältere Android-Version entwickelt und funktioniert möglicherweise nicht mehr richtig. Prüfe, ob Updates verfügbar sind oder kontaktiere den Entwickler."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Auf Updates prüfen"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du hast neue Nachrichten"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 61ca692aae16..30a8d61d7b22 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Ενεργοποίηση προφίλ εργασίας;"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Οι εφαρμογές, οι ειδοποιήσεις και τα δεδομένα εργασίας σας, καθώς και άλλες λειτουργίες του προφίλ εργασίας, θα ενεργοποιηθούν"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Ενεργοποίηση"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Η εφαρμογή δεν είναι διαθέσιμη"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν είναι διαθέσιμη αυτήν τη στιγμή."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Αυτή η εφαρμογή δημιουργήθηκε για παλαιότερη έκδοση του Android και μπορεί να μην λειτουργεί σωστά. Δοκιμάστε να ελέγξετε εάν υπάρχουν ενημερώσεις ή επικοινωνήστε με τον προγραμματιστή."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Έλεγχος για ενημέρωση"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Έχετε νέα μηνύματα"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 15a059f449f1..d15fc5a3c61e 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index f3ab25afdf1e..bec2e349ec67 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 15a059f449f1..d15fc5a3c61e 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 15a059f449f1..d15fc5a3c61e 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Turn on work profile?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Your work apps, notifications, data and other work profile features will be turned on"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Turn on"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 871e528c8e94..42ec9321019e 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‎‎‎Turn on work profile?‎‏‎‎‏‎"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎Your work apps, notifications, data, and other work profile features will be turned on‎‏‎‎‏‎"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎Turn on‎‏‎‎‏‎"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎App is not available‎‏‎‎‏‎"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is not available right now.‎‏‎‎‏‎"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎This app was built for an older version of Android and may not work properly. Try checking for updates, or contact the developer.‎‏‎‎‏‎"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎Check for update‎‏‎‎‏‎"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎You have new messages‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1cb9fde2956a..ac555d58a5e8 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"¿Activar el perfil de trabajo?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Se activaran las apps de trabajo, los datos, las notificaciones y otras funciones del perfil de trabajo"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta app se creó para una versión anterior de Android y es posible que no funcione correctamente. Busca actualizaciones o comunícate con el programador."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d8509a331453..190664b4fd54 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -802,7 +802,7 @@
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Introduce el código PIN para desbloquear."</string>
<string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"Código PIN incorrecto"</string>
<string name="keyguard_label_text" msgid="3841953694564168384">"Para desbloquear el teléfono, pulsa la tecla de menú y, a continuación, pulsa 0."</string>
- <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Número de emergencia"</string>
+ <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Llamada de emergencia"</string>
<string name="lockscreen_carrier_default" msgid="6192313772955399160">"Sin servicio"</string>
<string name="lockscreen_screen_locked" msgid="7364905540516041817">"Pantalla bloqueada"</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pulsa la tecla de menú para desbloquear el teléfono o realizar una llamada de emergencia."</string>
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"¿Activar el perfil de trabajo?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Tus aplicaciones, notificaciones, datos y otras funciones del perfil de trabajo se activarán"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"La aplicación no está disponible"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"En estos momentos, <xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta aplicación se ha diseñado para una versión anterior de Android y es posible que no funcione correctamente. Busca actualizaciones o ponte en contacto con el desarrollador."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualizaciones"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 2148c09f08ad..0c302ee6b5fa 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Kas lülitada tööprofiil sisse?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Teie töörakendused, märguanded, andmed ja muud tööprofiili funktsioonid lülitatakse sisse"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Lülita sisse"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Rakendus ei ole saadaval"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole praegu saadaval."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"See rakendus on loodud Androidi vanema versiooni jaoks ega pruugi õigesti töötada. Otsige värskendusi või võtke ühendust arendajaga."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Otsi värskendust"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Teile on uusi sõnumeid"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 07bde5ee0648..e7aedd557225 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -517,7 +517,7 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Argazki-bilduma aldatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"multimedia-edukien bildumako kokapena irakurri"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Multimedia-edukien bildumako kokapena irakurtzeko baimena ematen die aplikazioei."</string>
- <string name="biometric_dialog_default_title" msgid="5284880398508155088">"Egiaztatu zu zarela"</string>
+ <string name="biometric_dialog_default_title" msgid="5284880398508155088">"Egiaztatu zeu zarela"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrikoa ez dago erabilgarri"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Utzi da autentifikazioa"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ez da ezagutu"</string>
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Laneko profila aktibatu?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Laneko aplikazioak, jakinarazpenak, datuak eta laneko profileko bestelako eginbideak aktibatuko dira"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Aktibatu"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikazioa ez dago erabilgarri"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ez dago erabilgarri une honetan."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Aplikazioa Android-en bertsio zaharrago baterako sortu zenez, baliteke behar bezala ez funtzionatzea. Bilatu eguneratzerik baden, edo jarri garatzailearekin harremanetan."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Bilatu eguneratzeak"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Mezu berriak dituzu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d65357b73ba0..9d9a13c5d75c 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"نمایه کاری روشن شود؟"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"برنامه‌ها، اعلان‌ها، داده‌ها و سایر قابلیت‌های نمایه کاری شما روشن خواهد شد"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"روشن کردن"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"برنامه در دسترس نیست"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحال‌حاضر در دسترس نیست."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏این برنامه برای نسخه قدیمی‌تری از Android ساخته شده است و ممکن است درست کار نکند. وجود به‌روزرسانی را بررسی کنید یا با برنامه‌نویس تماس بگیرید."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"بررسی وجود به‌روزرسانی"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"پیام‌های جدیدی دارید"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 17b3d33b4cf8..35cc8b9a8cb8 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Otetaanko työprofiili käyttöön?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Työsovellukset, ‑ilmoitukset, ‑tiedot ja muut työprofiiliominaisuudet otetaan käyttöön"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Ota käyttöön"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Sovellus ei ole käytettävissä"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole nyt käytettävissä."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Tämä sovellus on suunniteltu vanhemmalle Android-versiolle eikä välttämättä toimi oikein. Kokeile tarkistaa päivitykset tai ottaa yhteyttä kehittäjään."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tarkista päivitykset"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Sinulle on uusia viestejä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 45b8613a1e6f..caec9fa7615e 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Activer le profil professionnel?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Vos applications professionnelles, vos notifications, vos données et les autres fonctionnalités de profil professionnel seront activées"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activer"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Cette application a été conçue pour une ancienne version d\'Android et pourrait ne pas fonctionner correctement. Essayez de vérifier les mises à jour ou communiquez avec son concepteur."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Vérifier la présence de mises à jour"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index c646aeb8d82d..601fe431a292 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Activer profil professionnel ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Vos applications professionnelles, notifications, données et d\'autres fonctionnalités de votre profil professionnel seront activées"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activer"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Application non disponible"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas disponible pour le moment."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Cette application a été conçue pour une ancienne version d\'Android et risque de ne pas fonctionner correctement. Recherchez des mises à jour ou contactez le développeur."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rechercher une mise à jour"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 2a2d7c4712b9..0aa627716191 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Activar o perfil de traballo?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Activaranse as túas aplicacións de traballo, as notificacións, os datos e outras funcións do perfil de traballo"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"A aplicación non está dispoñible"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> non está dispoñible neste momento."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta aplicación deseñouse para unha versión anterior de Android e quizais non funcione correctamente. Proba a buscar actualizacións ou contacta co programador."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tes mensaxes novas"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index aab09f751076..85bf30ed51f8 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"કાર્યાલયની પ્રોફાઇલ ચાલુ કરીએ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"તમારી કાર્યાલયની ઍપ, નોટિફિકેશન, ડેટા અને અન્ય કાર્યાલયની પ્રોફાઇલ સુવિધાઓ ચાલુ કરવામાં આવશે"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ચાલુ કરો"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ઍપ ઉપલબ્ધ નથી"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> હાલમાં ઉપલબ્ધ નથી."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"આ ઍપ Androidના જૂના વર્ઝન માટે બનાવવામાં આવ્યું હતું અને તે કદાચ તે યોગ્ય રીતે કાર્ય કરી શકશે નહીં. અપડેટ માટે તપાસવાનો પ્રયાસ કરો અથવા ડેવલપરનો સંપર્ક કરો."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"અપડેટ માટે તપાસો"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"તમારી પાસે નવા સંદેશા છે"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index e1bb060fbc76..19e154ef2046 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"वर्क प्रोफ़ाइल चालू करें?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"आपके काम से जुड़े ऐप्लिकेशन, सूचनाएं, डेटा और वर्क प्रोफ़ाइल से जुड़ी दूसरी सुविधाएं चालू हो जाएंगी"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"चालू करें"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ऐप्लिकेशन उपलब्ध नहीं है"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> इस समय उपलब्ध नहीं है."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"यह ऐप्लिकेशन Android के पुराने वर्शन के लिए बनाया गया था, इसलिए हो सकता है कि यह सही से काम न करे. देखें कि अपडेट मौजूद हैं या नहीं, या फिर डेवलपर से संपर्क करें."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"देखें कि अपडेट मौजूद है या नहीं"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"आपके पास नए संदेश हैं"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 383943429400..9a9357f188e2 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1885,6 +1885,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Želite uključiti radni profil?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Uključit će se vaše radne aplikacije, obavijesti, podaci i druge značajke radnog profila"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Uključi"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutačno nije dostupna."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova je aplikacija razvijena za stariju verziju Androida i možda neće funkcionirati pravilno. Potražite ažuriranja ili se obratite razvojnom programeru."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri ažuriranja"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index fcea1ec4975a..d4ac7e2b6a61 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Bekapcsolja a munkaprofilt?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"A munkahelyi alkalmazások, értesítések, adatok és a munkaprofilhoz tartozó egyéb funkciók be lesznek kapcsolva"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Bekapcsolás"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Az alkalmazás nem hozzáférhető"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg nem hozzáférhető."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ez az alkalmazás az Android egyik korábbi verziójához készült, így elképzelhető, hogy nem működik majd megfelelően ezen a rendszeren. Keressen frissítéseket, vagy vegye fel a kapcsolatot a fejlesztővel."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Frissítés keresése"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Új üzenetei érkeztek"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index cbd754f15e29..5cd8e8eeb8e5 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Միացնե՞լ աշխատանքային պրոֆիլը"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Ձեր աշխատանքային հավելվածները, ծանուցումները, տվյալները և աշխատանքային պրոֆիլի մյուս գործառույթները կմիանան"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Միացնել"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Հավելվածը հասանելի չէ"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն այս պահին հասանելի չէ։"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Այս հավելվածը ստեղծվել է Android-ի ավելի հին տարբերակի համար և կարող է պատշաճ չաշխատել: Ստուգեք թարմացումների առկայությունը կամ դիմեք մշակողին:"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Ստուգել նոր տարբերակի առկայությունը"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Դուք ունեք նոր հաղորդագրություններ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index f1a94ff0149e..3a1571df64bd 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Aktifkan profil kerja?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Aplikasi kerja, notifikasi, data, dan fitur profil kerja lainnya akan diaktifkan"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Aktifkan"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikasi tidak tersedia"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia saat ini."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Aplikasi ini dibuat untuk Android versi lama dan mungkin tidak berfungsi sebagaimana mestinya. Coba periksa apakah ada update, atau hubungi developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa apakah ada update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ada pesan baru"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index b4cb76d367b5..eddb21455101 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Kveikja á vinnusniði?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Kveikt verður á vinnuforritum, tilkynningum, gögnum og öðrum eiginleikum vinnusniðsins"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Kveikja"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Forrit er ekki tiltækt"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ekki tiltækt núna."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Þetta forrit var hannað fyrir eldri útgáfu af Android og ekki er víst að það virki eðlilega. Athugaðu hvort uppfærslur séu í boði eða hafðu samband við þróunaraðilann."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Leita að uppfærslu"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Þú ert með ný skilaboð"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 23a62a8a48f8..135a226e0cf5 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Attivare il profilo di lavoro?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Le tue app di lavoro, le notifiche, i dati e altri elementi del profilo di lavoro saranno attivati."</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Attiva"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"L\'app non è disponibile"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è al momento disponibile."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Questa app è stata realizzata per una versione precedente di Android e potrebbe non funzionare correttamente. Prova a verificare la disponibilità di aggiornamenti o contatta lo sviluppatore."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Verifica la presenza di aggiornamenti"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Hai nuovi messaggi"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 4319aa8644f0..65b738461e56 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"להפעיל את פרופיל העבודה?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"אפליקציות העבודה, התראות, נתונים ותכונות נוספות של פרופיל העבודה יופעלו"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"הפעל"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"האפליקציה לא זמינה"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא זמינה בשלב זה."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏האפליקציה הזו עוצבה לגרסה ישנה יותר של Android וייתכן שלא תפעל כראוי. ניתן לבדוק אם יש עדכונים או ליצור קשר עם המפתח."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"האם יש עדכון חדש?"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"יש לך הודעות חדשות"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 481af76de9a7..bda206442c6e 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"仕事用プロファイルの有効化"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"仕事用のアプリ、通知、データなど、仕事用プロファイルの機能が ON になります"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ON にする"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"アプリの利用不可"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"現在 <xliff:g id="APP_NAME">%1$s</xliff:g> はご利用になれません。"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"このアプリは以前のバージョンの Android 用に作成されており、正常に動作しない可能性があります。アップデートを確認するか、デベロッパーにお問い合わせください。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"アップデートを確認"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"新着メッセージがあります"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index c2c28e515593..c47b71048163 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"ჩაირთოს სამსახურის პროფილი?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"თქვენი სამსახურის აპები, შეტყობინებები, მონაცემები და სამსახურის პროფილის ყველა სხვა ფუნქცია ჩაირთვება"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ჩართვა"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"აპი მიუწვდომელია"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ამჟამად მიუწვდომელია."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ეს აპი Android-ის ძველი ვერსიისთვის შეიქმნა და შესაძლოა სათანადოდ არ მუშაობდეს. გადაამოწმეთ განახლებები ან დაუკავშირდით დეველოპერს."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"განახლების შემოწმება"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"თქვენ ახალი შეტყობინებები გაქვთ"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 7cb05129495d..241cf08bf594 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Жұмыс профилі қосылсын ба?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Жұмыс қолданбалары, хабарландырулар, деректер және басқа да жұмыс профильдерінің мүмкіндіктері қосылады"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Қосу"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Қолданба қолжетімді емес"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> қазір қолжетімді емес."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Қолданба Android жүйесінің ескі нұсқасына арналған және дұрыс жұмыс істемеуі мүмкін. Жаңартылған нұсқаны тексеріңіз немесе әзірлеушіге хабарласыңыз."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңартылған нұсқаны тексеру"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Сізде жаңа хабарлар бар"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index e0267d363721..483e236c13c7 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1855,6 +1855,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"បើក​កម្រង​ព័ត៌មាន​ការ​ងារ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"កម្មវិធី​ការងារ ការ​ជូនដំណឹង ទិន្នន័យ និង​មុខងារ​កម្រង​ព័ត៌មាន​ការងារ​ផ្សេង​ទៀត​របស់អ្នក​នឹង​ត្រូវ​បាន​បើក"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"បើក"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"មិនអាច​ប្រើ​កម្មវិធី​នេះបានទេ"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"មិនអាច​ប្រើ <xliff:g id="APP_NAME">%1$s</xliff:g> នៅពេល​នេះ​បានទេ​។"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"កម្មវិធី​នេះ​ត្រូវបាន​បង្កើត​ឡើង​សម្រាប់​កំណែ​ប្រព័ន្ធ​ប្រតិបត្តិការ Android ចាស់ ហើយ​វាអាច​ដំណើរការ​ខុសប្រក្រតី។ សូម​សាកល្បង​ពិនិត្យមើល​កំណែ​ថ្មី ឬ​ទាក់ទង​ទៅអ្នក​អភិវឌ្ឍន៍។"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"រក​មើល​កំណែ​ថ្មី"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"អ្នកមានសារថ្មី"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 4a2bc72d27d8..7133e89a8436 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ ಆನ್ ಮಾಡುವುದೇ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"ನಿಮ್ಮ ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು, ಅಧಿಸೂಚನೆಗಳು, ಡೇಟಾ ಮತ್ತು ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ನ ಇತರ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಆನ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ಆನ್‌ ಮಾಡಿ"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ಆ್ಯಪ್ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಇದೀಗ ಲಭ್ಯವಿಲ್ಲ."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು Android ನ ಹಳೆಯ ಆವೃತ್ತಿಗೆ ರಚಿಸಲಾಗಿದೆ ಮತ್ತು ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡದಿರಬಹುದು. ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಅಥವಾ ಡೆವಲಪರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ನೀವು ಹೊಸ ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿರುವಿರಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 0ac7a1447f7c..12c05baedbd7 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"직장 프로필을 사용 설정하시겠어요?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"업무용 앱, 알림, 데이터 및 기타 직장 프로필 기능이 사용 설정됩니다."</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"사용 설정"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"앱을 사용할 수 없습니다"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"현재 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 사용할 수 없습니다."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"이 앱은 Android 이전 버전에 맞게 개발되었기 때문에 제대로 작동하지 않을 수 있습니다. 업데이트를 확인하거나 개발자에게 문의하세요."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"업데이트 확인"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"새 메시지 있음"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 88e36ff0b533..ccbf845ea1e0 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -190,7 +190,7 @@
<string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Өтө көп жолу сырсөздү киргизүү аракети жасалды"</string>
<string name="device_ownership_relinquished" msgid="4080886992183195724">"Админ түзмөктөн жеке колдонуу үчүн баш тартты"</string>
<string name="network_logging_notification_title" msgid="554983187553845004">"Түзмөктү ишкана башкарат"</string>
- <string name="network_logging_notification_text" msgid="1327373071132562512">"Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын көрүү үчүн таптап коюңуз."</string>
+ <string name="network_logging_notification_text" msgid="1327373071132562512">"Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын билгиңиз келсе, таптап коюңуз."</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"Түзмөгүңүз тазаланат"</string>
<string name="factory_reset_message" msgid="2657049595153992213">"Түзмөктү башкаруучу колдонмо жараксыз. Түзмөгүңүз азыр тазаланат.\n\nСуроолоруңуз болсо, ишканаңыздын администраторуна кайрылыңыз."</string>
<string name="printing_disabled_by" msgid="3517499806528864633">"Басып чыгаруу <xliff:g id="OWNER_APP">%s</xliff:g> тарабынан өчүрүлдү."</string>
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Жумуш профили күйгүзүлсүнбү?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Жумуш колдонмолоруңуз, эскертмелериңиз, дайын-даректериңиз жана жумуш профилинин башка функциялары күйгүзүлөт."</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Күйгүзүү"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Колдонмо учурда жеткиликсиз"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> учурда жеткиликсиз"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Бул колдонмо Android\'дин эски версиясы үчүн иштеп чыгарылган, андыктан туура эмес иштеши мүмкүн. Жаңыртууларды издеп көрүңүз же иштеп чыгуучуга кайрылыңыз."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңыртууну издөө"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Сизге жаңы билдирүүлөр келди"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 63b87ac54e3e..e8bda532f31b 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"ເປີດໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກບໍ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"ແອັບວຽກຂອງທ່ານ, ການແຈ້ງເຕືອນ, ຂໍ້ມູນ ແລະ ຄຸນສົມບັດໂປຣໄຟລ໌ວຽກຈະຖືກເປີດໃຊ້"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ເປີດ​"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ແອັບບໍ່ສາມາດໃຊ້ໄດ້"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ສາມາດໃຊ້ໄດ້ໃນຕອນນີ້."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ແອັບນີ້ຖືກສ້າງຂຶ້ນສຳລັບ Android ເວີຊັນທີ່ເກົ່າກວ່າ ແລະ ອາດເຮັດວຽກໄດ້ບໍ່ປົກກະຕິ. ໃຫ້ລອງກວດສອບເບິ່ງອັບເດດ ຫຼື ຕິດຕໍ່ຜູ້ພັດທະນາ."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ກວດເບິ່ງອັບເດດ"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ທ່ານມີຂໍ້ຄວາມໃໝ່"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index b8d848e91929..ad90ab3412e2 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Įjungti darbo profilį?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Darbo programos, pranešimai, duomenys ir kitos darbo profilio funkcijos bus išjungtos"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Įjungti"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Programa nepasiekiama."</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ šiuo metu nepasiekiama."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ši programa sukurta naudoti senesnės versijos sistemoje „Android“ ir gali tinkamai neveikti. Pabandykite patikrinti, ar yra naujinių, arba susisiekite su kūrėju."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tikrinti, ar yra naujinių"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Turite naujų pranešimų"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f168bb4121c8..6ffe39af644f 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1885,6 +1885,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Vai ieslēgt darba profilu?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Tiks ieslēgtas jūsu darba lietotnes, paziņojumi, dati un citas darba profila funkcijas."</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Ieslēgt"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Lietotne nav pieejama"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pašlaik nav pieejama."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Šī lietotne tika izstrādāta vecākai Android versijai un var nedarboties pareizi. Meklējiet atjauninājumus vai sazinieties ar izstrādātāju."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Meklēt atjauninājumu"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Jums ir jaunas īsziņas."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index f94d191fba28..bb1d9c6ca23e 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1855,6 +1855,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Да се вклучи работниот профил?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Вашите работни апликации, известувања, податоци и други функции на работниот профил ќе бидат вклучени"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Вклучи"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Апликацијата не е достапна"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> не е достапна во моментов."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Апликацијава е создадена за постара верзија на Android и може да не функционира правилно. Проверете за ажурирања или контактирајте со програмерот."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за ажурирање"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови пораки"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 1efd21132ebc..31edd8cc324d 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"ഔദ്യോഗിക പ്രൊഫൈൽ ഓണാക്കണോ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ, അറിയിപ്പുകൾ, ഡാറ്റ, മറ്റ് ഔദ്യോഗിക പ്രൊഫൈൽ ഫീച്ചറുകൾ എന്നിവ ഓണാക്കും"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ഓണാക്കുക"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ആപ്പ് ലഭ്യമല്ല"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഇപ്പോൾ ലഭ്യമല്ല."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ഈ ആപ്പ് Android-ന്റെ പഴയ പതിപ്പിനായി നിർമ്മിച്ചിരിക്കുന്നതിനാൽ ശരിയായി പ്രവർത്തിച്ചേക്കില്ല. അപ്‌ഡേറ്റിനായി പരിശോധിക്കുക, അല്ലെങ്കിൽ ഡെവലപ്പറുമായി ബന്ധപ്പെടുക."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"അപ്‌ഡേറ്റിനായി പരിശോധിക്കുക"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"നിങ്ങൾക്ക് പുതിയ സന്ദേശങ്ങൾ ഉണ്ട്"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index cc031754b2b7..eb61a46d876a 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Ажлын профайлыг асаах уу?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Таны ажлын апп, мэдэгдэл, өгөгдөл болон бусад ажлын профайлын онцлогийг асаана"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Асаах"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Апп боломжгүй байна"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> яг одоо боломжгүй байна."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Энэ аппыг Андройдын хуучин хувилбарт зориулсан бөгөөд буруу ажиллаж болзошгүй. Шинэчлэлтийг шалгаж эсвэл хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шинэчлэлтийг шалгах"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ зурвасууд байна"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index cd9b6fc5ee5a..0a8f4afa79ac 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"कार्य प्रोफाइल चालू ठेवायची?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"तुमची कार्य अ‍ॅप्स, सूचना, डेटा आणि अन्य कार्य प्रोफाइल वैशिष्ट्ये चालू केली जातील"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"चालू करा"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ॲप उपलब्ध नाही"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> आता उपलब्ध नाही."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"हे अ‍ॅप Android च्या जुन्या आवृत्ती साठी तयार करण्यात आले होते आणि योग्यरितीने कार्य करू शकणार नाही. अपडेट आहेत का ते तपासून पाहा, किंवा डेव्हलपरशी संपर्क साधण्याचा प्रयत्न करा."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अपडेट आहे का ते तपासा"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"आपल्याकडे नवीन मेसेज आहेत"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 0a4073519b59..59c7d65afb32 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Hidupkan profil kerja?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Apl kerja, pemberitahuan, data dan ciri profil kerja anda yang lain akan dihidupkan"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Hidupkan"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Apl tidak tersedia"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia sekarang."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Apl ini dibina untuk versi Android yang lebih lama dan mungkin tidak berfungsi dengan betul. Cuba semak kemas kini atau hubungi pembangun."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Semak kemas kini"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Anda mempunyai mesej baharu"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 9e048411b5c7..b3efcb180d90 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"အလုပ်ပရိုဖိုင် ဖွင့်လိုသလား။"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"သင်၏ အလုပ်အက်ပ်၊ အကြောင်းကြားချက်၊ ဒေတာနှင့် အခြားအလုပ်ပရိုဖိုင် ဝန်ဆောင်မှုများကို ဖွင့်လိုက်ပါမည်"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ဖွင့်ပါ"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"အက်ပ်ကို မရနိုင်ပါ"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ယခု မရနိုင်ပါ။"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ဤအက်ပ်ကို Android ဗားရှင်းဟောင်းအတွက် ပြုလုပ်ထားခြင်းဖြစ်ပြီး ပုံမှန်အလုပ်မလုပ်နိုင်ပါ။ အပ်ဒိတ်များအတွက် ရှာကြည့်ပါ သို့မဟုတ် ဆော့ဖ်ဝဲအင်ဂျင်နီယာကို ဆက်သွယ်ပါ။"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"အပ်ဒိတ်စစ်ရန်"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"သင့်ထံတွင် စာအသစ်များရောက်နေသည်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 45ab3e552c17..5a3a5886eb24 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Vil du slå på jobbprofilen?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Jobbappene dine samt varsler, data og andre funksjoner i jobbprofilen din blir slått på"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Slå på"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgjengelig"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgjengelig for øyeblikket."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Denne appen er utviklet for en eldre versjon av Android og fungerer kanskje ikke som den skal. Prøv å se etter oppdateringer, eller kontakt utvikleren."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Se etter oppdateringer"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye meldinger"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 11033a740aa1..e95866ba1a7c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1859,6 +1859,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"कार्य प्रोफाइल सक्रिय गर्ने?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"तपाईंका कार्यसम्बन्धी अनुप्रयोग, सूचना, डेटा र कार्य प्रोफाइलका अन्य सुविधाहरू सक्रिय गरिने छन्‌"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"सक्रिय गर्नुहोस्"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"अनुप्रयोग उपलब्ध छैन"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> अहिले उपलब्ध छैन।"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"यो अनुप्रयोग Android को पुरानो संस्करणका लागि बनाइएको हुनाले यसले सही ढङ्गले काम नगर्न सक्छ। अद्यावधिकहरू उपलब्ध छन् वा छैनन् भनी जाँच गरी हेर्नुहोस् वा यसको विकासकर्तालाई सम्पर्क गर्नुहोस्।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अद्यावधिक उपलब्ध छ वा छैन भनी जाँच गर्नुहोस्"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"तपाईंलाई नयाँ सन्देश आएको छ"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 13f6725c82b7..e524c1b71d85 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Werkprofiel inschakelen?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Je werk-apps, meldingen, gegevens en andere functies van je werkprofiel worden uitgeschakeld"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Inschakelen"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Deze app is ontwikkeld voor een oudere versie van Android en werkt mogelijk niet op de juiste manier. Controleer op updates of neem contact op met de ontwikkelaar."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Controleren op update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Je hebt nieuwe berichten"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 4424af7dcab0..246b4d9b86f5 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ଚାଲୁ କରିବେ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"ଆପଣଙ୍କର କାର୍ଯ୍ୟକାରୀ ଆପ୍‌, ବିଜ୍ଞପ୍ତି, ଡାଟା ଓ ଅନ୍ୟ ୱର୍କ ପ୍ରୋଫାଇଲ୍‌ଗୁଡ଼ିକ ଚାଲୁ ହୋଇଯିବ"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ଅନ୍ କରନ୍ତୁ"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବର୍ତ୍ତମାନ ଉପଲବ୍ଧ ନାହିଁ।"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ଏହି ଆପ୍‌କୁ Androidର ପୁରୁଣା ଭର୍ସନ୍ ପାଇଁ ନିର୍ମାଣ କରାଯାଇଥିଲା ଏବଂ ଠିକ୍ ଭାବେ କାମ କରିନପାରେ। ଏହାପାଇଁ ଅପଡେଟ୍‌ ଅଛି କି ନାହିଁ ଯାଞ୍ଚ କରନ୍ତୁ କିମ୍ବା ଡେଭେଲପର୍‌ଙ୍କ ସହିତ ସମ୍ପର୍କ କରନ୍ତୁ।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ଅପଡେଟ୍‌ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ଆପଣଙ୍କ ପାଖରେ ନୂଆ ମେସେଜ୍‍ ରହିଛି"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 8c87581f9a61..3d688325fc6e 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"ਕੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਚਾਲੂ ਕਰਨੀ ਹੈ?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"ਤੁਹਾਡੀਆਂ ਕਾਰਜ-ਸਥਾਨ ਐਪਾਂ, ਸੂਚਨਾਵਾਂ, ਡਾਟਾ ਅਤੇ ਹੋਰ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਚਾਲੂ ਕੀਤੀਆਂ ਜਾਣਗੀਆਂ"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ਚਾਲੂ ਕਰੋ"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ਇਹ ਐਪ Android ਦੇ ਕਿਸੇ ਵਧੇਰੇ ਪੁਰਾਣੇ ਵਰਜਨ ਲਈ ਬਣਾਈ ਗਈ ਸੀ ਅਤੇ ਸ਼ਾਇਦ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ। ਅੱਪਡੇਟਾਂ ਲਈ ਜਾਂਚ ਕਰੋ ਜਾਂ ਵਿਕਾਸਕਾਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ਅੱਪਡੇਟ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ਤੁਹਾਨੂੰ ਨਵੇਂ ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਹੋਏ ਹਨ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 5efbfbe36830..2fb9ac20ba23 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Włączyć profil służbowy?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacje do pracy, powiadomienia, dane i inne funkcje profilu do pracy zostaną włączone"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Włącz"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacja jest niedostępna"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest obecnie niedostępna."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ta aplikacja jest na starszą wersję Androida i może nie działać prawidłowo. Sprawdź dostępność aktualizacji lub skontaktuj się z programistą."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sprawdź dostępność aktualizacji"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Masz nowe wiadomości"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index db4844163ba9..1ae0c360bf11 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -509,8 +509,8 @@
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permite que o app execute métodos para adicionar e excluir modelos de impressão digital para uso."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"usar hardware de impressão digital"</string>
<string name="permdesc_useFingerprint" msgid="412463055059323742">"Permite que o app use hardware de impressão digital para autenticação."</string>
- <string name="permlab_audioWrite" msgid="8501705294265669405">"modificar sua coleção de músicas"</string>
- <string name="permdesc_audioWrite" msgid="8057399517013412431">"Permite que o app modifique sua coleção de músicas."</string>
+ <string name="permlab_audioWrite" msgid="8501705294265669405">"modificar sua biblioteca de música"</string>
+ <string name="permdesc_audioWrite" msgid="8057399517013412431">"Permite que o app modifique sua biblioteca de música."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"modificar sua coleção de vídeos"</string>
<string name="permdesc_videoWrite" msgid="6124731210613317051">"Permite que o app modifique sua coleção de vídeos."</string>
<string name="permlab_imagesWrite" msgid="1774555086984985578">"modificar sua coleção de fotos"</string>
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Ativar o perfil de trabalho?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Seus apps, notificações, dados e outros recursos do perfil de trabalho serão ativados"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Este app foi criado para uma versão mais antiga do Android e pode não funcionar corretamente. Tente verificar se há atualizações ou entre em contato com o desenvolvedor."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 04296fe10378..c381709f61db 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Ativar o perfil de trabalho?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"As aplicações de trabalho, as notificações, os dados e outras funcionalidades do perfil de trabalho serão desativados"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"A app não está disponível"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"De momento, a app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta aplicação foi concebida para uma versão mais antiga do Android e pode não funcionar corretamente. Experimente verificar se existem atualizações ou contacte o programador."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Verificar se existem atualizações"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tem mensagens novas"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index db4844163ba9..1ae0c360bf11 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -509,8 +509,8 @@
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permite que o app execute métodos para adicionar e excluir modelos de impressão digital para uso."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"usar hardware de impressão digital"</string>
<string name="permdesc_useFingerprint" msgid="412463055059323742">"Permite que o app use hardware de impressão digital para autenticação."</string>
- <string name="permlab_audioWrite" msgid="8501705294265669405">"modificar sua coleção de músicas"</string>
- <string name="permdesc_audioWrite" msgid="8057399517013412431">"Permite que o app modifique sua coleção de músicas."</string>
+ <string name="permlab_audioWrite" msgid="8501705294265669405">"modificar sua biblioteca de música"</string>
+ <string name="permdesc_audioWrite" msgid="8057399517013412431">"Permite que o app modifique sua biblioteca de música."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"modificar sua coleção de vídeos"</string>
<string name="permdesc_videoWrite" msgid="6124731210613317051">"Permite que o app modifique sua coleção de vídeos."</string>
<string name="permlab_imagesWrite" msgid="1774555086984985578">"modificar sua coleção de fotos"</string>
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Ativar o perfil de trabalho?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Seus apps, notificações, dados e outros recursos do perfil de trabalho serão ativados"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Ativar"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Este app foi criado para uma versão mais antiga do Android e pode não funcionar corretamente. Tente verificar se há atualizações ou entre em contato com o desenvolvedor."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 030e76a2f6cf..7c5b63efdb02 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1885,6 +1885,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Activați profilul de serviciu?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Se vor activa aplicațiile dvs. de serviciu, notificările, datele și alte funcții ale profilului de serviciu"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Activați"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplicația nu este disponibilă"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu este disponibilă momentan."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Această aplicație a fost creată pentru o versiune Android mai veche și este posibil să nu funcționeze corect. Încercați să căutați actualizări sau contactați dezvoltatorul."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Căutați actualizări"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Aveți mesaje noi"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 94029f51c0c0..fa2c9f5697ab 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1177,7 +1177,7 @@
<string name="whichEditApplication" msgid="6191568491456092812">"Редактировать с помощью приложения:"</string>
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"Редактировать с помощью приложения \"%1$s\""</string>
<string name="whichEditApplicationLabel" msgid="1463288652070140285">"Изменить"</string>
- <string name="whichSendApplication" msgid="4143847974460792029">"Отправка данных"</string>
+ <string name="whichSendApplication" msgid="4143847974460792029">"Поделиться"</string>
<string name="whichSendApplicationNamed" msgid="4470386782693183461">"Поделиться через %1$s"</string>
<string name="whichSendApplicationLabel" msgid="7467813004769188515">"Поделиться"</string>
<string name="whichSendToApplication" msgid="77101541959464018">"Выберите приложение"</string>
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Включить рабочий профиль?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Будут включены корпоративные приложения, уведомления, данные и другие функции рабочего профиля."</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Включить"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Приложение недоступно"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" сейчас недоступно."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Это приложение было создано для более ранней версии Android и может работать со сбоями. Проверьте наличие обновлений или свяжитесь с разработчиком."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверить обновления"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Новые сообщения"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 73cf01890108..dbe1f2203c84 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1855,6 +1855,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"කාර්යාල පැතිකඩ ක්‍රියාත්මක කරන්නද?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"ඔබගේ වැඩ යෙදුම්, දැනුම්දීම්, දත්ත සහ වෙනත් කාර්යාල පැතිකඩ විශේෂාංග ක්‍රියාත්මක කරනු ඇත"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ක්‍රියාත්මක කරන්න"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"යෙදුම ලබා ගත නොහැකිය"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> මේ දැන් ලබා ගත නොහැකිය."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"මෙම යෙදුම Android හි පැරණි අනුවාදයක් සඳහා තනා ඇති අතර නිසියාකාරව ක්‍රියා නොකරනු ඇත. යාවත්කාලීන සඳහා පරික්ෂා කිරීම උත්සාහ කරන්න, නැතහොත් සංවර්ධක අමතන්න."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"යාවත්කාලීන සඳහා පරික්ෂා කරන්න"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ඔබට නව පණිවිඩ තිබේ"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index b86fc4696a01..5483efdb4d51 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Zapnúť pracovný profil?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Pracovné aplikácie, upozornenia, dáta a ďalšie funkcie pracovného profilu sa zapnú"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Zapnúť"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Táto aplikácia bola zostavená pre staršiu verziu Androidu a nemusí správne fungovať. Skúste skontrolovať dostupnosť aktualizácií alebo kontaktovať vývojára."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Skontrolovať dostupnosť aktualizácie"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové správy."</string>
@@ -1944,7 +1946,7 @@
<string name="app_category_social" msgid="2278269325488344054">"Sociálne siete a komunikácia"</string>
<string name="app_category_news" msgid="1172762719574964544">"Noviny a časopisy"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapy a navigácia"</string>
- <string name="app_category_productivity" msgid="1844422703029557883">"Produktivita"</string>
+ <string name="app_category_productivity" msgid="1844422703029557883">"Kancelárske"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Úložisko zariadenia"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Ladenie cez USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hodina"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index bc2bc3acb7db..fed39e8343f4 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Želite vklopiti delovni profil?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Vklopili boste svoje delovne aplikacije, obvestila, podatke in druge funkcije delovnega profila"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Vklop"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija ni na voljo"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno ni na voljo."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ta aplikacija je bila zasnovana za starejšo različico Androida in morda ne bo delovala pravilno. Preverite, ali so na voljo posodobitve, ali pa se obrnite na razvijalca."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Preveri, ali je na voljo posodobitev"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nova sporočila."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index a35328879f29..ec61fb966b5e 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Të aktivizohet profili i punës?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Aplikacionet e punës, njoftimet, të dhënat e tua dhe funksionet e tjera të profilit të punës do të aktivizohen"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivizo"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacioni nuk ofrohet"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk ofrohet për momentin."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ky aplikacion është ndërtuar për një version më të vjetër të Android dhe mund të mos funksionojë mirë. Provo të kontrollosh për përditësime ose kontakto me zhvilluesin."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kontrollo për përditësim"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ke mesazhe të reja"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 8ee644ad2e4f..e1c4e1822e5b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1885,6 +1885,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Да укључимо профил за Work?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Укључиће се пословне апликације, обавештења, подаци и друге функције профила за Work"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Укључи"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Апликација није доступна"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> тренутно није доступна."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ова апликација је направљена за старију верзију Android-а, па можда неће радити исправно. Потражите ажурирања или контактирајте програмера."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Потражи ажурирање"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нове поруке"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 577933e6a296..0737b22c4aea 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Vill du aktivera jobbprofilen?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Jobbappar, aviseringar, data och andra funktioner i jobbprofilen aktiveras"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Aktivera"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Appen är inte tillgänglig"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> är inte tillgängligt just nu."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Appen har utvecklats för en äldre version av Android och kanske inte fungerar som den ska. Testa att söka efter uppdateringar eller kontakta utvecklaren."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sök efter uppdateringar"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nya meddelanden"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index a6ee3667b3c1..3c6b0fad22c8 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Ungependa kuwasha wasifu wa kazini?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Hatua hii itawasha data, arifa, programu za kazini, arifa na vipengele vingine vya wasifu wa kazini"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Washa"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Programu haipatikani"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> haipatikani hivi sasa."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Programu hii iliundwa kwa ajili ya toleo la zamani la Android na huenda isifanye kazi vizuri. Jaribu kuangalia masasisho au uwasiliane na msanidi programu."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Angalia masasisho"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Una ujumbe mpya"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index a56465fcd8ac..e80f37becd91 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"பணிச் சுயவிவரத்தை ஆன் செய்யவா?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"பணி ஆப்ஸ், அறிவிப்புகள், தரவு மற்றும் பிற பணிச் சுயவிவர அம்சங்கள் ஆன் செய்யப்படும்"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"இயக்கு"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"இந்த ஆப்ஸ் இப்போது கிடைப்பதில்லை"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் இப்போது கிடைப்பதில்லை."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"இந்த ஆப்ஸ் Android இன் பழைய பதிப்புக்காக உருவாக்கப்பட்டதால், சரியாக வேலை செய்யாமல் போகலாம். புதுப்பிப்புகள் ஏதேனும் உள்ளதா எனப் பார்க்கவும் அல்லது டெவெலப்பரைத் தொடர்புகொள்ளவும்."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"புதுப்பிப்பு உள்ளதா எனப் பார்"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"புதிய செய்திகள் வந்துள்ளன"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 7a0aece84500..81d4b4fd0220 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"కార్యాలయ ప్రొఫైల్‌ని ఆన్ చేయాలా?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"మీ కార్యాలయ యాప్‌లు, నోటిఫికేషన్‌లు, డేటా మరియు ఇతర కార్యాలయ ప్రొఫైల్ ఫీచర్‌లు ఆన్ చేయబడతాయి"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"ఆన్ చేయి"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"యాప్ అందుబాటులో లేదు"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రస్తుతం అందుబాటులో లేదు."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్‌డేట్‌ల కోసం తనిఖీ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్‌ని సంప్రదించండి."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం తనిఖీ చేయండి"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త సందేశాలు ఉన్నాయి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 98f2d8880b8a..46530ca33912 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"เปิดโปรไฟล์งานไหม"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"ระบบจะเปิดแอปงาน การแจ้งเตือน ข้อมูล และฟีเจอร์อื่นๆ ในโปรไฟล์งาน"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"เปิด"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"แอปไม่พร้อมใช้งาน"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่พร้อมใช้งานในขณะนี้"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"แอปนี้สร้างขึ้นเพื่อ Android เวอร์ชันเก่าและอาจทำงานผิดปกติ โปรดลองตรวจหาการอัปเดตหรือติดต่อนักพัฒนาซอฟต์แวร์"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ตรวจสอบอัปเดต"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"คุณมีข้อความใหม่"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c38a6d54cdbd..b9f1f293475b 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"I-on ang profile sa trabaho?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Mao-on ang iyong mga app sa trabaho, notification, data, at iba pang feature sa profile sa trabaho"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"I-on"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Hindi available ang app"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Hindi available sa ngayon ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ang app na ito ay ginawa para sa mas lumang bersyon ng Android at maaaring hindi gumana nang maayos. Subukang tingnan kung may mga update, o makipag-ugnayan sa developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tingnan kung may update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Mayroon kang mga bagong mensahe"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 5e0930947afb..81fb07933f0c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"İş profili açılsın mı?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"İş uygulamalarınız, bildirimleriniz, verileriniz ve diğer iş profili özellikleriniz açılacak"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Aç"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Uygulama kullanılamıyor"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması şu anda kullanılamıyor."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu uygulama Android\'in daha eski bir sürümü için oluşturuldu ve düzgün çalışmayabilir. Güncellemeleri kontrol etmeyi deneyin veya geliştiriciyle iletişime geçin."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncellemeleri denetle"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 1096f97e3c98..c71ea74ccaad 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1917,6 +1917,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Увімкнути робочий профіль?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Додатки, сповіщення, дані й інші функції робочого профілю буде ввімкнено"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Увімкнути"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Додаток недоступний"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> зараз недоступний."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Цей додаток створений для старішої версії Android і може працювати неналежним чином. Спробуйте знайти оновлення або зв’яжіться з розробником."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шукати оновлення"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"У вас є нові повідомлення"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 4c331916bb57..8a0425bdcd34 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"دفتری پروفائل آن کریں؟"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"آپ کی دفتری ایپس، اطلاعات، ڈیٹا اور دفتری پروفائل کی دیگر خصوصیات آن کر دی جائیں گی"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"آن کریں"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"ایپ دستیاب نہیں ہے"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ابھی دستیاب نہیں ہے۔"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏یہ ایپ Android کے پرانے ورژن کے لئے بنائی گئی ہے اور ہو سکتا ہے صحیح طور پر کام نہ کرے۔ اپ ڈیٹس چیک کر کے آزمائیں یا ڈیولپر سے رابطہ کریں۔"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"اپ ڈیٹ چیک کریں"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"آپ کے پاس نئے پیغامات ہیں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 23873b5f2b4f..b5c31c2f50dd 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Ishchi profil yoqilsinmi?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Ishchi ilovalar, bildirishnomalar, ma’lumotlar va boshqa ishchi profil imkoniyatlari yoqiladi"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Yoqish"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Ilova ishlamayapti"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"Ayni vaqtda <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi ishlamayapti."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu ilova eskiroq Android versiyalariga chiqarilgan va xato ishlashi mumkin. Yangilanishlarini tekshiring yoki dasturchi bilan bog‘laning."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Yangilanish borligini tekshirish"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Sizga yangi SMS keldi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 1ed30d7db57e..970d41ff9203 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Bạn muốn bật hồ sơ công việc?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Ứng dụng công việc, thông báo, dữ liệu và các tính năng khác của hồ sơ công việc sẽ được bật"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Bật"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Ứng dụng này không dùng được"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện không dùng được."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ứng dụng này được xây dựng cho một phiên bản Android cũ hơn và có thể hoạt động không bình thường. Hãy thử kiểm tra các bản cập nhật hoặc liên hệ với nhà phát triển."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kiểm tra bản cập nhật"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Bạn có tin nhắn mới"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 7671063821d0..c9bba5902788 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"要开启工作资料吗?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"您的工作应用、通知、数据及其他工作资料功能将会开启"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"开启"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"应用无法使用"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g>目前无法使用。"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"此应用专为旧版 Android 打造,因此可能无法正常运行。请尝试检查更新或与开发者联系。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"检查更新"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"您有新消息"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 89bea07ae1a7..fc652e3b59e5 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"要開啟工作設定檔嗎?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"系統將開啟您的工作應用程式、通知、資料和其他工作設定檔功能"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"開啟"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"無法使用應用程式"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"目前無法使用「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"此應用程式專為舊版 Android 打造,因此可能無法正常運作。請嘗試檢查更新,或與開發人員聯絡。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"您有新的訊息"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c95ae37602a0..75d05a29f2c9 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"要開啟工作資料夾嗎?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"系統將開啟你的辦公應用程式、通知、資料和其他工作資料夾功能"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"開啟"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"應用程式無法使用"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」目前無法使用。"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"這個應用程式是專為舊版 Android 所打造,因此可能無法正常運作。請嘗試檢查更新,或是與開發人員聯絡。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"你有新訊息"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 0cd669bb07a7..0d2abc0c4aa7 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1853,6 +1853,8 @@
<string name="work_mode_off_title" msgid="5503291976647976560">"Vula iphrofayela yomsebenzi?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Izinhlelo zakho zokusebenza zomsebenzi, izaziso, idatha, nezinye izici zephrofayela yomsebenzi kuzovulwa"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"Vula"</string>
+ <string name="app_blocked_title" msgid="7353262160455028160">"Uhlelo lokusebenza alutholakali"</string>
+ <string name="app_blocked_message" msgid="542972921087873023">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayitholakali khona manje."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Lolu hlelo lokusebenza belakhelwe inguqulo endala ye-Android futhi kungenzeka lungasebenzi kahle. Zama ukuhlolela izibuyekezo, noma uxhumane nonjiniyela."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Hlola izibuyekezo"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Unemilayezo emisha"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index b22e1867f257..c66261bb6630 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2056,6 +2056,9 @@
<attr name="name" />
</declare-styleable>
<declare-styleable name="AndroidManifestQueriesIntent" parent="AndroidManifestQueries" />
+ <declare-styleable name="AndroidManifestQueriesProvider" parent="AndroidManifestQueries" >
+ <attr name="authorities" />
+ </declare-styleable>
<!-- The <code>static-library</code> tag declares that this apk is providing itself
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 9f15fafe2bf1..e04d3de622d8 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -52,9 +52,14 @@ android_test {
"android.test.base",
"android.test.mock",
"framework-atb-backward-compatibility",
+ "framework-all",
+ "icing-java-proto-lite",
+ "ext",
+ "framework-res",
],
platform_apis: true,
+ sdk_version: "core_platform",
test_suites: ["device-tests"],
certificate: "platform",
diff --git a/core/tests/coretests/src/android/view/CutoutSpecificationTest.java b/core/tests/coretests/src/android/view/CutoutSpecificationTest.java
new file mode 100644
index 000000000000..1f831bb2f9a8
--- /dev/null
+++ b/core/tests/coretests/src/android/view/CutoutSpecificationTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2020 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.view;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.graphics.Rect;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class CutoutSpecificationTest {
+ private static final String WITHOUT_BIND_CUTOUT_SPECIFICATION = "M 0,0\n"
+ + "h 48\n"
+ + "v 48\n"
+ + "h -48\n"
+ + "z\n"
+ + "@left\n"
+ + "@center_vertical\n"
+ + "M 0,0\n"
+ + "h 48\n"
+ + "v 48\n"
+ + "h -48\n"
+ + "z\n"
+ + "@left\n"
+ + "@center_vertical\n"
+ + "M 0,0\n"
+ + "h -48\n"
+ + "v 48\n"
+ + "h 48\n"
+ + "z\n"
+ + "@right\n"
+ + "@dp";
+ private static final String WITH_BIND_CUTOUT_SPECIFICATION = "M 0,0\n"
+ + "h 48\n"
+ + "v 48\n"
+ + "h -48\n"
+ + "z\n"
+ + "@left\n"
+ + "@center_vertical\n"
+ + "M 0,0\n"
+ + "h 48\n"
+ + "v 48\n"
+ + "h -48\n"
+ + "z\n"
+ + "@left\n"
+ + "@bind_left_cutout\n"
+ + "@center_vertical\n"
+ + "M 0,0\n"
+ + "h -48\n"
+ + "v 48\n"
+ + "h 48\n"
+ + "z\n"
+ + "@right\n"
+ + "@bind_right_cutout\n"
+ + "@dp";
+ private static final String CORNER_CUTOUT_SPECIFICATION = "M 0,0\n"
+ + "h 1\n"
+ + "v 1\n"
+ + "h -1\n"
+ + "z\n"
+ + "@left\n"
+ + "@cutout\n"
+ + "M 0, 0\n"
+ + "h -2\n"
+ + "v 2\n"
+ + "h 2\n"
+ + "z\n"
+ + "@right\n"
+ + "@bind_right_cutout\n"
+ + "@cutout\n"
+ + "M 0, 200\n"
+ + "h 3\n"
+ + "v -3\n"
+ + "h -3\n"
+ + "z\n"
+ + "@left\n"
+ + "@bind_left_cutout\n"
+ + "@bottom\n"
+ + "M 0, 0\n"
+ + "h -4\n"
+ + "v -4\n"
+ + "h 4\n"
+ + "z\n"
+ + "@right\n"
+ + "@dp";
+
+ private CutoutSpecification.Parser mParser;
+
+ /**
+ * Setup the necessary member field used by test methods.
+ */
+ @Before
+ public void setUp() {
+ mParser = new CutoutSpecification.Parser(3.5f, 1080, 1920);
+ }
+
+ @Test
+ public void parse_nullString_shouldTriggerException() {
+ assertThrows(NullPointerException.class, () -> mParser.parse(null));
+ }
+
+ @Test
+ public void parse_emptyString_pathShouldBeNull() {
+ CutoutSpecification cutoutSpecification = mParser.parse("");
+ assertThat(cutoutSpecification.getPath()).isNull();
+ }
+
+ @Test
+ public void parse_withoutBindMarker_shouldHaveNoLeftBound() {
+ CutoutSpecification cutoutSpecification = mParser.parse(WITHOUT_BIND_CUTOUT_SPECIFICATION);
+ assertThat(cutoutSpecification.getLeftBound()).isNull();
+ }
+
+ @Test
+ public void parse_withoutBindMarker_shouldHaveNoRightBound() {
+ CutoutSpecification cutoutSpecification = mParser.parse(WITHOUT_BIND_CUTOUT_SPECIFICATION);
+ assertThat(cutoutSpecification.getRightBound()).isNull();
+ }
+
+ @Test
+ public void parse_withBindMarker_shouldHaveLeftBound() {
+ CutoutSpecification cutoutSpecification = mParser.parse(WITH_BIND_CUTOUT_SPECIFICATION);
+ assertThat(cutoutSpecification.getLeftBound()).isEqualTo(new Rect(0, 960, 168, 1128));
+ }
+
+ @Test
+ public void parse_withBindMarker_shouldHaveRightBound() {
+ CutoutSpecification cutoutSpecification = mParser.parse(WITH_BIND_CUTOUT_SPECIFICATION);
+ assertThat(cutoutSpecification.getRightBound()).isEqualTo(new Rect(912, 960, 1080, 1128));
+ }
+
+ @Test
+ public void parse_tallCutout_shouldBeDone() {
+ CutoutSpecification cutoutSpecification = mParser.parse("M 0,0\n"
+ + "L -48, 0\n"
+ + "L -44.3940446283, 36.0595537175\n"
+ + "C -43.5582133885, 44.4178661152 -39.6, 48.0 -31.2, 48.0\n"
+ + "L 31.2, 48.0\n"
+ + "C 39.6, 48.0 43.5582133885, 44.4178661152 44.3940446283, 36.0595537175\n"
+ + "L 48, 0\n"
+ + "Z\n"
+ + "@dp");
+
+ assertThat(cutoutSpecification.getTopBound().height()).isEqualTo(168);
+ }
+
+ @Test
+ public void parse_wideCutout_shouldBeDone() {
+ CutoutSpecification cutoutSpecification = mParser.parse("M 0,0\n"
+ + "L -72, 0\n"
+ + "L -69.9940446283, 20.0595537175\n"
+ + "C -69.1582133885, 28.4178661152 -65.2, 32.0 -56.8, 32.0\n"
+ + "L 56.8, 32.0\n"
+ + "C 65.2, 32.0 69.1582133885, 28.4178661152 69.9940446283, 20.0595537175\n"
+ + "L 72, 0\n"
+ + "Z\n"
+ + "@dp");
+
+ assertThat(cutoutSpecification.getTopBound().width()).isEqualTo(504);
+ }
+
+ @Test
+ public void parse_narrowCutout_shouldBeDone() {
+ CutoutSpecification cutoutSpecification = mParser.parse("M 0,0\n"
+ + "L -24, 0\n"
+ + "L -21.9940446283, 20.0595537175\n"
+ + "C -21.1582133885, 28.4178661152 -17.2, 32.0 -8.8, 32.0\n"
+ + "L 8.8, 32.0\n"
+ + "C 17.2, 32.0 21.1582133885, 28.4178661152 21.9940446283, 20.0595537175\n"
+ + "L 24, 0\n"
+ + "Z\n"
+ + "@dp");
+
+ assertThat(cutoutSpecification.getTopBound().width()).isEqualTo(168);
+ }
+
+ @Test
+ public void parse_doubleCutout_shouldBeDone() {
+ CutoutSpecification cutoutSpecification = mParser.parse("M 0,0\n"
+ + "L -72, 0\n"
+ + "L -69.9940446283, 20.0595537175\n"
+ + "C -69.1582133885, 28.4178661152 -65.2, 32.0 -56.8, 32.0\n"
+ + "L 56.8, 32.0\n"
+ + "C 65.2, 32.0 69.1582133885, 28.4178661152 69.9940446283, 20.0595537175\n"
+ + "L 72, 0\n"
+ + "Z\n"
+ + "@bottom\n"
+ + "M 0,0\n"
+ + "L -72, 0\n"
+ + "L -69.9940446283, -20.0595537175\n"
+ + "C -69.1582133885, -28.4178661152 -65.2, -32.0 -56.8, -32.0\n"
+ + "L 56.8, -32.0\n"
+ + "C 65.2, -32.0 69.1582133885, -28.4178661152 69.9940446283, -20"
+ + ".0595537175\n"
+ + "L 72, 0\n"
+ + "Z\n"
+ + "@dp");
+
+ assertThat(cutoutSpecification.getTopBound().height()).isEqualTo(112);
+ }
+
+ @Test
+ public void parse_cornerCutout_shouldBeDone() {
+ CutoutSpecification cutoutSpecification = mParser.parse("M 0,0\n"
+ + "L -48, 0\n"
+ + "C -48,48 -48,48 0,48\n"
+ + "Z\n"
+ + "@dp\n"
+ + "@right");
+
+ assertThat(cutoutSpecification.getTopBound().height()).isEqualTo(168);
+ }
+
+ @Test
+ public void parse_holeCutout_shouldBeDone() {
+ CutoutSpecification cutoutSpecification = mParser.parse("M 20.0,20.0\n"
+ + "h 136\n"
+ + "v 136\n"
+ + "h -136\n"
+ + "Z\n"
+ + "@left");
+
+ assertThat(cutoutSpecification.getSafeInset()).isEqualTo(new Rect(0, 156, 0, 0));
+ }
+
+ @Test
+ public void getSafeInset_shortEdgeIsTopBottom_shouldMatchExpectedInset() {
+ CutoutSpecification cutoutSpecification =
+ new CutoutSpecification.Parser(2f, 200, 400)
+ .parse(CORNER_CUTOUT_SPECIFICATION);
+
+ assertThat(cutoutSpecification.getSafeInset())
+ .isEqualTo(new Rect(0, 4, 0, 8));
+ }
+
+ @Test
+ public void getSafeInset_shortEdgeIsLeftRight_shouldMatchExpectedInset() {
+ CutoutSpecification cutoutSpecification =
+ new CutoutSpecification.Parser(2f, 400, 200)
+ .parse(CORNER_CUTOUT_SPECIFICATION);
+
+ assertThat(cutoutSpecification.getSafeInset())
+ .isEqualTo(new Rect(6, 0, 8, 0));
+ }
+}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 301d1afc6c13..debb38b2c1b0 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -171,7 +171,6 @@ cc_defaults {
"renderthread/RenderTask.cpp",
"renderthread/TimeLord.cpp",
"hwui/AnimatedImageDrawable.cpp",
- "hwui/AnimatedImageThread.cpp",
"hwui/Bitmap.cpp",
"hwui/Canvas.cpp",
"hwui/ImageDecoder.cpp",
@@ -213,6 +212,7 @@ cc_defaults {
android: {
srcs: [
+ "hwui/AnimatedImageThread.cpp",
"pipeline/skia/ATraceMemoryDump.cpp",
"pipeline/skia/GLFunctorDrawable.cpp",
"pipeline/skia/LayerDrawable.cpp",
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index 4544beae5df8..638de850a6c5 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -15,7 +15,9 @@
*/
#include "AnimatedImageDrawable.h"
+#ifdef __ANDROID__ // Layoutlib does not support AnimatedImageThread
#include "AnimatedImageThread.h"
+#endif
#include "utils/TraceUtils.h"
@@ -160,8 +162,10 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
} else if (starting) {
// The image has animated, and now is being reset. Queue up the first
// frame, but keep showing the current frame until the first is ready.
+#ifdef __ANDROID__ // Layoutlib does not support AnimatedImageThread
auto& thread = uirenderer::AnimatedImageThread::getInstance();
mNextSnapshot = thread.reset(sk_ref_sp(this));
+#endif
}
bool finalFrame = false;
@@ -187,8 +191,10 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
}
if (mRunning && !mNextSnapshot.valid()) {
+#ifdef __ANDROID__ // Layoutlib does not support AnimatedImageThread
auto& thread = uirenderer::AnimatedImageThread::getInstance();
mNextSnapshot = thread.decodeNextFrame(sk_ref_sp(this));
+#endif
}
if (!drawDirectly) {
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 767b67b7e885..d2379757f226 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -1457,6 +1457,9 @@ public class ExifInterface {
private int mRw2JpgFromRawOffset;
private boolean mIsSupportedFile;
private boolean mModified;
+ // XMP data can be contained as either part of the EXIF data (tag number 700), or as a
+ // separate data marker (a separate MARKER_APP1).
+ private boolean mXmpIsFromSeparateMarker;
// Pattern to check non zero timestamp
private static final Pattern sNonZeroTimePattern = Pattern.compile(".*[1-9].*");
@@ -2837,10 +2840,12 @@ public class ExifInterface {
final long offset = start + IDENTIFIER_XMP_APP1.length;
final byte[] value = Arrays.copyOfRange(bytes,
IDENTIFIER_XMP_APP1.length, bytes.length);
-
+ // TODO: check if ignoring separate XMP data when tag 700 already exists is
+ // valid.
if (getAttribute(TAG_XMP) == null) {
mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, new ExifAttribute(
IFD_FORMAT_BYTE, value.length, offset, value));
+ mXmpIsFromSeparateMarker = true;
}
}
break;
@@ -3445,11 +3450,24 @@ public class ExifInterface {
}
dataOutputStream.writeByte(MARKER_SOI);
+ // Remove XMP data if it is from a separate marker (IDENTIFIER_XMP_APP1, not
+ // IDENTIFIER_EXIF_APP1)
+ // Will re-add it later after the rest of the file is written
+ ExifAttribute xmpAttribute = null;
+ if (getAttribute(TAG_XMP) != null && mXmpIsFromSeparateMarker) {
+ xmpAttribute = (ExifAttribute) mAttributes[IFD_TYPE_PRIMARY].remove(TAG_XMP);
+ }
+
// Write EXIF APP1 segment
dataOutputStream.writeByte(MARKER);
dataOutputStream.writeByte(MARKER_APP1);
writeExifSegment(dataOutputStream);
+ // Re-add previously removed XMP data.
+ if (xmpAttribute != null) {
+ mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, xmpAttribute);
+ }
+
byte[] bytes = new byte[4096];
while (true) {
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index b1f930d0f2cc..2c1fdab9da01 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -247,13 +247,23 @@ public class MediaRouter2Manager {
Objects.requireNonNull(packageName, "packageName must not be null");
Objects.requireNonNull(route, "route must not be null");
+ boolean transferred = false;
+ //TODO: instead of release all controllers, add an API to specify controllers that
+ // should be released (or is the system controller).
for (RoutingController controller : getRoutingControllers(packageName)) {
- if (controller.getSessionInfo().getTransferrableRoutes().contains(route.getId())) {
+ if (!transferred && controller.getSessionInfo().getTransferrableRoutes()
+ .contains(route.getId())) {
controller.transferToRoute(route);
- return;
+ transferred = true;
+ } else if (!controller.getSessionInfo().isSystemSession()) {
+ controller.release();
}
}
+ if (transferred) {
+ return;
+ }
+
Client client;
synchronized (sLock) {
client = mClient;
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 870c1b4a3558..486c0c25a737 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -266,8 +266,12 @@ public final class MediaSession {
* playback after the session has been stopped. If your app is started in
* this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via
* the pending intent.
+ * <p>
+ * The pending intent is recommended to be explicit to follow the security recommendation of
+ * {@link PendingIntent#getActivity}.
*
* @param mbr The {@link PendingIntent} to send the media button event to.
+ * @see PendingIntent#getActivity
*/
public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 53a23b89f943..0ec739fecaa7 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -30,6 +30,7 @@ import android.view.IWindowManager;
import android.view.LayoutInflater;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.dagger.qualifiers.Background;
@@ -191,6 +192,12 @@ public class DependencyProvider {
return new AlwaysOnDisplayPolicy(context);
}
+ /***/
+ @Provides
+ public NotificationMessagingUtil provideNotificationMessagingUtil(Context context) {
+ return new NotificationMessagingUtil(context);
+ }
+
/** */
@Provides
public ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 7b541991088c..f068d9c10e86 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -40,6 +40,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.Notifica
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
+import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -68,7 +69,9 @@ import dagger.Provides;
NotificationsModule.class,
PeopleHubModule.class,
},
- subcomponents = {StatusBarComponent.class, NotificationRowComponent.class})
+ subcomponents = {StatusBarComponent.class,
+ NotificationRowComponent.class,
+ ExpandableNotificationRowComponent.class})
public abstract class SystemUIModule {
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 41c1b7b5fae8..006d40ddbac5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -69,6 +69,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotificationGuts;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
@@ -153,6 +154,7 @@ public final class NotificationEntry extends ListEntry {
private NotificationEntry parent; // our parent (if we're in a group)
private ExpandableNotificationRow row; // the outer expanded view
+ private ExpandableNotificationRowController mRowController;
private int mCachedContrastColor = COLOR_INVALID;
private int mCachedContrastColorIsFor = COLOR_INVALID;
@@ -424,6 +426,14 @@ public final class NotificationEntry extends ListEntry {
this.row = row;
}
+ public ExpandableNotificationRowController getRowController() {
+ return mRowController;
+ }
+
+ public void setRowController(ExpandableNotificationRowController controller) {
+ mRowController = controller;
+ }
+
@Nullable
public List<NotificationEntry> getChildren() {
if (row == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index ecf62db4680b..e8a62e48e75e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification.collection.inflation;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
-import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
import android.annotation.Nullable;
@@ -40,19 +39,19 @@ import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder;
import com.android.systemui.statusbar.notification.row.RowContentBindParams;
import com.android.systemui.statusbar.notification.row.RowContentBindStage;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
+import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.Objects;
@@ -67,35 +66,28 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
private static final String TAG = "NotificationViewManager";
- private final NotificationGroupManager mGroupManager;
- private final NotificationGutsManager mGutsManager;
private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private final Context mContext;
private final NotifBindPipeline mNotifBindPipeline;
private final RowContentBindStage mRowContentBindStage;
private final NotificationMessagingUtil mMessagingUtil;
- private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
- this::logNotificationExpansion;
private final NotificationRemoteInputManager mNotificationRemoteInputManager;
private final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
- private final boolean mAllowLongPress;
- private final KeyguardBypassController mKeyguardBypassController;
- private final StatusBarStateController mStatusBarStateController;
private NotificationPresenter mPresenter;
private NotificationListContainer mListContainer;
- private HeadsUpManager mHeadsUpManager;
private NotificationRowContentBinder.InflationCallback mInflationCallback;
- private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
private BindRowCallback mBindRowCallback;
private NotificationClicker mNotificationClicker;
private final Provider<RowInflaterTask> mRowInflaterTaskProvider;
- private final NotificationLogger mNotificationLogger;
+ private final ExpandableNotificationRowComponent.Builder
+ mExpandableNotificationRowComponentBuilder;
@Inject
public NotificationRowBinderImpl(
Context context,
+ NotificationMessagingUtil notificationMessagingUtil,
NotificationRemoteInputManager notificationRemoteInputManager,
NotificationLockscreenUserManager notificationLockscreenUserManager,
NotifBindPipeline notifBindPipeline,
@@ -107,21 +99,16 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
NotificationGutsManager notificationGutsManager,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
Provider<RowInflaterTask> rowInflaterTaskProvider,
- NotificationLogger logger) {
+ ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder) {
mContext = context;
mNotifBindPipeline = notifBindPipeline;
mRowContentBindStage = rowContentBindStage;
- mMessagingUtil = new NotificationMessagingUtil(context);
+ mMessagingUtil = notificationMessagingUtil;
mNotificationRemoteInputManager = notificationRemoteInputManager;
mNotificationLockscreenUserManager = notificationLockscreenUserManager;
- mAllowLongPress = allowLongPress;
- mKeyguardBypassController = keyguardBypassController;
- mStatusBarStateController = statusBarStateController;
- mGroupManager = notificationGroupManager;
- mGutsManager = notificationGutsManager;
mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
mRowInflaterTaskProvider = rowInflaterTaskProvider;
- mNotificationLogger = logger;
+ mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder;
}
/**
@@ -129,13 +116,10 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
*/
public void setUpWithPresenter(NotificationPresenter presenter,
NotificationListContainer listContainer,
- HeadsUpManager headsUpManager,
BindRowCallback bindRowCallback) {
mPresenter = presenter;
mListContainer = listContainer;
- mHeadsUpManager = headsUpManager;
mBindRowCallback = bindRowCallback;
- mOnAppOpsClickListener = mGutsManager::openGuts;
}
public void setInflationCallback(NotificationRowContentBinder.InflationCallback callback) {
@@ -150,9 +134,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
* Inflates the views for the given entry (possibly asynchronously).
*/
@Override
- public void inflateViews(
- NotificationEntry entry,
- Runnable onDismissRunnable)
+ public void inflateViews(NotificationEntry entry, Runnable onDismissRunnable)
throws InflationException {
ViewGroup parent = mListContainer.getViewParentForNotification(entry);
PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
@@ -163,12 +145,26 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
entry.updateIcons(mContext, sbn);
entry.reset();
updateNotification(entry, pmUser, sbn, entry.getRow());
- entry.getRow().setOnDismissRunnable(onDismissRunnable);
+ entry.getRowController().setOnDismissRunnable(onDismissRunnable);
} else {
entry.createIcons(mContext, sbn);
mRowInflaterTaskProvider.get().inflate(mContext, parent, entry,
row -> {
- bindRow(entry, pmUser, sbn, row, onDismissRunnable);
+ // Setup the controller for the view.
+ ExpandableNotificationRowComponent component =
+ mExpandableNotificationRowComponentBuilder
+ .expandableNotificationRow(row)
+ .notificationEntry(entry)
+ .onDismissRunnable(onDismissRunnable)
+ .inflationCallback(mInflationCallback)
+ .rowContentBindStage(mRowContentBindStage)
+ .onExpandClickListener(mPresenter)
+ .build();
+ ExpandableNotificationRowController rowController =
+ component.getExpandableNotificationRowController();
+ rowController.init();
+ entry.setRowController(rowController);
+ bindRow(entry, pmUser, sbn, row);
updateNotification(entry, pmUser, sbn, row);
});
}
@@ -176,55 +172,12 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
//TODO: This method associates a row with an entry, but eventually needs to not do that
private void bindRow(NotificationEntry entry, PackageManager pmUser,
- StatusBarNotification sbn, ExpandableNotificationRow row,
- Runnable onDismissRunnable) {
- // Get the app name.
- // Note that Notification.Builder#bindHeaderAppName has similar logic
- // but since this field is used in the guts, it must be accurate.
- // Therefore we will only show the application label, or, failing that, the
- // package name. No substitutions.
- final String pkg = sbn.getPackageName();
- String appname = pkg;
- try {
- final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS);
- if (info != null) {
- appname = String.valueOf(pmUser.getApplicationLabel(info));
- }
- } catch (PackageManager.NameNotFoundException e) {
- // Do nothing
- }
-
- row.initialize(
- appname,
- sbn.getKey(),
- mExpansionLogger,
- mKeyguardBypassController,
- mGroupManager,
- mHeadsUpManager,
- mRowContentBindStage,
- mPresenter);
-
- // TODO: Either move these into ExpandableNotificationRow#initialize or out of row entirely
- row.setStatusBarStateController(mStatusBarStateController);
- row.setAppOpsOnClickListener(mOnAppOpsClickListener);
- if (mAllowLongPress) {
- row.setLongPressListener(mGutsManager::openGuts);
- }
+ StatusBarNotification sbn, ExpandableNotificationRow row) {
mListContainer.bindRow(row);
mNotificationRemoteInputManager.bindRow(row);
-
- row.setOnDismissRunnable(onDismissRunnable);
- row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
- if (ENABLE_REMOTE_INPUT) {
- row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
- }
-
entry.setRow(row);
row.setEntry(entry);
mNotifBindPipeline.manageRow(entry, row);
-
mBindRowCallback.onBindRow(entry, pmUser, sbn, row);
}
@@ -307,10 +260,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
Objects.requireNonNull(mNotificationClicker).register(row, sbn);
}
- private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
- mNotificationLogger.onExpansionChanged(key, userAction, expanded);
- }
-
/** Callback for when a row is bound to an entry. */
public interface BindRowCallback {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 254b64ffcd90..3e0bcbb796bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -90,7 +90,6 @@ class NotificationsControllerImpl @Inject constructor(
notificationRowBinder.setUpWithPresenter(
presenter,
listContainer,
- headsUpManager,
bindRowCallback)
if (featureFlags.isNewNotifPipelineEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 50a20374fee5..3eac229af3f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -33,16 +33,14 @@ import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
-import com.android.systemui.Dependency;
+import com.android.systemui.Gefingerpoken;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
-import com.android.systemui.statusbar.phone.DoubleTapHelper;
/**
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationShelf}
@@ -94,14 +92,12 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
= new PathInterpolator(0, 0, 0.5f, 1);
private int mTintedRippleColor;
- protected int mNormalRippleColor;
- private final AccessibilityManager mAccessibilityManager;
- private final DoubleTapHelper mDoubleTapHelper;
+ private int mNormalRippleColor;
+ private Gefingerpoken mTouchHandler;
private boolean mDimmed;
- protected int mBgTint = NO_COLOR;
- private float mBgAlpha = 1f;
+ int mBgTint = NO_COLOR;
/**
* Flag to indicate that the notification has been touched once and the second touch will
@@ -116,7 +112,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private Interpolator mCurrentAppearInterpolator;
private Interpolator mCurrentAlphaInterpolator;
- protected NotificationBackgroundView mBackgroundNormal;
+ NotificationBackgroundView mBackgroundNormal;
private NotificationBackgroundView mBackgroundDimmed;
private ObjectAnimator mBackgroundAnimator;
private RectF mAppearAnimationRect = new RectF();
@@ -130,7 +126,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private boolean mLastInSection;
private boolean mFirstInSection;
private boolean mIsBelowSpeedBump;
- private final FalsingManager mFalsingManager;
private float mNormalBackgroundVisibilityAmount;
private float mDimmedBackgroundFadeInAmount = -1;
@@ -154,38 +149,25 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
*/
private boolean mNeedsDimming;
private int mDimmedAlpha;
- private boolean mBlockNextTouch;
private boolean mIsHeadsUpAnimation;
private int mHeadsUpAddStartLocation;
private float mHeadsUpLocation;
private boolean mIsAppearing;
private boolean mDismissed;
private boolean mRefocusOnDismiss;
+ private OnDimmedListener mOnDimmedListener;
+ private AccessibilityManager mAccessibilityManager;
public ActivatableNotificationView(Context context, AttributeSet attrs) {
super(context, attrs);
mSlowOutFastInInterpolator = new PathInterpolator(0.8f, 0.0f, 0.6f, 1.0f);
mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
- mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller.
setClipChildren(false);
setClipToPadding(false);
updateColors();
- mAccessibilityManager = AccessibilityManager.getInstance(mContext);
-
- mDoubleTapHelper = new DoubleTapHelper(this, (active) -> {
- if (active) {
- makeActive();
- } else {
- makeInactive(true /* animate */);
- }
- }, super::performClick, this::handleSlideBack, mFalsingManager::onNotificationDoubleTap);
initDimens();
}
- public FalsingManager getFalsingManager() {
- return mFalsingManager;
- }
-
private void updateColors() {
mNormalColor = mContext.getColor(R.color.notification_material_background_color);
mTintedRippleColor = mContext.getColor(
@@ -236,32 +218,15 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim);
}
- private final Runnable mTapTimeoutRunnable = new Runnable() {
- @Override
- public void run() {
- makeInactive(true /* animate */);
- }
- };
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (mNeedsDimming && ev.getActionMasked() == MotionEvent.ACTION_DOWN
- && disallowSingleClick(ev) && !isTouchExplorationEnabled()) {
- if (!mActivated) {
- return true;
- } else if (!mDoubleTapHelper.isWithinDoubleTapSlop(ev)) {
- mBlockNextTouch = true;
- makeInactive(true /* animate */);
- return true;
- }
+ if (mTouchHandler != null && mTouchHandler.onInterceptTouchEvent(ev)) {
+ return true;
}
return super.onInterceptTouchEvent(ev);
}
- private boolean isTouchExplorationEnabled() {
- return mAccessibilityManager.isTouchExplorationEnabled();
- }
-
protected boolean disallowSingleClick(MotionEvent ev) {
return false;
}
@@ -270,25 +235,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
return false;
}
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- boolean result;
- if (mBlockNextTouch) {
- mBlockNextTouch = false;
- return false;
- }
- if (mNeedsDimming && !isTouchExplorationEnabled() && isInteractive()) {
- boolean wasActivated = mActivated;
- result = handleTouchEventDimmed(event);
- if (wasActivated && result && event.getAction() == MotionEvent.ACTION_UP) {
- removeCallbacks(mTapTimeoutRunnable);
- }
- } else {
- result = super.onTouchEvent(event);
- }
- return result;
- }
-
/**
* @return whether this view is interactive and can be double tapped
*/
@@ -313,28 +259,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
}
- public void setRippleAllowed(boolean allowed) {
+ void setRippleAllowed(boolean allowed) {
mBackgroundNormal.setPressedAllowed(allowed);
}
- private boolean handleTouchEventDimmed(MotionEvent event) {
- if (mNeedsDimming && !mDimmed) {
- // We're actually dimmed, but our content isn't dimmable, let's ensure we have a ripple
- super.onTouchEvent(event);
- }
- return mDoubleTapHelper.onTouchEvent(event, getActualHeight());
- }
-
- @Override
- public boolean performClick() {
- if (!mNeedsDimming || isTouchExplorationEnabled()) {
- return super.performClick();
- }
- return false;
- }
-
- private void makeActive() {
- mFalsingManager.onNotificationActive();
+ void makeActive() {
startActivateAnimation(false /* reverse */);
mActivated = true;
if (mOnActivatedListener != null) {
@@ -388,19 +317,25 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mBackgroundNormal.animate()
.alpha(reverse ? 0f : 1f)
.setInterpolator(alphaInterpolator)
- .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float animatedFraction = animation.getAnimatedFraction();
- if (reverse) {
- animatedFraction = 1.0f - animatedFraction;
- }
- setNormalBackgroundVisibilityAmount(animatedFraction);
+ .setUpdateListener(animation -> {
+ float animatedFraction = animation.getAnimatedFraction();
+ if (reverse) {
+ animatedFraction = 1.0f - animatedFraction;
}
+ setNormalBackgroundVisibilityAmount(animatedFraction);
})
.setDuration(ACTIVATE_ANIMATION_LENGTH);
}
+ @Override
+ public boolean performClick() {
+ if (!mNeedsDimming || (mAccessibilityManager != null
+ && mAccessibilityManager.isTouchExplorationEnabled())) {
+ return super.performClick();
+ }
+ return false;
+ }
+
/**
* Cancels the hotspot and makes the notification inactive.
*/
@@ -418,11 +353,13 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
if (mOnActivatedListener != null) {
mOnActivatedListener.onActivationReset(this);
}
- removeCallbacks(mTapTimeoutRunnable);
}
public void setDimmed(boolean dimmed, boolean fade) {
mNeedsDimming = dimmed;
+ if (mOnDimmedListener != null) {
+ mOnDimmedListener.onSetDimmed(dimmed);
+ }
dimmed &= isDimmable();
if (mDimmed != dimmed) {
mDimmed = dimmed;
@@ -439,13 +376,17 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
return true;
}
+ public boolean isDimmed() {
+ return mDimmed;
+ }
+
private void updateOutlineAlpha() {
float alpha = NotificationStackScrollLayout.BACKGROUND_ALPHA_DIMMED;
alpha = (alpha + (1.0f - alpha) * mNormalBackgroundVisibilityAmount);
setOutlineAlpha(alpha);
}
- public void setNormalBackgroundVisibilityAmount(float normalBackgroundVisibilityAmount) {
+ private void setNormalBackgroundVisibilityAmount(float normalBackgroundVisibilityAmount) {
mNormalBackgroundVisibilityAmount = normalBackgroundVisibilityAmount;
updateOutlineAlpha();
}
@@ -473,14 +414,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
/**
* Sets the tint color of the background
*/
- public void setTintColor(int color) {
+ protected void setTintColor(int color) {
setTintColor(color, false);
}
/**
* Sets the tint color of the background
*/
- public void setTintColor(int color, boolean animated) {
+ void setTintColor(int color, boolean animated) {
if (color != mBgTint) {
mBgTint = color;
updateBackgroundTint(animated);
@@ -562,13 +503,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mStartTint = mCurrentBackgroundTint;
mTargetTint = color;
mBackgroundColorAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
- mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int newColor = NotificationUtils.interpolateColors(mStartTint, mTargetTint,
- animation.getAnimatedFraction());
- setBackgroundTintColor(newColor);
- }
+ mBackgroundColorAnimator.addUpdateListener(animation -> {
+ int newColor = NotificationUtils.interpolateColors(mStartTint, mTargetTint,
+ animation.getAnimatedFraction());
+ setBackgroundTintColor(newColor);
});
mBackgroundColorAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
mBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR);
@@ -643,11 +581,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
protected void updateBackgroundAlpha(float transformationAmount) {
- mBgAlpha = isChildInGroup() && mDimmed ? transformationAmount : 1f;
+ float bgAlpha = isChildInGroup() && mDimmed ? transformationAmount : 1f;
if (mDimmedBackgroundFadeInAmount != -1) {
- mBgAlpha *= mDimmedBackgroundFadeInAmount;
+ bgAlpha *= mDimmedBackgroundFadeInAmount;
}
- mBackgroundDimmed.setAlpha(mBgAlpha);
+ mBackgroundDimmed.setAlpha(bgAlpha);
}
protected void resetBackgroundAlpha() {
@@ -671,7 +609,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mBackgroundDimmed.setVisibility(View.INVISIBLE);
mBackgroundNormal.setVisibility(View.VISIBLE);
mBackgroundNormal.setAlpha(1f);
- removeCallbacks(mTapTimeoutRunnable);
// make in inactive to avoid it sticking around active
makeInactive(false /* animate */);
}
@@ -783,14 +720,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mAppearAnimator.setInterpolator(Interpolators.LINEAR);
mAppearAnimator.setDuration(
(long) (duration * Math.abs(mAppearAnimationFraction - targetValue)));
- mAppearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mAppearAnimationFraction = (float) animation.getAnimatedValue();
- updateAppearAnimationAlpha();
- updateAppearRect();
- invalidate();
- }
+ mAppearAnimator.addUpdateListener(animation -> {
+ mAppearAnimationFraction = (float) animation.getAnimatedValue();
+ updateAppearAnimationAlpha();
+ updateAppearRect();
+ invalidate();
});
if (animationListener != null) {
mAppearAnimator.addListener(animationListener);
@@ -921,7 +855,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
getCurrentBackgroundRadiusBottom());
}
- protected void applyBackgroundRoundness(float topRadius, float bottomRadius) {
+ private void applyBackgroundRoundness(float topRadius, float bottomRadius) {
mBackgroundDimmed.setRoundness(topRadius, bottomRadius);
mBackgroundNormal.setRoundness(topRadius, bottomRadius);
}
@@ -963,7 +897,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
}
- protected int getRippleColor() {
+ private int getRippleColor() {
if (mBgTint != 0) {
return mTintedRippleColor;
} else {
@@ -1010,10 +944,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mOnActivatedListener = onActivatedListener;
}
- public boolean hasSameBgColor(ActivatableNotificationView otherView) {
- return calculateBgColor() == otherView.calculateBgColor();
- }
-
@Override
public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
int outlineTranslation) {
@@ -1071,8 +1001,24 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
return mRefocusOnDismiss || isAccessibilityFocused();
}
+ void setTouchHandler(Gefingerpoken touchHandler) {
+ mTouchHandler = touchHandler;
+ }
+
+ void setOnDimmedListener(OnDimmedListener onDimmedListener) {
+ mOnDimmedListener = onDimmedListener;
+ }
+
+ public void setAccessibilityManager(AccessibilityManager accessibilityManager) {
+ mAccessibilityManager = accessibilityManager;
+ }
+
public interface OnActivatedListener {
void onActivated(ActivatableNotificationView view);
void onActivationReset(ActivatableNotificationView view);
}
+
+ interface OnDimmedListener {
+ void onSetDimmed(boolean dimmed);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index 18993ffec357..8465658079f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -16,9 +16,13 @@
package com.android.systemui.statusbar.notification.row;
+import android.view.MotionEvent;
+import android.view.View;
import android.view.accessibility.AccessibilityManager;
+import com.android.systemui.Gefingerpoken;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.statusbar.phone.DoubleTapHelper;
import javax.inject.Inject;
@@ -27,21 +31,102 @@ import javax.inject.Inject;
*/
public class ActivatableNotificationViewController {
private final ActivatableNotificationView mView;
+ private final ExpandableOutlineViewController mExpandableOutlineViewController;
private final AccessibilityManager mAccessibilityManager;
private final FalsingManager mFalsingManager;
+ private DoubleTapHelper mDoubleTapHelper;
+ private boolean mNeedsDimming;
+
+ private TouchHandler mTouchHandler = new TouchHandler();
@Inject
public ActivatableNotificationViewController(ActivatableNotificationView view,
+ ExpandableOutlineViewController expandableOutlineViewController,
AccessibilityManager accessibilityManager, FalsingManager falsingManager) {
mView = view;
+ mExpandableOutlineViewController = expandableOutlineViewController;
mAccessibilityManager = accessibilityManager;
mFalsingManager = falsingManager;
+
+ mView.setOnActivatedListener(new ActivatableNotificationView.OnActivatedListener() {
+ @Override
+ public void onActivated(ActivatableNotificationView view) {
+ mFalsingManager.onNotificationActive();
+ }
+
+ @Override
+ public void onActivationReset(ActivatableNotificationView view) {
+ }
+ });
}
/**
* Initialize the controller, setting up handlers and other behavior.
*/
public void init() {
+ mExpandableOutlineViewController.init();
+ mDoubleTapHelper = new DoubleTapHelper(mView, (active) -> {
+ if (active) {
+ mView.makeActive();
+ mFalsingManager.onNotificationActive();
+ } else {
+ mView.makeInactive(true /* animate */);
+ }
+ }, mView::performClick, mView::handleSlideBack, mFalsingManager::onNotificationDoubleTap);
+ mView.setOnTouchListener(mTouchHandler);
+ mView.setTouchHandler(mTouchHandler);
+ mView.setOnDimmedListener(dimmed -> {
+ mNeedsDimming = dimmed;
+ });
+ mView.setAccessibilityManager(mAccessibilityManager);
+ }
+
+ class TouchHandler implements Gefingerpoken, View.OnTouchListener {
+ private boolean mBlockNextTouch;
+
+ @Override
+ public boolean onTouch(View v, MotionEvent ev) {
+ boolean result;
+ if (mBlockNextTouch) {
+ mBlockNextTouch = false;
+ return true;
+ }
+ if (mNeedsDimming && !mAccessibilityManager.isTouchExplorationEnabled()
+ && mView.isInteractive()) {
+ if (mNeedsDimming && !mView.isDimmed()) {
+ // We're actually dimmed, but our content isn't dimmable,
+ // let's ensure we have a ripple
+ return false;
+ }
+ result = mDoubleTapHelper.onTouchEvent(ev, mView.getActualHeight());
+ } else {
+ return false;
+ }
+ return result;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (mNeedsDimming && ev.getActionMasked() == MotionEvent.ACTION_DOWN
+ && mView.disallowSingleClick(ev)
+ && !mAccessibilityManager.isTouchExplorationEnabled()) {
+ if (!mView.isActivated()) {
+ return true;
+ } else if (!mDoubleTapHelper.isWithinDoubleTapSlop(ev)) {
+ mBlockNextTouch = true;
+ mView.makeInactive(true /* animate */);
+ return true;
+ }
+ }
+ return false;
+ }
+ /**
+ * Use {@link #onTouch(View, MotionEvent) instead}.
+ */
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ return false;
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index c34bba782ad5..551731824570 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -42,7 +42,6 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
-import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -72,11 +71,11 @@ import com.android.internal.widget.CachingIconView;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarIconView;
@@ -199,6 +198,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private NotificationGuts mGuts;
private NotificationEntry mEntry;
private String mAppName;
+ private FalsingManager mFalsingManager;
/**
* Whether or not the notification is using the heads up view and should peek from the top.
@@ -1087,20 +1087,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mEntry.setInitializationTime(SystemClock.elapsedRealtime());
- Dependency.get(PluginManager.class).addPluginListener(this,
- NotificationMenuRowPlugin.class, false /* Allow multiple */);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- Dependency.get(PluginManager.class).removePluginListener(this);
- }
-
- @Override
public void onPluginConnected(NotificationMenuRowPlugin plugin, Context pluginContext) {
boolean existed = mMenuRow != null && mMenuRow.getMenuView() != null;
if (existed) {
@@ -1439,7 +1425,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mIsBlockingHelperShowing && mNotificationTranslationFinished;
}
- public void setOnDismissRunnable(Runnable onDismissRunnable) {
+ void setOnDismissRunnable(Runnable onDismissRunnable) {
mOnDismissRunnable = onDismissRunnable;
}
@@ -1597,7 +1583,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mMenuRow = new NotificationMenuRow(mContext);
mImageResolver = new NotificationInlineImageResolver(context,
new NotificationInlineImageCache());
- mMediaManager = Dependency.get(NotificationMediaManager.class);
initDimens();
}
@@ -1612,7 +1597,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
NotificationGroupManager groupManager,
HeadsUpManager headsUpManager,
RowContentBindStage rowContentBindStage,
- OnExpandClickListener onExpandClickListener) {
+ OnExpandClickListener onExpandClickListener,
+ NotificationMediaManager notificationMediaManager,
+ OnAppOpsClickListener onAppOpsClickListener,
+ FalsingManager falsingManager,
+ StatusBarStateController statusBarStateController) {
mAppName = appName;
if (mMenuRow != null && mMenuRow.getMenuView() != null) {
mMenuRow.setAppName(mAppName);
@@ -1625,9 +1614,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mHeadsUpManager = headsUpManager;
mRowContentBindStage = rowContentBindStage;
mOnExpandClickListener = onExpandClickListener;
- }
-
- public void setStatusBarStateController(StatusBarStateController statusBarStateController) {
+ mMediaManager = notificationMediaManager;
+ setAppOpsOnClickListener(onAppOpsClickListener);
+ mFalsingManager = falsingManager;
mStatusbarStateController = statusBarStateController;
}
@@ -1719,7 +1708,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mOnAppOpsClickListener;
}
- public void setAppOpsOnClickListener(ExpandableNotificationRow.OnAppOpsClickListener l) {
+ void setAppOpsOnClickListener(ExpandableNotificationRow.OnAppOpsClickListener l) {
mOnAppOpsClickListener = v -> {
createMenu();
NotificationMenuRowPlugin provider = getProvider();
@@ -2188,7 +2177,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
* @param allowChildExpansion whether a call to this method allows expanding children
*/
public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
- getFalsingManager().setNotificationExpanded();
+ mFalsingManager.setNotificationExpanded();
if (mIsSummaryWithChildren && !shouldShowPublic() && allowChildExpansion
&& !mChildrenContainer.showingAsLowPriority()) {
final boolean wasExpanded = mGroupManager.isGroupExpanded(mEntry.getSbn());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
new file mode 100644
index 000000000000..39fab439ad07
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row;
+
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.dagger.AppName;
+import com.android.systemui.statusbar.notification.row.dagger.DismissRunnable;
+import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
+import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.util.time.SystemClock;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * Controller for {@link ExpandableNotificationRow}.
+ */
+@NotificationRowScope
+public class ExpandableNotificationRowController {
+ private final ExpandableNotificationRow mView;
+ private final ActivatableNotificationViewController mActivatableNotificationViewController;
+ private final NotificationMediaManager mMediaManager;
+ private final PluginManager mPluginManager;
+ private final SystemClock mClock;
+ private final String mAppName;
+ private final String mNotificationKey;
+ private final KeyguardBypassController mKeyguardBypassController;
+ private final NotificationGroupManager mNotificationGroupManager;
+ private final RowContentBindStage mRowContentBindStage;
+ private final NotificationLogger mNotificationLogger;
+ private final HeadsUpManager mHeadsUpManager;
+ private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener;
+ private final StatusBarStateController mStatusBarStateController;
+ private final NotificationRowContentBinder.InflationCallback mInflationCallback;
+
+ private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
+ this::logNotificationExpansion;
+ private final ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
+ private final NotificationGutsManager mNotificationGutsManager;
+ private Runnable mOnDismissRunnable;
+ private final FalsingManager mFalsingManager;
+ private final boolean mAllowLongPress;
+
+ @Inject
+ public ExpandableNotificationRowController(ExpandableNotificationRow view,
+ ActivatableNotificationViewController activatableNotificationViewController,
+ NotificationMediaManager mediaManager, PluginManager pluginManager,
+ SystemClock clock, @AppName String appName, @NotificationKey String notificationKey,
+ KeyguardBypassController keyguardBypassController,
+ NotificationGroupManager notificationGroupManager,
+ RowContentBindStage rowContentBindStage,
+ NotificationLogger notificationLogger, HeadsUpManager headsUpManager,
+ ExpandableNotificationRow.OnExpandClickListener onExpandClickListener,
+ StatusBarStateController statusBarStateController,
+ NotificationRowContentBinder.InflationCallback inflationCallback,
+ NotificationGutsManager notificationGutsManager,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
+ @DismissRunnable Runnable onDismissRunnable, FalsingManager falsingManager) {
+ mView = view;
+ mActivatableNotificationViewController = activatableNotificationViewController;
+ mMediaManager = mediaManager;
+ mPluginManager = pluginManager;
+ mClock = clock;
+ mAppName = appName;
+ mNotificationKey = notificationKey;
+ mKeyguardBypassController = keyguardBypassController;
+ mNotificationGroupManager = notificationGroupManager;
+ mRowContentBindStage = rowContentBindStage;
+ mNotificationLogger = notificationLogger;
+ mHeadsUpManager = headsUpManager;
+ mOnExpandClickListener = onExpandClickListener;
+ mStatusBarStateController = statusBarStateController;
+ mInflationCallback = inflationCallback;
+ mNotificationGutsManager = notificationGutsManager;
+ mOnDismissRunnable = onDismissRunnable;
+ mOnAppOpsClickListener = mNotificationGutsManager::openGuts;
+ mAllowLongPress = allowLongPress;
+ mFalsingManager = falsingManager;
+ }
+
+ /**
+ * Initialize the controller.
+ */
+ public void init() {
+ mActivatableNotificationViewController.init();
+ mView.initialize(
+ mAppName,
+ mNotificationKey,
+ mExpansionLogger,
+ mKeyguardBypassController,
+ mNotificationGroupManager,
+ mHeadsUpManager,
+ mRowContentBindStage,
+ mOnExpandClickListener,
+ mMediaManager,
+ mOnAppOpsClickListener,
+ mFalsingManager,
+ mStatusBarStateController
+ );
+ mView.setOnDismissRunnable(mOnDismissRunnable);
+ mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ if (mAllowLongPress) {
+ mView.setLongPressListener(mNotificationGutsManager::openGuts);
+ }
+ if (ENABLE_REMOTE_INPUT) {
+ mView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+ }
+
+ mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ mView.getEntry().setInitializationTime(mClock.elapsedRealtime());
+ mPluginManager.addPluginListener(mView,
+ NotificationMenuRowPlugin.class, false /* Allow multiple */);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ mPluginManager.removePluginListener(mView);
+ }
+ });
+ }
+
+ private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
+ mNotificationLogger.onExpansionChanged(key, userAction, expanded);
+ }
+
+ /** */
+ public void setOnDismissRunnable(Runnable onDismissRunnable) {
+ mOnDismissRunnable = onDismissRunnable;
+ mView.setOnDismissRunnable(onDismissRunnable);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineViewController.java
new file mode 100644
index 000000000000..75c9d1e6f2fc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineViewController.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row;
+
+import javax.inject.Inject;
+
+/**
+ * Controller for {@link ExpandableOutlineView}.
+ */
+public class ExpandableOutlineViewController {
+ private final ExpandableOutlineView mView;
+ private final ExpandableViewController mExpandableViewController;
+
+ @Inject
+ public ExpandableOutlineViewController(ExpandableOutlineView view,
+ ExpandableViewController expandableViewController) {
+ mView = view;
+ mExpandableViewController = expandableViewController;
+ }
+
+ /**
+ * Initialize the controller.
+ */
+ public void init() {
+ mExpandableViewController.init();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableViewController.java
new file mode 100644
index 000000000000..e14ca8c4e590
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableViewController.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row;
+
+import javax.inject.Inject;
+
+/**
+ * Controller for {@link ExpandableView}.
+ */
+public class ExpandableViewController {
+ private final ExpandableView mView;
+
+ @Inject
+ public ExpandableViewController(ExpandableView view) {
+ mView = view;
+ }
+
+ /**
+ * Initialize the controller.
+ */
+ public void init() {
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
index c173b4dbaebe..6feffe654630 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
@@ -26,7 +26,6 @@ import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import com.android.systemui.R;
import com.android.systemui.statusbar.InflationTask;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import javax.inject.Inject;
@@ -37,7 +36,6 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
private static final String TAG = "RowInflaterTask";
private static final boolean TRACE_ORIGIN = true;
- private final NotificationRowComponent.Builder mNotificationRowComponentBuilder;
private RowInflationFinishedListener mListener;
private NotificationEntry mEntry;
@@ -45,10 +43,7 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
private Throwable mInflateOrigin;
@Inject
- public RowInflaterTask(
- NotificationRowComponent.Builder notificationRowComponentBuilder) {
- super();
- mNotificationRowComponentBuilder = notificationRowComponentBuilder;
+ public RowInflaterTask() {
}
/**
@@ -75,12 +70,6 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
public void onInflateFinished(View view, int resid, ViewGroup parent) {
if (!mCancelled) {
try {
- // Setup the controller for the view.
- NotificationRowComponent component = mNotificationRowComponentBuilder
- .activatableNotificationView((ActivatableNotificationView) view)
- .build();
- component.getActivatableNotificationViewController().init();
-
mEntry.onInflationTaskFinished();
mListener.onInflationFinished((ExpandableNotificationRow) view);
} catch (Throwable t) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ActivatableNotificationViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ActivatableNotificationViewModule.java
new file mode 100644
index 000000000000..a3dfa608c709
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ActivatableNotificationViewModule.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row.dagger;
+
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
+import com.android.systemui.statusbar.notification.row.ExpandableOutlineView;
+import com.android.systemui.statusbar.notification.row.ExpandableView;
+
+import dagger.Binds;
+import dagger.Module;
+
+/**
+ * Module for NotificationRowComponent.
+ */
+@Module
+public interface ActivatableNotificationViewModule {
+ /** ExpandableView is provided as an instance of ActivatableNotificationView. */
+ @Binds
+ ExpandableView bindExpandableView(ActivatableNotificationView view);
+ /** ExpandableOutlineView is provided as an instance of ActivatableNotificationView. */
+ @Binds
+ ExpandableOutlineView bindExpandableOutlineView(ActivatableNotificationView view);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/AppName.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/AppName.java
new file mode 100644
index 000000000000..1dbca0cd5527
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/AppName.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface AppName {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java
new file mode 100644
index 000000000000..433114224289
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface DismissRunnable {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
new file mode 100644
index 000000000000..6d6d3e446f53
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row.dagger;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder;
+import com.android.systemui.statusbar.notification.row.RowContentBindStage;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import dagger.Binds;
+import dagger.BindsInstance;
+import dagger.Module;
+import dagger.Provides;
+import dagger.Subcomponent;
+
+/**
+ * Dagger Component for a {@link ExpandableNotificationRow}.
+ */
+@Subcomponent(modules = {ExpandableNotificationRowComponent.ExpandableNotificationRowModule.class,
+ ActivatableNotificationViewModule.class})
+@NotificationRowScope
+public interface ExpandableNotificationRowComponent {
+
+ /**
+ * Builder for {@link NotificationRowComponent}.
+ */
+ @Subcomponent.Builder
+ interface Builder {
+ // TODO: NotificationEntry contains a reference to ExpandableNotificationRow, so it
+ // should be possible to pull one from the other, but they aren't connected at the time
+ // this component is constructed.
+ @BindsInstance
+ Builder expandableNotificationRow(ExpandableNotificationRow view);
+ @BindsInstance
+ Builder notificationEntry(NotificationEntry entry);
+ @BindsInstance
+ Builder onDismissRunnable(@DismissRunnable Runnable runnable);
+ @BindsInstance
+ Builder rowContentBindStage(RowContentBindStage rowContentBindStage);
+ @BindsInstance
+ Builder inflationCallback(NotificationRowContentBinder.InflationCallback inflationCallback);
+ @BindsInstance
+ Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter);
+ ExpandableNotificationRowComponent build();
+ }
+
+ /**
+ * Creates a ExpandableNotificationRowController.
+ */
+ @NotificationRowScope
+ ExpandableNotificationRowController getExpandableNotificationRowController();
+
+ /**
+ * Dagger Module that extracts interesting properties from an ExpandableNotificationRow.
+ */
+ @Module
+ abstract class ExpandableNotificationRowModule {
+
+ /** ExpandableNotificationRow is provided as an instance of ActivatableNotificationView. */
+ @Binds
+ abstract ActivatableNotificationView bindExpandableView(ExpandableNotificationRow view);
+
+ @Provides
+ static StatusBarNotification provideStatusBarNotification(
+ NotificationEntry notificationEntry) {
+ return notificationEntry.getSbn();
+ }
+
+ @Provides
+ @NotificationKey
+ static String provideNotificationKey(StatusBarNotification statusBarNotification) {
+ return statusBarNotification.getKey();
+ }
+
+ @Provides
+ @AppName
+ static String provideAppName(Context context, StatusBarNotification statusBarNotification) {
+ // Get the app name.
+ // Note that Notification.Builder#bindHeaderAppName has similar logic
+ // but since this field is used in the guts, it must be accurate.
+ // Therefore we will only show the application label, or, failing that, the
+ // package name. No substitutions.
+ PackageManager pmUser = StatusBar.getPackageManagerForUser(
+ context, statusBarNotification.getUser().getIdentifier());
+ final String pkg = statusBarNotification.getPackageName();
+ try {
+ final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS);
+ if (info != null) {
+ return String.valueOf(pmUser.getApplicationLabel(info));
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Do nothing
+ }
+
+ return pkg;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationKey.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationKey.java
new file mode 100644
index 000000000000..b1fff383cd5d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationKey.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface NotificationKey {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java
index f16ea7ae23e9..1f535c5e3f56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java
@@ -16,24 +16,17 @@
package com.android.systemui.statusbar.notification.row.dagger;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Scope;
-
import dagger.BindsInstance;
import dagger.Subcomponent;
/**
* Dagger subcomponent for Notification related views.
*/
-@Subcomponent(modules = {})
-@NotificationRowComponent.NotificationRowScope
+@Subcomponent(modules = {ActivatableNotificationViewModule.class})
+@NotificationRowScope
public interface NotificationRowComponent {
/**
* Builder for {@link NotificationRowComponent}.
@@ -46,14 +39,6 @@ public interface NotificationRowComponent {
}
/**
- * Scope annotation for singleton items within the StatusBarComponent.
- */
- @Documented
- @Retention(RUNTIME)
- @Scope
- @interface NotificationRowScope {}
-
- /**
* Creates a ActivatableNotificationViewController.
*/
@NotificationRowScope
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java
new file mode 100644
index 000000000000..4555b839a3f2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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.statusbar.notification.row.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singleton items within the StatusBarComponent.
+ */
+@Documented
+@Retention(RUNTIME)
+@Scope
+public @interface NotificationRowScope {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 07f6936ece07..5a0a495e1f85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -58,10 +58,13 @@ import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.util.NotificationMessagingUtil;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -83,12 +86,13 @@ import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.RowContentBindParams;
import com.android.systemui.statusbar.notification.row.RowContentBindStage;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
-import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
+import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -96,6 +100,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.Assert;
import com.android.systemui.util.leak.LeakDetector;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.After;
import org.junit.Before;
@@ -106,6 +111,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -141,8 +147,13 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
@Mock private NotificationEntryManagerLogger mLogger;
@Mock private FeatureFlags mFeatureFlags;
@Mock private LeakDetector mLeakDetector;
- @Mock private ActivatableNotificationViewController mActivatableNotificationViewController;
- @Mock private NotificationRowComponent.Builder mNotificationRowComponentBuilder;
+ @Mock private NotificationMediaManager mNotificationMediaManager;
+ @Mock private ExpandableNotificationRowComponent.Builder
+ mExpandableNotificationRowComponentBuilder;
+ @Mock private ExpandableNotificationRowComponent mExpandableNotificationRowComponent;
+ @Mock private FalsingManager mFalsingManager;
+ @Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private StatusBarStateController mStatusBarStateController;
private int mId;
private NotificationEntry mEntry;
@@ -191,7 +202,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
mDependency.injectMockDependency(SmartReplyController.class);
- mDependency.injectMockDependency(NotificationMediaManager.class);
mCountDownLatch = new CountDownLatch(1);
@@ -207,28 +217,23 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mEntry.expandedIcon = mock(StatusBarIconView.class);
- when(mNotificationRowComponentBuilder.activatableNotificationView(any()))
- .thenReturn(mNotificationRowComponentBuilder);
- when(mNotificationRowComponentBuilder.build()).thenReturn(
- () -> mActivatableNotificationViewController);
-
RowContentBindStage bindStage = mock(RowContentBindStage.class);
when(bindStage.getStageParams(any())).thenReturn(new RowContentBindParams());
-
NotificationRowBinderImpl notificationRowBinder =
new NotificationRowBinderImpl(mContext,
+ new NotificationMessagingUtil(mContext),
mRemoteInputManager,
mLockscreenUserManager,
mock(NotifBindPipeline.class),
bindStage,
true, /* allowLongPress */
- mock(KeyguardBypassController.class),
- mock(StatusBarStateController.class),
+ mKeyguardBypassController,
+ mStatusBarStateController,
mGroupManager,
mGutsManager,
mNotificationInterruptionStateProvider,
- () -> new RowInflaterTask(mNotificationRowComponentBuilder),
- mock(NotificationLogger.class));
+ RowInflaterTask::new,
+ mExpandableNotificationRowComponentBuilder);
when(mFeatureFlags.isNewNotifPipelineEnabled()).thenReturn(false);
when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
@@ -236,7 +241,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mLogger,
mGroupManager,
new NotificationRankingManager(
- () -> mock(NotificationMediaManager.class),
+ () -> mNotificationMediaManager,
mGroupManager,
mHeadsUpManager,
mock(NotificationFilter.class),
@@ -255,13 +260,55 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mEntryManager.addNotificationEntryListener(mEntryListener);
mEntryManager.addNotificationRemoveInterceptor(mRemoveInterceptor);
- notificationRowBinder.setUpWithPresenter(
- mPresenter, mListContainer, mHeadsUpManager, mBindCallback);
+ notificationRowBinder.setUpWithPresenter(mPresenter, mListContainer, mBindCallback);
notificationRowBinder.setInflationCallback(mEntryManager);
notificationRowBinder.setNotificationClicker(mock(NotificationClicker.class));
setUserSentiment(
mEntry.getKey(), Ranking.USER_SENTIMENT_NEUTRAL);
+
+ ArgumentCaptor<ExpandableNotificationRow> viewCaptor =
+ ArgumentCaptor.forClass(ExpandableNotificationRow.class);
+ when(mExpandableNotificationRowComponentBuilder
+ .expandableNotificationRow(viewCaptor.capture()))
+ .thenReturn(mExpandableNotificationRowComponentBuilder);
+ when(mExpandableNotificationRowComponentBuilder
+ .notificationEntry(any()))
+ .thenReturn(mExpandableNotificationRowComponentBuilder);
+ when(mExpandableNotificationRowComponentBuilder
+ .onDismissRunnable(any()))
+ .thenReturn(mExpandableNotificationRowComponentBuilder);
+ when(mExpandableNotificationRowComponentBuilder
+ .inflationCallback(any()))
+ .thenReturn(mExpandableNotificationRowComponentBuilder);
+ when(mExpandableNotificationRowComponentBuilder
+ .onExpandClickListener(any()))
+ .thenReturn(mExpandableNotificationRowComponentBuilder);
+
+ when(mExpandableNotificationRowComponentBuilder.build())
+ .thenReturn(mExpandableNotificationRowComponent);
+ when(mExpandableNotificationRowComponent.getExpandableNotificationRowController())
+ .thenAnswer((Answer<ExpandableNotificationRowController>) invocation ->
+ new ExpandableNotificationRowController(
+ viewCaptor.getValue(),
+ mock(ActivatableNotificationViewController.class),
+ mNotificationMediaManager,
+ mock(PluginManager.class),
+ new FakeSystemClock(),
+ "FOOBAR", "FOOBAR",
+ mKeyguardBypassController,
+ mGroupManager,
+ bindStage,
+ mock(NotificationLogger.class),
+ mHeadsUpManager,
+ mPresenter,
+ mStatusBarStateController,
+ mEntryManager,
+ mGutsManager,
+ true,
+ null,
+ mFalsingManager
+ ));
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index d8cf6ed9a47b..a8918103c4a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -194,9 +194,8 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
@Test
public void testClickSound() throws Exception {
assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled());
- StatusBarStateController mock = mock(StatusBarStateController.class);
+ StatusBarStateController mock = mNotificationTestHelper.getStatusBarStateController();
when(mock.isDozing()).thenReturn(true);
- mGroupRow.setStatusBarStateController(mock);
mGroupRow.setSecureStateProvider(()-> false);
assertFalse("Shouldn't play sounds when dark and trusted.",
mGroupRow.isSoundEffectsEnabled());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 9b2e0c375e87..35b55087873b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -45,6 +45,7 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.TestableDependency;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.bubbles.BubblesTestActivity;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -91,6 +92,7 @@ public class NotificationTestHelper {
private final NotifBindPipeline mBindPipeline;
private final NotificationEntryListener mBindPipelineEntryListener;
private final RowContentBindStage mBindStage;
+ private StatusBarStateController mStatusBarStateController;
public NotificationTestHelper(Context context, TestableDependency dependency) {
mContext = context;
@@ -98,9 +100,9 @@ public class NotificationTestHelper {
dependency.injectMockDependency(BubbleController.class);
dependency.injectMockDependency(NotificationShadeWindowController.class);
dependency.injectMockDependency(SmartReplyController.class);
- StatusBarStateController stateController = mock(StatusBarStateController.class);
- mGroupManager = new NotificationGroupManager(stateController);
- mHeadsUpManager = new HeadsUpManagerPhone(mContext, stateController,
+ mStatusBarStateController = mock(StatusBarStateController.class);
+ mGroupManager = new NotificationGroupManager(mStatusBarStateController);
+ mHeadsUpManager = new HeadsUpManagerPhone(mContext, mStatusBarStateController,
mock(KeyguardBypassController.class));
mHeadsUpManager.setUp(null, mGroupManager, null, null);
mGroupManager.setHeadsUpManager(mHeadsUpManager);
@@ -321,6 +323,10 @@ public class NotificationTestHelper {
return notificationBuilder.build();
}
+ public StatusBarStateController getStatusBarStateController() {
+ return mStatusBarStateController;
+ }
+
private ExpandableNotificationRow generateRow(
Notification notification,
String pkg,
@@ -382,7 +388,11 @@ public class NotificationTestHelper {
mGroupManager,
mHeadsUpManager,
mBindStage,
- mock(OnExpandClickListener.class));
+ mock(OnExpandClickListener.class),
+ mock(NotificationMediaManager.class),
+ mock(ExpandableNotificationRow.OnAppOpsClickListener.class),
+ mock(FalsingManager.class),
+ mStatusBarStateController);
row.setAboveShelfChangedListener(aboveShelf -> { });
mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
inflateAndWait(entry, mBindStage);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index e84f14a6a2c1..2d1bc7890aed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -30,7 +30,6 @@ import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -59,8 +58,6 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
private ExpandableNotificationRow mFirst;
private ExpandableNotificationRow mSecond;
@Mock
- private StatusBarStateController mStatusBarStateController;
- @Mock
private KeyguardBypassController mBypassController;
@Before
@@ -150,13 +147,12 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
createSection(mFirst, mSecond),
createSection(null, null)
});
- ExpandableNotificationRow row = new NotificationTestHelper(getContext(), mDependency)
- .createRow();
+ NotificationTestHelper testHelper = new NotificationTestHelper(getContext(), mDependency);
+ ExpandableNotificationRow row = testHelper.createRow();
NotificationEntry entry = mock(NotificationEntry.class);
when(entry.getRow()).thenReturn(row);
- when(mStatusBarStateController.isDozing()).thenReturn(true);
- row.setStatusBarStateController(mStatusBarStateController);
+ when(testHelper.getStatusBarStateController().isDozing()).thenReturn(true);
row.setHeadsUp(true);
mRoundnessManager.onHeadsUpStateChanged(entry, true);
Assert.assertEquals(1f, row.getCurrentBottomRoundness(), 0.0f);
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 285f4ab6cdf5..4efe93439b42 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -28,6 +28,7 @@ java_defaults {
"netd_aidl_interface-unstable-java",
"netlink-client",
"networkstack-aidl-interfaces-unstable-java",
+ "android.hardware.tetheroffload.config-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
"net-utils-framework-common",
],
@@ -48,25 +49,26 @@ android_library {
// Due to b/143733063, APK can't access a jni lib that is in APEX (but not in the APK).
cc_library {
name: "libtetherutilsjni",
+ sdk_version: "current",
srcs: [
"jni/android_net_util_TetheringUtils.cpp",
],
shared_libs: [
- "libcgrouprc",
- "libnativehelper_compat_libc++",
- "libvndksupport",
- ],
- static_libs: [
- "android.hardware.tetheroffload.config@1.0",
"liblog",
- "libbase",
- "libcutils",
- "libhidlbase",
- "libjsoncpp",
- "libprocessgroup",
- "libutils",
+ "libnativehelper_compat_libc++",
],
+ // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
+ // java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
+ // even if "libc++" is added into jni_libs below. Adding "libc++_shared" into jni_libs doesn't
+ // build because soong complains of:
+ // module Tethering missing dependencies: libc++_shared
+ //
+ // So, link libc++ statically. This means that we also need to ensure that all the C++ libraries
+ // we depend on do not dynamically link libc++. This is currently the case, because liblog is
+ // C-only and libnativehelper_compat_libc also uses stl: "c++_static".
+ stl: "c++_static",
+
cflags: [
"-Wall",
"-Werror",
@@ -85,9 +87,8 @@ java_defaults {
// Build system doesn't track transitive dependeicies for jni_libs, list all the dependencies
// explicitly.
jni_libs: [
- "libcgrouprc",
+ "liblog",
"libnativehelper_compat_libc++",
- "libvndksupport",
"libtetherutilsjni",
],
resource_dirs: [
diff --git a/packages/Tethering/jni/android_net_util_TetheringUtils.cpp b/packages/Tethering/jni/android_net_util_TetheringUtils.cpp
index 1cf8f988432c..549344064405 100644
--- a/packages/Tethering/jni/android_net_util_TetheringUtils.cpp
+++ b/packages/Tethering/jni/android_net_util_TetheringUtils.cpp
@@ -16,123 +16,18 @@
#include <errno.h>
#include <error.h>
-#include <hidl/HidlSupport.h>
#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
-#include <linux/netfilter/nfnetlink.h>
-#include <linux/netlink.h>
#include <net/if.h>
#include <netinet/icmp6.h>
#include <sys/socket.h>
-#include <android-base/unique_fd.h>
-#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
#define LOG_TAG "TetheringUtils"
-#include <utils/Log.h>
+#include <android/log.h>
namespace android {
-using hardware::hidl_handle;
-using hardware::hidl_string;
-using hardware::tetheroffload::config::V1_0::IOffloadConfig;
-
-namespace {
-
-inline const sockaddr * asSockaddr(const sockaddr_nl *nladdr) {
- return reinterpret_cast<const sockaddr *>(nladdr);
-}
-
-int conntrackSocket(unsigned groups) {
- base::unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER));
- if (s.get() < 0) return -errno;
-
- const struct sockaddr_nl bind_addr = {
- .nl_family = AF_NETLINK,
- .nl_pad = 0,
- .nl_pid = 0,
- .nl_groups = groups,
- };
- if (bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
- return -errno;
- }
-
- const struct sockaddr_nl kernel_addr = {
- .nl_family = AF_NETLINK,
- .nl_pad = 0,
- .nl_pid = 0,
- .nl_groups = groups,
- };
- if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
- return -errno;
- }
-
- return s.release();
-}
-
-// Return a hidl_handle that owns the file descriptor owned by fd, and will
-// auto-close it (otherwise there would be double-close problems).
-//
-// Rely upon the compiler to eliminate the constexprs used for clarity.
-hidl_handle handleFromFileDescriptor(base::unique_fd fd) {
- hidl_handle h;
-
- static constexpr int kNumFds = 1;
- static constexpr int kNumInts = 0;
- native_handle_t *nh = native_handle_create(kNumFds, kNumInts);
- nh->data[0] = fd.release();
-
- static constexpr bool kTakeOwnership = true;
- h.setTo(nh, kTakeOwnership);
-
- return h;
-}
-
-} // namespace
-
-static jboolean android_net_util_configOffload(
- JNIEnv* /* env */) {
- sp<IOffloadConfig> configInterface = IOffloadConfig::getService();
- if (configInterface.get() == nullptr) {
- ALOGD("Could not find IOffloadConfig service.");
- return false;
- }
-
- // Per the IConfigOffload definition:
- //
- // fd1 A file descriptor bound to the following netlink groups
- // (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY).
- //
- // fd2 A file descriptor bound to the following netlink groups
- // (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
- base::unique_fd
- fd1(conntrackSocket(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY)),
- fd2(conntrackSocket(NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY));
- if (fd1.get() < 0 || fd2.get() < 0) {
- ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
- return false;
- }
-
- hidl_handle h1(handleFromFileDescriptor(std::move(fd1))),
- h2(handleFromFileDescriptor(std::move(fd2)));
-
- bool rval(false);
- hidl_string msg;
- const auto status = configInterface->setHandles(h1, h2,
- [&rval, &msg](bool success, const hidl_string& errMsg) {
- rval = success;
- msg = errMsg;
- });
- if (!status.isOk() || !rval) {
- ALOGE("IOffloadConfig::setHandles() error: '%s' / '%s'",
- status.description().c_str(), msg.c_str());
- // If status is somehow not ok, make sure rval captures this too.
- rval = false;
- }
-
- return rval;
-}
-
static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject javaFd,
jint ifIndex)
{
@@ -229,7 +124,6 @@ static void android_net_util_setupRaSocket(JNIEnv *env, jobject clazz, jobject j
*/
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
- { "configOffload", "()Z", (void*) android_net_util_configOffload },
{ "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_util_setupRaSocket },
};
@@ -242,7 +136,7 @@ int register_android_net_util_TetheringUtils(JNIEnv* env) {
extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("ERROR: GetEnv failed");
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
return JNI_ERR;
}
diff --git a/packages/Tethering/src/android/net/util/TetheringUtils.java b/packages/Tethering/src/android/net/util/TetheringUtils.java
index fa543bdce735..5a6d5c1cbfb0 100644
--- a/packages/Tethering/src/android/net/util/TetheringUtils.java
+++ b/packages/Tethering/src/android/net/util/TetheringUtils.java
@@ -24,14 +24,6 @@ import java.net.SocketException;
* {@hide}
*/
public class TetheringUtils {
-
- /**
- * Offload management process need to know conntrack rules to support NAT, but it may not have
- * permission to create netlink netfilter sockets. Create two netlink netfilter sockets and
- * share them with offload management process.
- */
- public static native boolean configOffload();
-
/**
* Configures a socket for receiving ICMPv6 router solicitations and sending advertisements.
* @param fd the socket's {@link FileDescriptor}.
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
index 90b9d3f148dc..b54571720857 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
@@ -18,19 +18,28 @@ package com.android.server.connectivity.tethering;
import static android.net.util.TetheringUtils.uint16;
+import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.net.netlink.NetlinkSocket;
import android.net.util.SharedLog;
-import android.net.util.TetheringUtils;
+import android.net.util.SocketUtils;
import android.os.Handler;
+import android.os.NativeHandle;
import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
import android.system.OsConstants;
import com.android.internal.annotations.VisibleForTesting;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.net.SocketException;
import java.util.ArrayList;
@@ -49,6 +58,10 @@ public class OffloadHardwareInterface {
private static final String NO_INTERFACE_NAME = "";
private static final String NO_IPV4_ADDRESS = "";
private static final String NO_IPV4_GATEWAY = "";
+ // Reference kernel/uapi/linux/netfilter/nfnetlink_compat.h
+ private static final int NF_NETLINK_CONNTRACK_NEW = 1;
+ private static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
+ private static final int NF_NETLINK_CONNTRACK_DESTROY = 4;
private final Handler mHandler;
private final SharedLog mLog;
@@ -121,9 +134,103 @@ public class OffloadHardwareInterface {
return DEFAULT_TETHER_OFFLOAD_DISABLED;
}
- /** Configure offload management process. */
+ /**
+ * Offload management process need to know conntrack rules to support NAT, but it may not have
+ * permission to create netlink netfilter sockets. Create two netlink netfilter sockets and
+ * share them with offload management process.
+ */
public boolean initOffloadConfig() {
- return TetheringUtils.configOffload();
+ IOffloadConfig offloadConfig;
+ try {
+ offloadConfig = IOffloadConfig.getService();
+ } catch (RemoteException e) {
+ mLog.e("getIOffloadConfig error " + e);
+ return false;
+ }
+ if (offloadConfig == null) {
+ mLog.e("Could not find IOffloadConfig service");
+ return false;
+ }
+ // Per the IConfigOffload definition:
+ //
+ // h1 provides a file descriptor bound to the following netlink groups
+ // (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY).
+ //
+ // h2 provides a file descriptor bound to the following netlink groups
+ // (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
+ final NativeHandle h1 = createConntrackSocket(
+ NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
+ if (h1 == null) return false;
+
+ final NativeHandle h2 = createConntrackSocket(
+ NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
+ if (h2 == null) {
+ closeFdInNativeHandle(h1);
+ return false;
+ }
+
+ final CbResults results = new CbResults();
+ try {
+ offloadConfig.setHandles(h1, h2,
+ (boolean success, String errMsg) -> {
+ results.mSuccess = success;
+ results.mErrMsg = errMsg;
+ });
+ } catch (RemoteException e) {
+ record("initOffloadConfig, setHandles fail", e);
+ return false;
+ }
+ // Explicitly close FDs.
+ closeFdInNativeHandle(h1);
+ closeFdInNativeHandle(h2);
+
+ record("initOffloadConfig, setHandles results:", results);
+ return results.mSuccess;
+ }
+
+ private void closeFdInNativeHandle(final NativeHandle h) {
+ try {
+ h.close();
+ } catch (IOException | IllegalStateException e) {
+ // IllegalStateException means fd is already closed, do nothing here.
+ // Also nothing we can do if IOException.
+ }
+ }
+
+ private NativeHandle createConntrackSocket(final int groups) {
+ FileDescriptor fd;
+ try {
+ fd = NetlinkSocket.forProto(OsConstants.NETLINK_NETFILTER);
+ } catch (ErrnoException e) {
+ mLog.e("Unable to create conntrack socket " + e);
+ return null;
+ }
+
+ final SocketAddress sockAddr = SocketUtils.makeNetlinkSocketAddress(0, groups);
+ try {
+ Os.bind(fd, sockAddr);
+ } catch (ErrnoException | SocketException e) {
+ mLog.e("Unable to bind conntrack socket for groups " + groups + " error: " + e);
+ try {
+ SocketUtils.closeSocket(fd);
+ } catch (IOException ie) {
+ // Nothing we can do here
+ }
+ return null;
+ }
+ try {
+ Os.connect(fd, sockAddr);
+ } catch (ErrnoException | SocketException e) {
+ mLog.e("connect to kernel fail for groups " + groups + " error: " + e);
+ try {
+ SocketUtils.closeSocket(fd);
+ } catch (IOException ie) {
+ // Nothing we can do here
+ }
+ return null;
+ }
+
+ return new NativeHandle(fd, true);
}
/** Initialize the tethering offload HAL. */
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java
index c67fe9ffa916..1e8109cb393c 100644
--- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java
@@ -23,6 +23,8 @@ import android.util.Log;
public class PacNative {
private static final String TAG = "PacProxy";
+ private static final PacNative sInstance = new PacNative();
+
private String mCurrentPac;
private boolean mIsActive;
@@ -39,8 +41,12 @@ public class PacNative {
System.loadLibrary("jni_pacprocessor");
}
- PacNative() {
+ private PacNative() {
+
+ }
+ public static PacNative getInstance() {
+ return sInstance;
}
public synchronized boolean startPacSupport() {
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
index 74391eb676d1..b006d6e1fa7b 100644
--- a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
@@ -31,43 +31,27 @@ import java.net.URL;
public class PacService extends Service {
private static final String TAG = "PacService";
- private PacNative mPacNative;
- private ProxyServiceStub mStub;
+ private PacNative mPacNative = PacNative.getInstance();
+ private ProxyServiceStub mStub = new ProxyServiceStub();
@Override
public void onCreate() {
super.onCreate();
- if (mPacNative == null) {
- mPacNative = new PacNative();
- mStub = new ProxyServiceStub(mPacNative);
- }
+ mPacNative.startPacSupport();
}
@Override
public void onDestroy() {
+ mPacNative.stopPacSupport();
super.onDestroy();
- if (mPacNative != null) {
- mPacNative.stopPacSupport();
- mPacNative = null;
- mStub = null;
- }
}
@Override
public IBinder onBind(Intent intent) {
- if (mPacNative == null) {
- mPacNative = new PacNative();
- mStub = new ProxyServiceStub(mPacNative);
- }
return mStub;
}
- private static class ProxyServiceStub extends IProxyService.Stub {
- private final PacNative mPacNative;
-
- public ProxyServiceStub(PacNative pacNative) {
- mPacNative = pacNative;
- }
+ private class ProxyServiceStub extends IProxyService.Stub {
@Override
public String resolvePacFile(String host, String url) throws RemoteException {
@@ -102,20 +86,12 @@ public class PacService extends Service {
@Override
public void startPacSystem() throws RemoteException {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- Log.e(TAG, "Only system user is allowed to call startPacSystem");
- throw new SecurityException();
- }
- mPacNative.startPacSupport();
+ //TODO: remove
}
@Override
public void stopPacSystem() throws RemoteException {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- Log.e(TAG, "Only system user is allowed to call stopPacSystem");
- throw new SecurityException();
- }
- mPacNative.stopPacSupport();
+ //TODO: remove
}
}
}
diff --git a/services/Android.bp b/services/Android.bp
index 32394f4fe5d9..416f448a965f 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -30,6 +30,7 @@ filegroup {
":services.usb-sources",
":services.voiceinteraction-sources",
":service-permission-sources",
+ ":service-statsd-sources",
],
visibility: ["//visibility:private"],
}
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
new file mode 100644
index 000000000000..58c2707a1f19
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2020 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.server.media;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ComponentInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Holds the media button receiver, and also provides helper methods around it.
+ */
+final class MediaButtonReceiverHolder {
+ public static final int COMPONENT_TYPE_INVALID = 0;
+ public static final int COMPONENT_TYPE_BROADCAST = 1;
+ public static final int COMPONENT_TYPE_ACTIVITY = 2;
+ public static final int COMPONENT_TYPE_SERVICE = 3;
+
+ @IntDef(value = {
+ COMPONENT_TYPE_INVALID,
+ COMPONENT_TYPE_BROADCAST,
+ COMPONENT_TYPE_ACTIVITY,
+ COMPONENT_TYPE_SERVICE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ComponentType {}
+
+ private static final String TAG = "PendingIntentHolder";
+ private static final boolean DEBUG_KEY_EVENT = MediaSessionService.DEBUG_KEY_EVENT;
+ private static final String COMPONENT_NAME_USER_ID_DELIM = ",";
+
+ private final int mUserId;
+ private final PendingIntent mPendingIntent;
+ private final ComponentName mComponentName;
+ private final String mPackageName;
+ @ComponentType
+ private final int mComponentType;
+
+ /**
+ * Unflatten from string which is previously flattened string via flattenToString().
+ * <p>
+ * It's used to store and restore media button receiver across the boot, by keeping the intent's
+ * component name to the persistent storage.
+ *
+ * @param mediaButtonReceiverInfo previously flattened string via flattenToString()
+ * @return new instance if the string was valid. {@code null} otherwise.
+ */
+ public static MediaButtonReceiverHolder unflattenFromString(
+ Context context, String mediaButtonReceiverInfo) {
+ if (TextUtils.isEmpty(mediaButtonReceiverInfo)) {
+ return null;
+ }
+ String[] tokens = mediaButtonReceiverInfo.split(COMPONENT_NAME_USER_ID_DELIM);
+ if (tokens == null || (tokens.length != 2 && tokens.length != 3)) {
+ return null;
+ }
+ ComponentName componentName = ComponentName.unflattenFromString(tokens[0]);
+ int userId = Integer.parseInt(tokens[1]);
+ // Guess component type if the OS version is updated from the older version.
+ int componentType = (tokens.length == 3)
+ ? Integer.parseInt(tokens[2])
+ : getComponentType(context, componentName);
+ return new MediaButtonReceiverHolder(userId, null, componentName, componentType);
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param context context
+ * @param userId userId
+ * @param pendingIntent pending intent
+ * @return Can be {@code null} if pending intent was null.
+ */
+ public static MediaButtonReceiverHolder create(Context context, int userId,
+ PendingIntent pendingIntent) {
+ if (pendingIntent == null) {
+ return null;
+ }
+ ComponentName componentName = (pendingIntent != null && pendingIntent.getIntent() != null)
+ ? pendingIntent.getIntent().getComponent() : null;
+ if (componentName != null) {
+ // Explicit intent, where component name is in the PendingIntent.
+ return new MediaButtonReceiverHolder(userId, pendingIntent, componentName,
+ getComponentType(context, componentName));
+ }
+
+ // Implicit intent, where component name isn't in the PendingIntent. Try resolve.
+ PackageManager pm = context.getPackageManager();
+ Intent intent = pendingIntent.getIntent();
+ if ((componentName = resolveImplicitServiceIntent(pm, intent)) != null) {
+ return new MediaButtonReceiverHolder(
+ userId, pendingIntent, componentName, COMPONENT_TYPE_SERVICE);
+ } else if ((componentName = resolveManifestDeclaredBroadcastReceiverIntent(pm, intent))
+ != null) {
+ return new MediaButtonReceiverHolder(
+ userId, pendingIntent, componentName, COMPONENT_TYPE_BROADCAST);
+ } else if ((componentName = resolveImplicitActivityIntent(pm, intent)) != null) {
+ return new MediaButtonReceiverHolder(
+ userId, pendingIntent, componentName, COMPONENT_TYPE_ACTIVITY);
+ }
+
+ // Failed to resolve target component for the pending intent. It's unlikely to be usable.
+ // However, the pending intent would be still used, just to follow the legacy behavior.
+ Log.w(TAG, "Unresolvable implicit intent is set, pi=" + pendingIntent);
+ String packageName = (pendingIntent != null && pendingIntent.getIntent() != null)
+ ? pendingIntent.getIntent().getPackage() : null;
+ return new MediaButtonReceiverHolder(userId, pendingIntent,
+ packageName != null ? packageName : "");
+ }
+
+ private MediaButtonReceiverHolder(int userId, PendingIntent pendingIntent,
+ ComponentName componentName, @ComponentType int componentType) {
+ mUserId = userId;
+ mPendingIntent = pendingIntent;
+ mComponentName = componentName;
+ mPackageName = componentName.getPackageName();
+ mComponentType = componentType;
+ }
+
+ private MediaButtonReceiverHolder(int userId, PendingIntent pendingIntent, String packageName) {
+ mUserId = userId;
+ mPendingIntent = pendingIntent;
+ mComponentName = null;
+ mPackageName = packageName;
+ mComponentType = COMPONENT_TYPE_INVALID;
+ }
+
+ /**
+ * @return the user id
+ */
+ public int getUserId() {
+ return mUserId;
+ }
+
+ /**
+ * @return package name that the media button receiver would be sent to.
+ */
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /**
+ * Sends the media key event to the media button receiver.
+ * <p>
+ * This prioritizes using use pending intent for sending media key event.
+ *
+ * @param context context to be used to call PendingIntent#send
+ * @param keyEvent keyEvent to send
+ * @param resultCode result code to be used to call PendingIntent#send
+ * Ignored if there's no valid pending intent.
+ * @param onFinishedListener callback to be used to get result of PendingIntent#send.
+ * Ignored if there's no valid pending intent.
+ * @param handler handler to be used to call onFinishedListener
+ * Ignored if there's no valid pending intent.
+ * @see PendingIntent#send(Context, int, Intent, PendingIntent.OnFinished, Handler)
+ */
+ public boolean send(Context context, KeyEvent keyEvent, String callingPackageName,
+ int resultCode, PendingIntent.OnFinished onFinishedListener, Handler handler) {
+ Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ mediaButtonIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+ // TODO: Find a way to also send PID/UID in secure way.
+ mediaButtonIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, callingPackageName);
+
+ if (mPendingIntent != null) {
+ if (DEBUG_KEY_EVENT) {
+ Log.d(TAG, "Sending " + keyEvent + " to the last known PendingIntent "
+ + mPendingIntent);
+ }
+ try {
+ mPendingIntent.send(
+ context, resultCode, mediaButtonIntent, onFinishedListener, handler);
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "Error sending key event to media button receiver " + mPendingIntent, e);
+ return false;
+ }
+ } else if (mComponentName != null) {
+ if (DEBUG_KEY_EVENT) {
+ Log.d(TAG, "Sending " + keyEvent + " to the restored intent "
+ + mComponentName + ", type=" + mComponentType);
+ }
+ mediaButtonIntent.setComponent(mComponentName);
+ UserHandle userHandle = UserHandle.of(mUserId);
+ try {
+ switch (mComponentType) {
+ case COMPONENT_TYPE_ACTIVITY:
+ context.startActivityAsUser(mediaButtonIntent, userHandle);
+ break;
+ case COMPONENT_TYPE_SERVICE:
+ context.startForegroundServiceAsUser(mediaButtonIntent,
+ userHandle);
+ break;
+ default:
+ // Legacy behavior for other cases.
+ context.sendBroadcastAsUser(mediaButtonIntent, userHandle);
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Error sending media button to the restored intent "
+ + mComponentName + ", type=" + mComponentType, e);
+ return false;
+ }
+ } else {
+ // Leave log, just in case.
+ Log.e(TAG, "Shouldn't be happen -- pending intent or component name must be set");
+ return false;
+ }
+ return true;
+ }
+
+
+ @Override
+ public String toString() {
+ if (mPendingIntent != null) {
+ return "MBR {pi=" + mPendingIntent + ", type=" + mComponentType + "}";
+ }
+ return "Restored MBR {component=" + mComponentName + ", type=" + mComponentType + "}";
+ }
+
+ /**
+ * @return flattened string. Can be empty string if the MBR is created with implicit intent.
+ */
+ public String flattenToString() {
+ if (mComponentName == null) {
+ // We don't know which component would receive the key event.
+ return "";
+ }
+ return String.join(COMPONENT_NAME_USER_ID_DELIM,
+ mComponentName.toString(),
+ String.valueOf(mUserId),
+ String.valueOf(mComponentType));
+ }
+
+ /**
+ * Gets the type of the component
+ *
+ * @param context context
+ * @param componentName component name
+ * @return A component type
+ */
+ @ComponentType
+ private static int getComponentType(Context context, ComponentName componentName) {
+ if (componentName == null) {
+ return COMPONENT_TYPE_INVALID;
+ }
+ PackageManager pm = context.getPackageManager();
+ try {
+ ActivityInfo activityInfo = pm.getActivityInfo(componentName,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.GET_ACTIVITIES);
+ if (activityInfo != null) {
+ return COMPONENT_TYPE_ACTIVITY;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ try {
+ ServiceInfo serviceInfo = pm.getServiceInfo(componentName,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.GET_SERVICES);
+ if (serviceInfo != null) {
+ return COMPONENT_TYPE_SERVICE;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ // Pick legacy behavior for BroadcastReceiver or unknown.
+ return COMPONENT_TYPE_BROADCAST;
+ }
+
+ private static ComponentName resolveImplicitServiceIntent(PackageManager pm, Intent intent) {
+ // Flag explanations.
+ // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE:
+ // filter apps regardless of the phone's locked/unlocked state.
+ // - GET_SERVICES: Return service
+ return createComponentName(pm.resolveService(intent,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.GET_SERVICES));
+ }
+
+ private static ComponentName resolveManifestDeclaredBroadcastReceiverIntent(
+ PackageManager pm, Intent intent) {
+ // Flag explanations.
+ // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE:
+ // filter apps regardless of the phone's locked/unlocked state.
+ List<ResolveInfo> resolveInfos = pm.queryBroadcastReceivers(intent,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+ return (resolveInfos != null && !resolveInfos.isEmpty())
+ ? createComponentName(resolveInfos.get(0)) : null;
+ }
+
+ private static ComponentName resolveImplicitActivityIntent(PackageManager pm, Intent intent) {
+ // Flag explanations.
+ // - MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE:
+ // Filter apps regardless of the phone's locked/unlocked state.
+ // - MATCH_DEFAULT_ONLY:
+ // Implicit intent receiver should be set as default. Only needed for activity.
+ // - GET_ACTIVITIES: Return activity
+ return createComponentName(pm.resolveActivity(intent,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DEFAULT_ONLY
+ | PackageManager.GET_ACTIVITIES));
+ }
+
+ private static ComponentName createComponentName(ResolveInfo resolveInfo) {
+ if (resolveInfo == null) {
+ return null;
+ }
+ ComponentInfo componentInfo;
+ // Code borrowed from ResolveInfo#getComponentInfo().
+ if (resolveInfo.activityInfo != null) {
+ componentInfo = resolveInfo.activityInfo;
+ } else if (resolveInfo.serviceInfo != null) {
+ componentInfo = resolveInfo.serviceInfo;
+ } else {
+ // We're not interested in content provider.
+ return null;
+ }
+ // Code borrowed from ComponentInfo#getComponentName().
+ try {
+ return new ComponentName(componentInfo.packageName, componentInfo.name);
+ } catch (IllegalArgumentException | NullPointerException e) {
+ // This may be happen if resolveActivity() end up with matching multiple activities.
+ // see PackageManager#resolveActivity().
+ return null;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
index d08fb71d3dee..dd536ecd19fa 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -411,6 +411,12 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
mActiveConnection.dispose();
mActiveConnection = null;
setAndNotifyProviderState(null);
+ synchronized (mLock) {
+ for (RoutingSessionInfo sessionInfo : mSessionInfos) {
+ mCallback.onSessionReleased(this, sessionInfo);
+ }
+ mSessionInfos.clear();
+ }
}
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 7bcbcd4a3d09..9f47b349d3fc 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -127,7 +127,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
new ArrayList<>();
private long mFlags;
- private PendingIntent mMediaButtonReceiver;
+ private MediaButtonReceiverHolder mMediaButtonReceiverHolder;
private PendingIntent mLaunchIntent;
// TransportPerformer fields
@@ -220,8 +220,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
*
* @return The pending intent set by the app or null.
*/
- public PendingIntent getMediaButtonReceiver() {
- return mMediaButtonReceiver;
+ public MediaButtonReceiverHolder getMediaButtonReceiver() {
+ return mMediaButtonReceiverHolder;
}
/**
@@ -471,7 +471,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
+ ", userId=" + mUserId);
pw.println(indent + "package=" + mPackageName);
pw.println(indent + "launchIntent=" + mLaunchIntent);
- pw.println(indent + "mediaButtonReceiver=" + mMediaButtonReceiver);
+ pw.println(indent + "mediaButtonReceiver=" + mMediaButtonReceiverHolder);
pw.println(indent + "active=" + mIsActive);
pw.println(indent + "flags=" + mFlags);
pw.println(indent + "rating type=" + mRatingType);
@@ -833,12 +833,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
@Override
public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
- if ((mPolicies & SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) == 1) {
- return;
- }
- mMediaButtonReceiver = pi;
final long token = Binder.clearCallingIdentity();
try {
+ if ((mPolicies & SessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
+ != 0) {
+ return;
+ }
+ mMediaButtonReceiverHolder =
+ MediaButtonReceiverHolder.create(mContext, mUserId, pi);
mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
} finally {
Binder.restoreCallingIdentity(token);
@@ -1529,5 +1531,4 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
msg.sendToTarget();
}
}
-
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 88b884efce83..7ffac062b7f5 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -18,22 +18,17 @@ package com.android.server.media;
import static android.os.UserHandle.USER_ALL;
-import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.INotificationManager;
import android.app.KeyguardManager;
import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
-import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.media.AudioManager;
@@ -99,7 +94,7 @@ public class MediaSessionService extends SystemService implements Monitor {
private static final String TAG = "MediaSessionService";
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
// Leave log for key event always.
- private static final boolean DEBUG_KEY_EVENT = true;
+ static final boolean DEBUG_KEY_EVENT = true;
private static final int WAKELOCK_TIMEOUT = 5000;
private static final int MEDIA_KEY_LISTENER_TIMEOUT = 1000;
@@ -760,12 +755,6 @@ public class MediaSessionService extends SystemService implements Monitor {
* <p>The contents of this object is guarded by {@link #mLock}.
*/
final class FullUserRecord implements MediaSessionStack.OnMediaButtonSessionChangedListener {
- public static final int COMPONENT_TYPE_INVALID = 0;
- public static final int COMPONENT_TYPE_BROADCAST = 1;
- public static final int COMPONENT_TYPE_ACTIVITY = 2;
- public static final int COMPONENT_TYPE_SERVICE = 3;
- private static final String COMPONENT_NAME_USER_ID_DELIM = ",";
-
private final int mFullUserId;
private final MediaSessionStack mPriorityStack;
private final HashMap<IBinder, OnMediaKeyEventDispatchedListenerRecord>
@@ -774,10 +763,7 @@ public class MediaSessionService extends SystemService implements Monitor {
mOnMediaKeyEventSessionChangedListeners = new HashMap<>();
private final SparseIntArray mUidToSessionCount = new SparseIntArray();
- private PendingIntent mLastMediaButtonReceiver;
- private ComponentName mRestoredMediaButtonReceiver;
- private int mRestoredMediaButtonReceiverComponentType;
- private int mRestoredMediaButtonReceiverUserId;
+ private MediaButtonReceiverHolder mLastMediaButtonReceiverHolder;
private IOnVolumeKeyLongPressListener mOnVolumeKeyLongPressListener;
private int mOnVolumeKeyLongPressListenerUid;
@@ -794,21 +780,9 @@ public class MediaSessionService extends SystemService implements Monitor {
// Restore the remembered media button receiver before the boot.
String mediaButtonReceiverInfo = Settings.Secure.getStringForUser(mContentResolver,
Settings.System.MEDIA_BUTTON_RECEIVER, mFullUserId);
- if (mediaButtonReceiverInfo == null) {
- return;
- }
- String[] tokens = mediaButtonReceiverInfo.split(COMPONENT_NAME_USER_ID_DELIM);
- if (tokens == null || (tokens.length != 2 && tokens.length != 3)) {
- return;
- }
- mRestoredMediaButtonReceiver = ComponentName.unflattenFromString(tokens[0]);
- mRestoredMediaButtonReceiverUserId = Integer.parseInt(tokens[1]);
- if (tokens.length == 3) {
- mRestoredMediaButtonReceiverComponentType = Integer.parseInt(tokens[2]);
- } else {
- mRestoredMediaButtonReceiverComponentType =
- getComponentType(mRestoredMediaButtonReceiver);
- }
+ mLastMediaButtonReceiverHolder =
+ MediaButtonReceiverHolder.unflattenFromString(
+ mContext, mediaButtonReceiverInfo);
}
public void destroySessionsForUserLocked(int userId) {
@@ -892,10 +866,7 @@ public class MediaSessionService extends SystemService implements Monitor {
: mOnMediaKeyEventSessionChangedListeners.values()) {
pw.println(indent + " from " + getCallingPackageName(cr.uid));
}
- pw.println(indent + "Last MediaButtonReceiver: " + mLastMediaButtonReceiver);
- pw.println(indent + "Restored MediaButtonReceiver: " + mRestoredMediaButtonReceiver);
- pw.println(indent + "Restored MediaButtonReceiverComponentType: "
- + mRestoredMediaButtonReceiverComponentType);
+ pw.println(indent + "Last MediaButtonReceiver: " + mLastMediaButtonReceiverHolder);
mPriorityStack.dump(pw, indent);
}
@@ -924,25 +895,12 @@ public class MediaSessionService extends SystemService implements Monitor {
return;
}
MediaSessionRecord sessionRecord = (MediaSessionRecord) record;
- PendingIntent receiver = sessionRecord.getMediaButtonReceiver();
- mLastMediaButtonReceiver = receiver;
- mRestoredMediaButtonReceiver = null;
- mRestoredMediaButtonReceiverComponentType = COMPONENT_TYPE_INVALID;
-
- String mediaButtonReceiverInfo = "";
- if (receiver != null) {
- ComponentName component = receiver.getIntent().getComponent();
- if (component != null
- && record.getPackageName().equals(component.getPackageName())) {
- String componentName = component.flattenToString();
- int componentType = getComponentType(component);
- mediaButtonReceiverInfo = String.join(COMPONENT_NAME_USER_ID_DELIM,
- componentName, String.valueOf(record.getUserId()),
- String.valueOf(componentType));
- }
- }
+ mLastMediaButtonReceiverHolder = sessionRecord.getMediaButtonReceiver();
+ String mediaButtonReceiverInfo = (mLastMediaButtonReceiverHolder == null)
+ ? "" : mLastMediaButtonReceiverHolder.flattenToString();
Settings.Secure.putStringForUser(mContentResolver,
- Settings.System.MEDIA_BUTTON_RECEIVER, mediaButtonReceiverInfo,
+ Settings.System.MEDIA_BUTTON_RECEIVER,
+ mediaButtonReceiverInfo,
mFullUserId);
}
@@ -958,15 +916,9 @@ public class MediaSessionService extends SystemService implements Monitor {
} else {
// TODO(jaewan): Implement
}
- } else if (mCurrentFullUserRecord.mLastMediaButtonReceiver != null) {
- callback.onMediaKeyEventSessionChanged(
- mCurrentFullUserRecord.mLastMediaButtonReceiver
- .getIntent().getComponent().getPackageName(),
- null);
- } else if (mCurrentFullUserRecord.mRestoredMediaButtonReceiver != null) {
- callback.onMediaKeyEventSessionChanged(
- mCurrentFullUserRecord.mRestoredMediaButtonReceiver.getPackageName(),
- null);
+ } else if (mCurrentFullUserRecord.mLastMediaButtonReceiverHolder != null) {
+ String packageName = mLastMediaButtonReceiverHolder.getPackageName();
+ callback.onMediaKeyEventSessionChanged(packageName, null);
}
} catch (RemoteException e) {
Log.w(TAG, "Failed to pushAddressedPlayerChangedLocked", e);
@@ -985,35 +937,6 @@ public class MediaSessionService extends SystemService implements Monitor {
? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession();
}
- private int getComponentType(@Nullable ComponentName componentName) {
- if (componentName == null) {
- return COMPONENT_TYPE_INVALID;
- }
- PackageManager pm = mContext.getPackageManager();
- try {
- ActivityInfo activityInfo = pm.getActivityInfo(componentName,
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.GET_ACTIVITIES);
- if (activityInfo != null) {
- return COMPONENT_TYPE_ACTIVITY;
- }
- } catch (NameNotFoundException e) {
- }
- try {
- ServiceInfo serviceInfo = pm.getServiceInfo(componentName,
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.GET_SERVICES);
- if (serviceInfo != null) {
- return COMPONENT_TYPE_SERVICE;
- }
- } catch (NameNotFoundException e) {
- }
- // Pick legacy behavior for BroadcastReceiver or unknown.
- return COMPONENT_TYPE_BROADCAST;
- }
-
final class OnMediaKeyEventDispatchedListenerRecord implements IBinder.DeathRecipient {
public final IOnMediaKeyEventDispatchedListener callback;
public final int uid;
@@ -2166,79 +2089,31 @@ public class MediaSessionService extends SystemService implements Monitor {
} catch (RemoteException e) {
Log.w(TAG, "Failed to send callback", e);
}
- } else if (mCurrentFullUserRecord.mLastMediaButtonReceiver != null
- || mCurrentFullUserRecord.mRestoredMediaButtonReceiver != null) {
+ } else if (mCurrentFullUserRecord.mLastMediaButtonReceiverHolder != null) {
if (needWakeLock) {
mKeyEventReceiver.acquireWakeLockLocked();
}
- Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
- mediaButtonIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
- // TODO: Find a way to also send PID/UID in secure way.
- String callerPackageName =
+ String callingPackageName =
(asSystemService) ? mContext.getPackageName() : packageName;
- mediaButtonIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, callerPackageName);
- try {
- if (mCurrentFullUserRecord.mLastMediaButtonReceiver != null) {
- PendingIntent receiver = mCurrentFullUserRecord.mLastMediaButtonReceiver;
- if (DEBUG_KEY_EVENT) {
- Log.d(TAG, "Sending " + keyEvent
- + " to the last known PendingIntent " + receiver);
- }
- receiver.send(mContext,
- needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
- mediaButtonIntent, mKeyEventReceiver, mHandler);
- ComponentName componentName = mCurrentFullUserRecord
- .mLastMediaButtonReceiver.getIntent().getComponent();
- if (componentName != null) {
- for (FullUserRecord.OnMediaKeyEventDispatchedListenerRecord cr
- : mCurrentFullUserRecord
- .mOnMediaKeyEventDispatchedListeners.values()) {
- cr.callback.onMediaKeyEventDispatched(keyEvent,
- componentName.getPackageName(), null);
- }
- }
- } else {
- ComponentName receiver =
- mCurrentFullUserRecord.mRestoredMediaButtonReceiver;
- int componentType = mCurrentFullUserRecord
- .mRestoredMediaButtonReceiverComponentType;
- UserHandle userHandle = UserHandle.of(mCurrentFullUserRecord
- .mRestoredMediaButtonReceiverUserId);
- if (DEBUG_KEY_EVENT) {
- Log.d(TAG, "Sending " + keyEvent + " to the restored intent "
- + receiver + ", type=" + componentType);
- }
- mediaButtonIntent.setComponent(receiver);
+
+ MediaButtonReceiverHolder mediaButtonReceiverHolder =
+ mCurrentFullUserRecord.mLastMediaButtonReceiverHolder;
+
+ boolean sent = mediaButtonReceiverHolder.send(
+ mContext, keyEvent, callingPackageName,
+ needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1, mKeyEventReceiver,
+ mHandler);
+ if (sent) {
+ String pkgName = mediaButtonReceiverHolder.getPackageName();
+ for (FullUserRecord.OnMediaKeyEventDispatchedListenerRecord cr
+ : mCurrentFullUserRecord
+ .mOnMediaKeyEventDispatchedListeners.values()) {
try {
- switch (componentType) {
- case FullUserRecord.COMPONENT_TYPE_ACTIVITY:
- mContext.startActivityAsUser(mediaButtonIntent, userHandle);
- break;
- case FullUserRecord.COMPONENT_TYPE_SERVICE:
- mContext.startForegroundServiceAsUser(mediaButtonIntent,
- userHandle);
- break;
- default:
- // Legacy behavior for other cases.
- mContext.sendBroadcastAsUser(mediaButtonIntent, userHandle);
- }
- } catch (Exception e) {
- Log.w(TAG, "Error sending media button to the restored intent "
- + receiver + ", type=" + componentType, e);
- }
- for (FullUserRecord.OnMediaKeyEventDispatchedListenerRecord cr
- : mCurrentFullUserRecord
- .mOnMediaKeyEventDispatchedListeners.values()) {
- cr.callback.onMediaKeyEventDispatched(keyEvent,
- receiver.getPackageName(), null);
+ cr.callback.onMediaKeyEventDispatched(keyEvent, pkgName, null);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed notify key event dispatch, uid=" + cr.uid, e);
}
}
- } catch (CanceledException e) {
- Log.i(TAG, "Error sending key event to media button receiver "
- + mCurrentFullUserRecord.mLastMediaButtonReceiver, e);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to send callback", e);
}
}
}
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 8c13b5bf8519..d629b547992b 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -33,7 +33,6 @@ import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo;
import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
import android.content.pm.parsing.ComponentParseUtils.ParsedService;
-import android.net.Uri;
import android.os.Binder;
import android.os.Process;
import android.os.Trace;
@@ -87,10 +86,10 @@ public class AppsFilter {
private final SparseSetArray<Integer> mQueriesViaPackage = new SparseSetArray<>();
/**
- * A mapping from the set of App IDs that query others via intent to the list
- * of packages that the intents resolve to.
+ * A mapping from the set of App IDs that query others via component match to the list
+ * of packages that the they resolve to.
*/
- private final SparseSetArray<Integer> mQueriesViaIntent = new SparseSetArray<>();
+ private final SparseSetArray<Integer> mQueriesViaComponent = new SparseSetArray<>();
/**
* A set of App IDs that are always queryable by any package, regardless of their manifest
@@ -206,16 +205,19 @@ public class AppsFilter {
}
/** Returns true if the querying package may query for the potential target package */
- private static boolean canQueryViaIntent(AndroidPackage querying,
+ private static boolean canQueryViaComponents(AndroidPackage querying,
AndroidPackage potentialTarget) {
- if (querying.getQueriesIntents() == null) {
- return false;
- }
- for (Intent intent : querying.getQueriesIntents()) {
- if (matches(intent, potentialTarget)) {
- return true;
+ if (querying.getQueriesIntents() != null) {
+ for (Intent intent : querying.getQueriesIntents()) {
+ if (matchesIntentFilters(intent, potentialTarget)) {
+ return true;
+ }
}
}
+ if (querying.getQueriesProviders() != null
+ && matchesProviders(querying.getQueriesProviders(), potentialTarget)) {
+ return true;
+ }
return false;
}
@@ -238,24 +240,25 @@ public class AppsFilter {
return false;
}
- private static boolean matches(Intent intent, AndroidPackage potentialTarget) {
+ private static boolean matchesProviders(
+ Set<String> queriesAuthorities, AndroidPackage potentialTarget) {
for (int p = ArrayUtils.size(potentialTarget.getProviders()) - 1; p >= 0; p--) {
ParsedProvider provider = potentialTarget.getProviders().get(p);
if (!provider.isExported()) {
continue;
}
- final Uri data = intent.getData();
- if (!"content".equalsIgnoreCase(intent.getScheme()) || data == null
- || provider.getAuthority() == null) {
- continue;
- }
- StringTokenizer authorities = new StringTokenizer(provider.getAuthority(), ";", false);
+ StringTokenizer authorities = new StringTokenizer(provider.getAuthority(), ";",
+ false);
while (authorities.hasMoreElements()) {
- if (Objects.equals(authorities.nextElement(), data.getAuthority())) {
+ if (queriesAuthorities.contains(authorities.nextToken())) {
return true;
}
}
}
+ return false;
+ }
+
+ private static boolean matchesIntentFilters(Intent intent, AndroidPackage potentialTarget) {
for (int s = ArrayUtils.size(potentialTarget.getServices()) - 1; s >= 0; s--) {
ParsedService service = potentialTarget.getServices().get(s);
if (!service.exported) {
@@ -368,8 +371,8 @@ public class AppsFilter {
final AndroidPackage existingPkg = existingSetting.pkg;
// let's evaluate the ability of already added packages to see this new package
if (!newIsForceQueryable) {
- if (canQueryViaIntent(existingPkg, newPkg)) {
- mQueriesViaIntent.add(existingSetting.appId, newPkgSetting.appId);
+ if (canQueryViaComponents(existingPkg, newPkg)) {
+ mQueriesViaComponent.add(existingSetting.appId, newPkgSetting.appId);
}
if (canQueryViaPackage(existingPkg, newPkg)
|| canQueryAsInstaller(existingSetting, newPkg)) {
@@ -378,8 +381,8 @@ public class AppsFilter {
}
// now we'll evaluate our new package's ability to see existing packages
if (!mForceQueryable.contains(existingSetting.appId)) {
- if (canQueryViaIntent(newPkg, existingPkg)) {
- mQueriesViaIntent.add(newPkgSetting.appId, existingSetting.appId);
+ if (canQueryViaComponents(newPkg, existingPkg)) {
+ mQueriesViaComponent.add(newPkgSetting.appId, existingSetting.appId);
}
if (canQueryViaPackage(newPkg, existingPkg)
|| canQueryAsInstaller(newPkgSetting, existingPkg)) {
@@ -427,9 +430,9 @@ public class AppsFilter {
}
}
- mQueriesViaIntent.remove(setting.appId);
- for (int i = mQueriesViaIntent.size() - 1; i >= 0; i--) {
- mQueriesViaIntent.remove(mQueriesViaIntent.keyAt(i), setting.appId);
+ mQueriesViaComponent.remove(setting.appId);
+ for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) {
+ mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.appId);
}
mQueriesViaPackage.remove(setting.appId);
for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
@@ -594,10 +597,10 @@ public class AppsFilter {
Trace.endSection();
}
try {
- Trace.beginSection("mQueriesViaIntent");
- if (mQueriesViaIntent.contains(callingAppId, targetAppId)) {
+ Trace.beginSection("mQueriesViaComponent");
+ if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries intent");
+ log(callingSetting, targetPkgSetting, "queries component");
}
return false;
}
@@ -732,7 +735,7 @@ public class AppsFilter {
pw.println(" queries via package name:");
dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages);
pw.println(" queries via intent:");
- dumpQueriesMap(pw, filteringAppId, mQueriesViaIntent, " ", expandPackages);
+ dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages);
pw.println(" queryable via interaction:");
for (int user : users) {
pw.append(" User ").append(Integer.toString(user)).println(":");
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index e77839c4e5b5..524ae54972e5 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -224,6 +224,13 @@ public class AppDataRollbackHelper {
}
/**
+ * Deletes all device-encrypted apex data snapshots for the given rollback id.
+ */
+ public void destroyApexDeSnapshots(int rollbackId) {
+ mApexManager.destroyDeSnapshots(rollbackId);
+ }
+
+ /**
* Commits the pending backups and restores for a given {@code userId} and {@code rollback}. If
* the rollback has a pending backup, it is updated with a mapping from {@code userId} to inode
* of the CE user data snapshot.
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index b5da1c2ec58a..5abd9f0698d3 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -44,7 +44,6 @@ import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.pm.ApexManager;
import java.io.File;
import java.io.IOException;
@@ -671,7 +670,7 @@ class Rollback {
}
}
if (containsApex) {
- ApexManager.getInstance().destroyDeSnapshots(info.getRollbackId());
+ dataHelper.destroyApexDeSnapshots(info.getRollbackId());
}
RollbackStore.deleteRollback(this);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index 8c54fa95e04b..88de34027bb9 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -87,11 +87,15 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
private static final long SYSTEM_CLOCK_PARANOIA_THRESHOLD_MILLIS = 2 * 1000;
/**
- * The number of previous telephony suggestions to keep for each ID (for use during debugging).
+ * The number of suggestions to keep. These are logged in bug reports to assist when debugging
+ * issues with detection.
*/
- private static final int KEEP_SUGGESTION_HISTORY_SIZE = 30;
+ private static final int KEEP_SUGGESTION_HISTORY_SIZE = 10;
- // A log for changes made to the system clock and why.
+ /**
+ * A log that records the decisions / decision metadata that affected the device's system clock
+ * time. This is logged in bug reports to assist with debugging issues with detection.
+ */
@NonNull
private final LocalLog mTimeChangesLog = new LocalLog(30, false /* useLocalTimestamps */);
@@ -140,7 +144,18 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
if (!validateSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) {
return;
}
- mLastNetworkSuggestion.set(timeSuggestion);
+
+ // The caller submits suggestions with the best available information when there are network
+ // changes. The best available information may have been cached and if they were all stored
+ // this would lead to duplicates showing up in the suggestion history. The suggestions may
+ // be made for different reasons but there is not a significant benefit to storing the same
+ // suggestion information again. doAutoTimeDetection() should still be called: this ensures
+ // the suggestion and device state are always re-evaluated, which might produce a different
+ // detected time if, for example, the age of all suggestions are considered.
+ NetworkTimeSuggestion lastNetworkSuggestion = mLastNetworkSuggestion.get();
+ if (lastNetworkSuggestion == null || !lastNetworkSuggestion.equals(timeSuggestion)) {
+ mLastNetworkSuggestion.set(timeSuggestion);
+ }
// Now perform auto time detection. The new suggestion may be used to modify the system
// clock.
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index 652dbe153680..cc33fb0f5008 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -161,16 +161,17 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
public static final int TELEPHONY_SCORE_USAGE_THRESHOLD = TELEPHONY_SCORE_MEDIUM;
/**
- * The number of previous telephony suggestions to keep for each ID (for use during debugging).
+ * The number of suggestions to keep. These are logged in bug reports to assist when debugging
+ * issues with detection.
*/
- private static final int KEEP_TELEPHONY_SUGGESTION_HISTORY_SIZE = 30;
+ private static final int KEEP_SUGGESTION_HISTORY_SIZE = 10;
@NonNull
private final Callback mCallback;
/**
- * A log that records the decisions / decision metadata that affected the device's time zone
- * (for use during debugging).
+ * A log that records the decisions / decision metadata that affected the device's time zone.
+ * This is logged in bug reports to assist with debugging issues with detection.
*/
@NonNull
private final LocalLog mTimeZoneChangesLog = new LocalLog(30, false /* useLocalTimestamps */);
@@ -182,8 +183,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
*/
@GuardedBy("this")
private ArrayMapWithHistory<Integer, QualifiedTelephonyTimeZoneSuggestion>
- mSuggestionBySlotIndex =
- new ArrayMapWithHistory<>(KEEP_TELEPHONY_SUGGESTION_HISTORY_SIZE);
+ mSuggestionBySlotIndex = new ArrayMapWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
/**
* Creates a new instance of {@link TimeZoneDetectorStrategyImpl}.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2fdcbc9083f6..2196d899406d 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -3323,6 +3323,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* @return {@code true} if the top activity looks like it belongs to {@param userId}.
*/
private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
+ // TODO(b/80414790): having utilities to loop for all leaf tasks from caller vs. checking
+ // leaf tasks here.
+ if (!task.isLeafTask()) {
+ // No op if not a leaf task since we don't want to report root tasks to
+ // TaskStackListeners.
+ return;
+ }
+
// To handle the case that work app is in the task but just is not the top one.
final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 0e500f9a25c0..9fb8e2f4e3da 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1431,18 +1431,27 @@ class Task extends WindowContainer<WindowContainer> {
}
/**
- * @return whether or not there are ONLY task overlay activities in the stack.
+ * @return whether or not there are ONLY task overlay activities in the task.
* If {@param includeFinishing} is set, then don't ignore finishing activities in the
* check. If there are no task overlay activities, this call returns false.
*/
boolean onlyHasTaskOverlayActivities(boolean includeFinishing) {
- if (getChildCount() == 0) {
- return false;
- }
- if (includeFinishing) {
- return getActivity((r) -> r.isTaskOverlay()) != null;
+ int count = 0;
+ for (int i = getChildCount() - 1; i >= 0; i--) {
+ final ActivityRecord r = getChildAt(i).asActivityRecord();
+ if (r == null) {
+ // Has a child that is other than Activity.
+ return false;
+ }
+ if (!includeFinishing && r.finishing) {
+ continue;
+ }
+ if (!r.isTaskOverlay()) {
+ return false;
+ }
+ count++;
}
- return getActivity((r) -> !r.finishing && r.isTaskOverlay()) != null;
+ return count > 0;
}
private boolean autoRemoveFromRecents() {
@@ -2369,6 +2378,15 @@ class Task extends WindowContainer<WindowContainer> {
return getRootTask() == this;
}
+ boolean isLeafTask() {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ if (mChildren.get(i).asTask() != null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
int getDescendantTaskCount() {
final int[] currentCount = {0};
final PooledConsumer c = PooledLambda.obtainConsumer((t, count) -> { count[0]++; },
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 633098566b1b..a370093a3907 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8021,7 +8021,11 @@ public class WindowManagerService extends IWindowManager.Stub
int displayId, Rect outContentInsets, Rect outStableInsets,
DisplayCutout.ParcelableWrapper displayCutout) {
synchronized (mGlobalLock) {
- final DisplayContent dc = mRoot.getDisplayContent(displayId);
+ final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
+ if (dc == null) {
+ throw new WindowManager.InvalidDisplayException("Display#" + displayId
+ + "could not be found!");
+ }
final WindowToken windowToken = dc.getWindowToken(attrs.token);
final ActivityRecord activity;
if (windowToken != null && windowToken.asActivityRecord() != null) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 553ec4201cc2..96ac279ef1e8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -458,8 +458,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// A collection of user restrictions that are deprecated and should simply be ignored.
private static final Set<String> DEPRECATED_USER_RESTRICTIONS;
private static final String AB_DEVICE_KEY = "ro.build.ab_update";
- // Permissions related to location which must not be granted automatically
- private static final Set<String> LOCATION_PERMISSIONS;
static {
SECURE_SETTINGS_WHITELIST = new ArraySet<>();
@@ -504,11 +502,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
DEPRECATED_USER_RESTRICTIONS = Sets.newHashSet(
UserManager.DISALLOW_ADD_MANAGED_PROFILE,
UserManager.DISALLOW_REMOVE_MANAGED_PROFILE);
-
- LOCATION_PERMISSIONS = Sets.newHashSet(
- permission.ACCESS_FINE_LOCATION,
- permission.ACCESS_BACKGROUND_LOCATION,
- permission.ACCESS_COARSE_LOCATION);
}
/**
@@ -12541,14 +12534,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
true);
}
- // Prevent granting location-related permissions without user consent.
- if (LOCATION_PERMISSIONS.contains(permission)
- && grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
- && !isUnattendedManagedKioskUnchecked()) {
- callback.sendResult(null);
- return;
- }
-
if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
|| grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
|| grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 3e3f40d31d0e..e28d13a1a20c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -35,7 +35,6 @@ import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
import android.content.pm.parsing.PackageImpl;
import android.content.pm.parsing.ParsingPackage;
-import android.net.Uri;
import android.os.Build;
import android.os.Process;
import android.util.ArrayMap;
@@ -87,6 +86,17 @@ public class AppsFilterTest {
return pkg;
}
+ private static ParsingPackage pkgQueriesProvider(String packageName,
+ String... queriesAuthorities) {
+ ParsingPackage pkg = pkg(packageName);
+ if (queriesAuthorities != null) {
+ for (String authority : queriesAuthorities) {
+ pkg.addQueriesProvider(authority);
+ }
+ }
+ return pkg;
+ }
+
private static ParsingPackage pkg(String packageName, String... queriesPackages) {
ParsingPackage pkg = pkg(packageName);
if (queriesPackages != null) {
@@ -172,8 +182,7 @@ public class AppsFilterTest {
PackageSetting target = simulateAddPackage(appsFilter,
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package",
- new Intent().setData(Uri.parse("content://com.some.authority"))),
+ pkgQueriesProvider("com.some.other.package", "com.some.authority"),
DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
@@ -188,8 +197,7 @@ public class AppsFilterTest {
PackageSetting target = simulateAddPackage(appsFilter,
pkgWithProvider("com.some.package", "com.some.authority"), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package",
- new Intent().setData(Uri.parse("content://com.some.other.authority"))),
+ pkgQueriesProvider("com.some.other.package", "com.some.other.authority"),
DUMMY_CALLING_UID);
assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
@@ -205,8 +213,7 @@ public class AppsFilterTest {
pkgWithProvider("com.some.package", "com.some.authority;com.some.other.authority"),
DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
- pkg("com.some.other.package",
- new Intent().setData(Uri.parse("content://com.some.authority"))),
+ pkgQueriesProvider("com.some.other.package", "com.some.authority"),
DUMMY_CALLING_UID);
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
@@ -266,7 +273,7 @@ public class AppsFilterTest {
appsFilter.onSystemReady();
PackageSetting target = simulateAddPackage(appsFilter,
- pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_UID);
+ pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_UID);
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_UID);
diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
index 804c1b9e09fd..1a6c6b4011cd 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
@@ -224,21 +224,43 @@ public class RollbackUnitTest {
}
@Test
- public void snapshotThenDelete() {
+ public void snapshotThenDeleteNoApex() {
+ Rollback rollback = new Rollback(123, new File("/test/testing"), -1, USER, INSTALLER);
+ PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false);
+ PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, false);
+ rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2));
+
+ int[] userIds = {111, 222};
+ rollback.snapshotUserData(PKG_2, userIds, mMockDataHelper);
+
+ verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds));
+
+ rollback.delete(mMockDataHelper);
+
+ verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(111));
+ verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(222));
+ verify(mMockDataHelper, never()).destroyApexDeSnapshots(anyInt());
+
+ assertThat(rollback.isDeleted()).isTrue();
+ }
+
+ @Test
+ public void snapshotThenDeleteWithApex() {
Rollback rollback = new Rollback(123, new File("/test/testing"), -1, USER, INSTALLER);
PackageRollbackInfo pkgInfo1 = newPkgInfoFor(PKG_1, 12, 10, false);
PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true);
rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2));
- int[] userIds = {12, 18};
+ int[] userIds = {111, 222};
rollback.snapshotUserData(PKG_2, userIds, mMockDataHelper);
verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds));
rollback.delete(mMockDataHelper);
- verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(12));
- verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(18));
+ verify(mMockDataHelper, never())
+ .destroyAppDataSnapshot(anyInt(), pkgRollbackInfoFor(PKG_2), anyInt());
+ verify(mMockDataHelper).destroyApexDeSnapshots(123);
assertThat(rollback.isDeleted()).isTrue();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index ebe4ab99663a..a0ea7290ec01 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -29,6 +29,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -140,6 +141,19 @@ public class ActivityRecordTests extends ActivityTestsBase {
}
@Test
+ public void testRemoveChildWithOverlayActivity() {
+ final ActivityRecord overlayActivity =
+ new ActivityBuilder(mService).setTask(mTask).build();
+ overlayActivity.setTaskOverlay(true);
+ final ActivityRecord overlayActivity2 =
+ new ActivityBuilder(mService).setTask(mTask).build();
+ overlayActivity2.setTaskOverlay(true);
+
+ mTask.removeChild(overlayActivity2, "test");
+ verify(mSupervisor, never()).removeTask(any(), anyBoolean(), anyBoolean(), any());
+ }
+
+ @Test
public void testNoCleanupMovingActivityInSameStack() {
final Task newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
mActivity.reparent(newTask, 0, null /*reason*/);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 9dbaa4c9ca82..e6291a4c34ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -95,8 +95,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Before
public void setUp() throws Exception {
- updateDisplayFrames();
-
mWindow = spy(createWindow(null, TYPE_APPLICATION, "window"));
// We only test window frames set by DisplayPolicy, so here prevents computeFrameLw from
// changing those frames.
@@ -106,6 +104,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
attrs.width = MATCH_PARENT;
attrs.height = MATCH_PARENT;
attrs.format = PixelFormat.TRANSLUCENT;
+
+ updateDisplayFrames();
}
@After
@@ -126,6 +126,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
private void updateDisplayFrames() {
mFrames = createDisplayFrames();
+ mDisplayContent.mDisplayFrames = mFrames;
}
private DisplayFrames createDisplayFrames() {
@@ -180,63 +181,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
}
@Test
- public void layoutWindowLw_appDrawsBars() {
- assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
- mWindow.mAttrs.flags = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- mWindow.mAttrs.setFitInsetsTypes(Type.systemBars());
- addWindow(mWindow);
-
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- }
-
- @Test
- public void layoutWindowLw_forceAppDrawBars() {
- assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
- mWindow.mAttrs.privateFlags = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
- mWindow.mAttrs.setFitInsetsTypes(Type.systemBars());
- addWindow(mWindow);
-
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- }
-
- @Test
- public void layoutWindowLw_onlyDrawBottomBar() {
- assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
- mWindow.mAttrs.flags = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- mWindow.mAttrs.setFitInsetsTypes(Type.systemBars());
- addWindow(mWindow);
-
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- }
-
- @Test
public void layoutWindowLw_fitAllSides() {
assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
@@ -273,7 +217,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
}
@Test
- public void layoutWindowLw_fitMax() {
+ public void layoutWindowLw_fitInsetsIgnoringVisibility() {
assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
final InsetsState state =
@@ -295,7 +239,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
}
@Test
- public void layoutWindowLw_fitNonMax() {
+ public void layoutWindowLw_fitInsetsNotIgnoringVisibility() {
assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
final InsetsState state =
@@ -398,6 +342,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
@@ -416,6 +361,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
addWindow(mWindow);
@@ -435,6 +381,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
mWindow.mAttrs.setFitInsetsTypes(
mWindow.mAttrs.getFitInsetsTypes() & ~Type.statusBars());
@@ -456,6 +403,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
mDisplayContent.getInsetsPolicy().getInsetsForDispatch(mWindow)
.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
@@ -477,6 +425,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
mDisplayContent.getInsetsPolicy().getInsetsForDispatch(mWindow)
.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
@@ -501,6 +450,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
@@ -521,6 +471,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
@@ -541,6 +492,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
mWindow.mAttrs.setFitInsetsTypes(
mWindow.mAttrs.getFitInsetsTypes() & ~Type.statusBars());
@@ -581,6 +533,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
mWindow.mAttrs.setFitInsetsTypes(
mWindow.mAttrs.getFitInsetsTypes() & ~Type.statusBars());
@@ -603,6 +556,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
addWindow(mWindow);
@@ -625,6 +579,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
public void layoutWindowLw_withForwardInset_SoftInputAdjustNothing() {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING;
addWindow(mWindow);
@@ -849,7 +804,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
final String prefix = "";
final InsetsState simulatedInsetsState = new InsetsState();
final DisplayFrames simulatedDisplayFrames = createDisplayFrames();
- mDisplayContent.mDisplayFrames = mFrames;
mDisplayPolicy.beginLayoutLw(mFrames, uiMode);
mDisplayContent.getInsetsStateController().onPostLayout();
mDisplayPolicy.simulateLayoutDisplay(simulatedDisplayFrames, simulatedInsetsState, uiMode);
@@ -867,6 +821,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
// Exclude comparing IME insets because currently the simulated layout only focuses on the
// insets from status bar and navigation bar.
realInsetsState.removeSource(InsetsState.ITYPE_IME);
+ realInsetsState.removeSource(InsetsState.ITYPE_CAPTION_BAR);
realInsetsState.dump(prefix, new PrintWriter(realInsetsDump));
final StringWriter simulatedInsetsDump = new StringWriter();
simulatedInsetsState.dump(prefix, new PrintWriter(simulatedInsetsDump));
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 2af118c40138..5aa32f868104 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -391,6 +391,7 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
manifest_action["uses-split"].Action(RequiredNameIsJavaPackage);
manifest_action["queries"]["package"].Action(RequiredNameIsJavaPackage);
manifest_action["queries"]["intent"] = intent_filter_action;
+ manifest_action["queries"]["provider"].Action(RequiredAndroidAttribute("authorities"));
// TODO: more complicated component name tag
manifest_action["key-sets"]["key-set"]["public-key"];