summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk3
-rw-r--r--api/current.txt9
-rw-r--r--api/system-current.txt9
-rw-r--r--api/test-current.txt9
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java45
-rw-r--r--core/java/android/app/ActivityView.java620
-rw-r--r--core/java/android/app/IActivityContainer.aidl36
-rw-r--r--core/java/android/app/IActivityContainerCallback.aidl25
-rw-r--r--core/java/android/app/IActivityManager.aidl6
-rw-r--r--core/java/android/app/IInputForwarder.aidl (renamed from packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml)17
-rw-r--r--core/java/android/content/Context.java52
-rw-r--r--core/java/android/content/SyncStatusInfo.java13
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl4
-rw-r--r--core/java/android/hardware/input/InputManager.java22
-rw-r--r--core/java/android/os/BatteryStats.java2
-rwxr-xr-xcore/java/android/provider/Settings.java16
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java2
-rw-r--r--core/java/android/service/vr/IVrListener.aidl2
-rw-r--r--core/java/android/service/vr/VrListenerService.java32
-rw-r--r--core/java/android/view/Surface.java103
-rw-r--r--core/java/com/android/internal/colorextraction/ColorExtractor.java30
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java12
-rw-r--r--core/jni/android_view_Surface.cpp16
-rw-r--r--core/proto/android/providers/settings.proto1
-rw-r--r--core/res/res/values-af/strings.xml4
-rw-r--r--core/res/res/values-am/strings.xml4
-rw-r--r--core/res/res/values-ar/strings.xml4
-rw-r--r--core/res/res/values-az/strings.xml4
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml4
-rw-r--r--core/res/res/values-be/strings.xml4
-rw-r--r--core/res/res/values-bg/strings.xml4
-rw-r--r--core/res/res/values-bn/strings.xml4
-rw-r--r--core/res/res/values-bs/strings.xml4
-rw-r--r--core/res/res/values-ca/strings.xml4
-rw-r--r--core/res/res/values-cs/strings.xml4
-rw-r--r--core/res/res/values-da/strings.xml4
-rw-r--r--core/res/res/values-de/strings.xml4
-rw-r--r--core/res/res/values-el/strings.xml4
-rw-r--r--core/res/res/values-en-rAU/strings.xml4
-rw-r--r--core/res/res/values-en-rGB/strings.xml4
-rw-r--r--core/res/res/values-en-rIN/strings.xml4
-rw-r--r--core/res/res/values-es-rUS/strings.xml4
-rw-r--r--core/res/res/values-es/strings.xml4
-rw-r--r--core/res/res/values-et/strings.xml4
-rw-r--r--core/res/res/values-eu/strings.xml4
-rw-r--r--core/res/res/values-fa/strings.xml6
-rw-r--r--core/res/res/values-fi/strings.xml4
-rw-r--r--core/res/res/values-fr-rCA/strings.xml4
-rw-r--r--core/res/res/values-fr/strings.xml4
-rw-r--r--core/res/res/values-gl/strings.xml6
-rw-r--r--core/res/res/values-gu/strings.xml4
-rw-r--r--core/res/res/values-hi/strings.xml20
-rw-r--r--core/res/res/values-hr/strings.xml4
-rw-r--r--core/res/res/values-hu/strings.xml4
-rw-r--r--core/res/res/values-hy/strings.xml4
-rw-r--r--core/res/res/values-in/strings.xml4
-rw-r--r--core/res/res/values-is/strings.xml4
-rw-r--r--core/res/res/values-it/strings.xml4
-rw-r--r--core/res/res/values-iw/strings.xml4
-rw-r--r--core/res/res/values-ja/strings.xml4
-rw-r--r--core/res/res/values-ka/strings.xml4
-rw-r--r--core/res/res/values-kk/strings.xml4
-rw-r--r--core/res/res/values-km/strings.xml4
-rw-r--r--core/res/res/values-kn/strings.xml8
-rw-r--r--core/res/res/values-ko/strings.xml4
-rw-r--r--core/res/res/values-ky/strings.xml4
-rw-r--r--core/res/res/values-lo/strings.xml4
-rw-r--r--core/res/res/values-lt/strings.xml4
-rw-r--r--core/res/res/values-lv/strings.xml4
-rw-r--r--core/res/res/values-mk/strings.xml4
-rw-r--r--core/res/res/values-ml/strings.xml4
-rw-r--r--core/res/res/values-mn/strings.xml4
-rw-r--r--core/res/res/values-mr/strings.xml6
-rw-r--r--core/res/res/values-ms/strings.xml4
-rw-r--r--core/res/res/values-my/strings.xml4
-rw-r--r--core/res/res/values-nb/strings.xml4
-rw-r--r--core/res/res/values-ne/strings.xml4
-rw-r--r--core/res/res/values-nl/strings.xml4
-rw-r--r--core/res/res/values-pa/strings.xml4
-rw-r--r--core/res/res/values-pl/strings.xml4
-rw-r--r--core/res/res/values-pt-rBR/strings.xml4
-rw-r--r--core/res/res/values-pt-rPT/strings.xml96
-rw-r--r--core/res/res/values-pt/strings.xml4
-rw-r--r--core/res/res/values-ro/strings.xml4
-rw-r--r--core/res/res/values-ru/strings.xml4
-rw-r--r--core/res/res/values-si/strings.xml4
-rw-r--r--core/res/res/values-sk/strings.xml4
-rw-r--r--core/res/res/values-sl/strings.xml4
-rw-r--r--core/res/res/values-sq/strings.xml4
-rw-r--r--core/res/res/values-sr/strings.xml4
-rw-r--r--core/res/res/values-sv/strings.xml4
-rw-r--r--core/res/res/values-sw/strings.xml4
-rw-r--r--core/res/res/values-ta/strings.xml4
-rw-r--r--core/res/res/values-te/strings.xml4
-rw-r--r--core/res/res/values-th/strings.xml4
-rw-r--r--core/res/res/values-tl/strings.xml4
-rw-r--r--core/res/res/values-tr/strings.xml4
-rw-r--r--core/res/res/values-uk/strings.xml6
-rw-r--r--core/res/res/values-ur/strings.xml4
-rw-r--r--core/res/res/values-uz/strings.xml4
-rw-r--r--core/res/res/values-vi/strings.xml4
-rw-r--r--core/res/res/values-zh-rCN/strings.xml4
-rw-r--r--core/res/res/values-zh-rHK/strings.xml4
-rw-r--r--core/res/res/values-zh-rTW/strings.xml4
-rw-r--r--core/res/res/values-zu/strings.xml4
-rw-r--r--core/res/res/values/strings.xml12
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java106
-rw-r--r--packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml (renamed from packages/SystemUI/res/drawable/ic_qs_night_display_on.xml)0
-rw-r--r--packages/SettingsLib/res/drawable/ic_signal_location.xml (renamed from packages/SystemUI/res/drawable/ic_signal_location.xml)0
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java12
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java22
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java3
-rw-r--r--packages/SystemUI/AndroidManifest.xml2
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values/attrs.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values/styles.xml8
-rw-r--r--packages/SystemUI/res/drawable/ic_dnd.xml8
-rw-r--r--packages/SystemUI/res/drawable/ic_dnd_total_silence.xml7
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_alarm.xml10
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml10
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_bt_sco.xml13
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_media.xml6
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_media_bt.xml7
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml10
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_media_mute.xml9
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_ringer.xml18
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml24
-rw-r--r--packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml6
-rw-r--r--packages/SystemUI/res/values/styles.xml43
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java98
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java21
-rw-r--r--packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk13
-rw-r--r--packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml8
-rw-r--r--packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml12
-rw-r--r--proto/src/metrics_constants.proto5
-rw-r--r--services/Android.mk1
-rw-r--r--services/art-profile17
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java13
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java3
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java83
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java15
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java17
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java65
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java536
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java58
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java7
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java17
-rw-r--r--services/core/java/com/android/server/am/PinnedActivityStack.java7
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java3
-rw-r--r--services/core/java/com/android/server/am/VrController.java7
-rw-r--r--services/core/java/com/android/server/input/InputForwarder.java46
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java26
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java20
-rw-r--r--services/core/java/com/android/server/location/GnssMeasurementsProvider.java5
-rw-r--r--services/core/java/com/android/server/location/GnssNavigationMessageProvider.java5
-rw-r--r--services/core/java/com/android/server/location/RemoteListenerHelper.java68
-rw-r--r--services/core/java/com/android/server/notification/ConditionProviders.java6
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java58
-rw-r--r--services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java10
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java99
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java33
-rw-r--r--services/core/java/com/android/server/notification/XmlUtils.java52
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java12
-rw-r--r--services/core/java/com/android/server/vr/VrManagerInternal.java3
-rw-r--r--services/core/java/com/android/server/vr/VrManagerService.java79
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java1
-rw-r--r--services/java/com/android/server/SystemServer.java5
-rw-r--r--services/retaildemo/Android.mk12
-rw-r--r--services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java178
-rw-r--r--services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java868
-rw-r--r--services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java105
-rw-r--r--services/tests/notification/Android.mk1
-rw-r--r--services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java26
-rw-r--r--services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java25
-rw-r--r--services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java184
-rw-r--r--services/tests/servicestests/Android.mk1
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java80
-rw-r--r--services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java164
-rw-r--r--services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java484
-rw-r--r--tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java33
-rw-r--r--tests/UiBench/Android.mk9
-rw-r--r--tests/UiBench/AndroidManifest.xml10
-rw-r--r--tests/UiBench/build.gradle1
-rw-r--r--tests/UiBench/src/com/android/test/uibench/leanback/BitmapLoader.java144
-rw-r--r--tests/UiBench/src/com/android/test/uibench/leanback/BrowseActivity.java31
-rw-r--r--tests/UiBench/src/com/android/test/uibench/leanback/BrowseFragment.java40
-rw-r--r--tests/UiBench/src/com/android/test/uibench/leanback/CardPresenter.java62
-rw-r--r--tests/UiBench/src/com/android/test/uibench/leanback/PhotoItem.java72
-rw-r--r--tests/UiBench/src/com/android/test/uibench/leanback/TestHelper.java238
197 files changed, 2288 insertions, 4091 deletions
diff --git a/Android.mk b/Android.mk
index 4695a1970cbc..69c8c2cae858 100644
--- a/Android.mk
+++ b/Android.mk
@@ -71,8 +71,6 @@ LOCAL_SRC_FILES += \
core/java/android/accounts/IAccountManagerResponse.aidl \
core/java/android/accounts/IAccountAuthenticator.aidl \
core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
- core/java/android/app/IActivityContainer.aidl \
- core/java/android/app/IActivityContainerCallback.aidl \
core/java/android/app/IActivityController.aidl \
core/java/android/app/IActivityManager.aidl \
core/java/android/app/IActivityPendingResult.aidl \
@@ -84,6 +82,7 @@ LOCAL_SRC_FILES += \
core/java/android/app/ITaskStackListener.aidl \
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IEphemeralResolver.aidl \
+ core/java/android/app/IInputForwarder.aidl \
core/java/android/app/IInstantAppResolver.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
core/java/android/app/INotificationManager.aidl \
diff --git a/api/current.txt b/api/current.txt
index 856244449b8b..7a2cecd930ab 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -45255,11 +45255,15 @@ package android.view {
public class Surface implements android.os.Parcelable {
ctor public Surface(android.graphics.SurfaceTexture);
method public int describeContents();
+ method public boolean isAutoRefreshEnabled();
+ method public boolean isSharedBufferModeEnabled();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
method public android.graphics.Canvas lockHardwareCanvas();
method public void readFromParcel(android.os.Parcel);
method public void release();
+ method public void setAutoRefreshEnabled(boolean);
+ method public void setSharedBufferModeEnabled(boolean);
method public deprecated void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
@@ -52301,6 +52305,11 @@ package dalvik.system {
method protected synchronized java.lang.Package getPackage(java.lang.String);
}
+ public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
+ ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader);
+ ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader);
+ }
+
public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index d0fa033d113a..60aaa6019d06 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -48911,11 +48911,15 @@ package android.view {
public class Surface implements android.os.Parcelable {
ctor public Surface(android.graphics.SurfaceTexture);
method public int describeContents();
+ method public boolean isAutoRefreshEnabled();
+ method public boolean isSharedBufferModeEnabled();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
method public android.graphics.Canvas lockHardwareCanvas();
method public void readFromParcel(android.os.Parcel);
method public void release();
+ method public void setAutoRefreshEnabled(boolean);
+ method public void setSharedBufferModeEnabled(boolean);
method public deprecated void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
@@ -56330,6 +56334,11 @@ package dalvik.system {
method protected synchronized java.lang.Package getPackage(java.lang.String);
}
+ public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
+ ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader);
+ ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader);
+ }
+
public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader);
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 2c2ba307a74e..282e9d0893bd 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -45660,11 +45660,15 @@ package android.view {
public class Surface implements android.os.Parcelable {
ctor public Surface(android.graphics.SurfaceTexture);
method public int describeContents();
+ method public boolean isAutoRefreshEnabled();
+ method public boolean isSharedBufferModeEnabled();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
method public android.graphics.Canvas lockHardwareCanvas();
method public void readFromParcel(android.os.Parcel);
method public void release();
+ method public void setAutoRefreshEnabled(boolean);
+ method public void setSharedBufferModeEnabled(boolean);
method public deprecated void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
@@ -52738,6 +52742,11 @@ package dalvik.system {
method protected synchronized java.lang.Package getPackage(java.lang.String);
}
+ public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
+ ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader);
+ ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader);
+ }
+
public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
ctor public DexClassLoader(java.lang.String, java.lang.String, java.lang.String, java.lang.ClassLoader);
}
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index f003061cec3a..ab075ee0e9f2 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -16,70 +16,25 @@
package com.android.commands.am;
-import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
-import static android.app.ActivityManager.RESIZE_MODE_USER;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
import android.app.ActivityManager;
-import android.app.ActivityManager.StackInfo;
-import android.app.IActivityContainer;
-import android.app.IActivityController;
import android.app.IActivityManager;
-import android.app.IInstrumentationWatcher;
-import android.app.Instrumentation;
-import android.app.IStopUserCallback;
-import android.app.ProfilerInfo;
-import android.app.UiAutomationConnection;
-import android.app.usage.ConfigurationStats;
-import android.app.usage.IUsageStatsManager;
-import android.app.usage.UsageStatsManager;
-import android.content.ComponentCallbacks2;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.IIntentReceiver;
-import android.content.Intent;
import android.content.pm.IPackageManager;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SELinux;
import android.os.ServiceManager;
import android.os.ShellCallback;
-import android.os.ShellCommand;
-import android.os.SystemProperties;
import android.os.UserHandle;
-import android.text.TextUtils;
import android.util.AndroidException;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.view.IWindowManager;
import com.android.internal.os.BaseCommand;
-import com.android.internal.util.HexDump;
-import com.android.internal.util.Preconditions;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
public class Am extends BaseCommand {
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 29b83dc3b315..5dd47acfb940 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
+/**
+ * Copyright (c) 2017 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.
@@ -16,17 +16,12 @@
package android.app;
-import static android.app.ActivityManager.START_CANCELED;
-
+import android.annotation.NonNull;
import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.IIntentSender;
import android.content.Intent;
-import android.content.IntentSender;
-import android.graphics.SurfaceTexture;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.OperationCanceledException;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.hardware.input.InputManager;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -35,163 +30,177 @@ import android.view.InputDevice;
import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.Surface;
-import android.view.TextureView;
-import android.view.TextureView.SurfaceTextureListener;
-import android.view.View;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
import android.view.ViewGroup;
import android.view.WindowManager;
-import dalvik.system.CloseGuard;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayDeque;
-import java.util.concurrent.Executor;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import com.android.internal.annotations.GuardedBy;
+import dalvik.system.CloseGuard;
-/** @hide */
+/**
+ * Activity container that allows launching activities into itself and does input forwarding.
+ * <p>Creation of this view is only allowed to callers who have
+ * {@link android.Manifest.permission#INJECT_EVENTS} permission.
+ * <p>Activity launching into this container is restricted by the same rules that apply to launching
+ * on VirtualDisplays.
+ * @hide
+ */
public class ActivityView extends ViewGroup {
- private static final String TAG = "ActivityView";
- private static final boolean DEBUG = false;
-
- private static final int MSG_SET_SURFACE = 1;
-
- private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
- private static final int MINIMUM_POOL_SIZE = 1;
- private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
- private static final int KEEP_ALIVE = 1;
-
- private static final ThreadFactory sThreadFactory = new ThreadFactory() {
- private final AtomicInteger mCount = new AtomicInteger(1);
-
- public Thread newThread(Runnable r) {
- return new Thread(r, "ActivityView #" + mCount.getAndIncrement());
- }
- };
-
- private static final BlockingQueue<Runnable> sPoolWorkQueue =
- new LinkedBlockingQueue<Runnable>(128);
- /**
- * An {@link Executor} that can be used to execute tasks in parallel.
- */
- private static final Executor sExecutor = new ThreadPoolExecutor(MINIMUM_POOL_SIZE,
- MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
-
-
- private static class SerialExecutor implements Executor {
- private final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
- private Runnable mActive;
-
- public synchronized void execute(final Runnable r) {
- mTasks.offer(new Runnable() {
- public void run() {
- try {
- r.run();
- } finally {
- scheduleNext();
- }
- }
- });
- if (mActive == null) {
- scheduleNext();
- }
- }
-
- protected synchronized void scheduleNext() {
- if ((mActive = mTasks.poll()) != null) {
- sExecutor.execute(mActive);
- }
- }
- }
-
- private final SerialExecutor mExecutor = new SerialExecutor();
+ private static final String DISPLAY_NAME = "ActivityViewVirtualDisplay";
+ private static final String TAG = "ActivityView";
- private final int mDensityDpi;
- private final TextureView mTextureView;
+ private VirtualDisplay mVirtualDisplay;
+ private final SurfaceView mSurfaceView;
+ private Surface mSurface;
- @GuardedBy("mActivityContainerLock")
- private ActivityContainerWrapper mActivityContainer;
- private Object mActivityContainerLock = new Object();
+ private final SurfaceCallback mSurfaceCallback;
+ private StateCallback mActivityViewCallback;
- private Activity mActivity;
- private int mWidth;
- private int mHeight;
- private Surface mSurface;
- private int mLastVisibility;
- private ActivityViewCallback mActivityViewCallback;
+ private IInputForwarder mInputForwarder;
+ private final CloseGuard mGuard = CloseGuard.get();
+ private boolean mOpened; // Protected by mGuard.
public ActivityView(Context context) {
- this(context, null);
+ this(context, null /* attrs */);
}
public ActivityView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, 0 /* defStyle */);
}
public ActivityView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- while (context instanceof ContextWrapper) {
- if (context instanceof Activity) {
- mActivity = (Activity)context;
- break;
- }
- context = ((ContextWrapper)context).getBaseContext();
- }
- if (mActivity == null) {
- throw new IllegalStateException("The ActivityView's Context is not an Activity.");
- }
+ mSurfaceView = new SurfaceView(context);
+ mSurfaceCallback = new SurfaceCallback();
+ mSurfaceView.getHolder().addCallback(mSurfaceCallback);
+ addView(mSurfaceView);
- try {
- mActivityContainer = new ActivityContainerWrapper(
- ActivityManager.getService().createVirtualActivityContainer(
- mActivity.getActivityToken(), new ActivityContainerCallback(this)));
- } catch (RemoteException e) {
- throw new RuntimeException("ActivityView: Unable to create ActivityContainer. "
- + e);
- }
+ mOpened = true;
+ mGuard.open("release");
+ }
- mTextureView = new TextureView(context);
- mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
- addView(mTextureView);
+ /** Callback that notifies when the container is ready or destroyed. */
+ public abstract static class StateCallback {
+ /**
+ * Called when the container is ready for launching activities. Calling
+ * {@link #startActivity(Intent)} prior to this callback will result in an
+ * {@link IllegalStateException}.
+ *
+ * @see #startActivity(Intent)
+ */
+ public abstract void onActivityViewReady(ActivityView view);
+ /**
+ * Called when the container can no longer launch activities. Calling
+ * {@link #startActivity(Intent)} after this callback will result in an
+ * {@link IllegalStateException}.
+ *
+ * @see #startActivity(Intent)
+ */
+ public abstract void onActivityViewDestroyed(ActivityView view);
+ }
- WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics metrics = new DisplayMetrics();
- wm.getDefaultDisplay().getMetrics(metrics);
- mDensityDpi = metrics.densityDpi;
+ /**
+ * Set the callback to be notified about state changes.
+ * <p>This class must finish initializing before {@link #startActivity(Intent)} can be called.
+ * <p>Note: If the instance was ready prior to this call being made, then
+ * {@link StateCallback#onActivityViewReady(ActivityView)} will be called from within
+ * this method call.
+ *
+ * @param callback The callback to report events to.
+ *
+ * @see StateCallback
+ * @see #startActivity(Intent)
+ */
+ public void setCallback(StateCallback callback) {
+ mActivityViewCallback = callback;
- mLastVisibility = getVisibility();
+ if (mVirtualDisplay != null && mActivityViewCallback != null) {
+ mActivityViewCallback.onActivityViewReady(this);
+ }
+ }
- if (DEBUG) Log.v(TAG, "ctor()");
+ /**
+ * Launch a new activity into this container.
+ * <p>Activity resolved by the provided {@link Intent} must have
+ * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
+ * launched here. Also, if activity is not owned by the owner of this container, it must allow
+ * embedding and the caller must have permission to embed.
+ * <p>Note: This class must finish initializing and
+ * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before
+ * this method can be called.
+ *
+ * @param intent Intent used to launch an activity.
+ *
+ * @see StateCallback
+ * @see #startActivity(PendingIntent)
+ */
+ public void startActivity(@NonNull Intent intent) {
+ final ActivityOptions options = prepareActivityOptions();
+ getContext().startActivity(intent, options.toBundle());
}
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- mTextureView.layout(0, 0, r - l, b - t);
+ /**
+ * Launch a new activity into this container.
+ * <p>Activity resolved by the provided {@link PendingIntent} must have
+ * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
+ * launched here. Also, if activity is not owned by the owner of this container, it must allow
+ * embedding and the caller must have permission to embed.
+ * <p>Note: This class must finish initializing and
+ * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before
+ * this method can be called.
+ *
+ * @param pendingIntent Intent used to launch an activity.
+ *
+ * @see StateCallback
+ * @see #startActivity(Intent)
+ */
+ public void startActivity(@NonNull PendingIntent pendingIntent) {
+ final ActivityOptions options = prepareActivityOptions();
+ try {
+ pendingIntent.send(null /* context */, 0 /* code */, null /* intent */,
+ null /* onFinished */, null /* handler */, null /* requiredPermission */,
+ options.toBundle());
+ } catch (PendingIntent.CanceledException e) {
+ throw new RuntimeException(e);
+ }
}
- @Override
- protected void onVisibilityChanged(View changedView, final int visibility) {
- super.onVisibilityChanged(changedView, visibility);
+ /**
+ * Check if container is ready to launch and create {@link ActivityOptions} to target the
+ * virtual display.
+ */
+ private ActivityOptions prepareActivityOptions() {
+ if (mVirtualDisplay == null) {
+ throw new IllegalStateException(
+ "Trying to start activity before ActivityView is ready.");
+ }
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
+ return options;
+ }
- if (mSurface != null && (visibility == View.GONE || mLastVisibility == View.GONE)) {
- if (DEBUG) Log.v(TAG, "visibility changed; enqueing runnable");
- final Surface surface = (visibility == View.GONE) ? null : mSurface;
- setSurfaceAsync(surface, mWidth, mHeight, mDensityDpi, false);
+ /**
+ * Release this container. Activity launching will no longer be permitted.
+ * <p>Note: Calling this method is allowed after
+ * {@link StateCallback#onActivityViewReady(ActivityView)} callback was triggered and before
+ * {@link StateCallback#onActivityViewDestroyed(ActivityView)}.
+ *
+ * @see StateCallback
+ */
+ public void release() {
+ if (mVirtualDisplay == null) {
+ throw new IllegalStateException(
+ "Trying to release container that is not initialized.");
}
- mLastVisibility = visibility;
+ performRelease();
}
- private boolean injectInputEvent(InputEvent event) {
- return mActivityContainer != null && mActivityContainer.injectEvent(event);
+ @Override
+ public void onLayout(boolean changed, int l, int t, int r, int b) {
+ mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */);
}
@Override
@@ -209,309 +218,118 @@ public class ActivityView extends ViewGroup {
return super.onGenericMotionEvent(event);
}
- @Override
- public void onAttachedToWindow() {
- if (DEBUG) Log.v(TAG, "onAttachedToWindow(): mActivityContainer=" + mActivityContainer +
- " mSurface=" + mSurface);
- }
-
- @Override
- public void onDetachedFromWindow() {
- if (DEBUG) Log.v(TAG, "onDetachedFromWindow(): mActivityContainer=" + mActivityContainer +
- " mSurface=" + mSurface);
- }
-
- public boolean isAttachedToDisplay() {
- return mSurface != null;
- }
-
- public void startActivity(Intent intent) {
- if (mActivityContainer == null) {
- throw new IllegalStateException("Attempt to call startActivity after release");
- }
- if (mSurface == null) {
- throw new IllegalStateException("Surface not yet created.");
- }
- if (DEBUG) Log.v(TAG, "startActivity(): intent=" + intent + " " +
- (isAttachedToDisplay() ? "" : "not") + " attached");
- if (mActivityContainer.startActivity(intent) == START_CANCELED) {
- throw new OperationCanceledException();
- }
- }
-
- public void startActivity(IntentSender intentSender) {
- if (mActivityContainer == null) {
- throw new IllegalStateException("Attempt to call startActivity after release");
- }
- if (mSurface == null) {
- throw new IllegalStateException("Surface not yet created.");
- }
- if (DEBUG) Log.v(TAG, "startActivityIntentSender(): intentSender=" + intentSender + " " +
- (isAttachedToDisplay() ? "" : "not") + " attached");
- final IIntentSender iIntentSender = intentSender.getTarget();
- if (mActivityContainer.startActivityIntentSender(iIntentSender) == START_CANCELED) {
- throw new OperationCanceledException();
- }
- }
-
- public void startActivity(PendingIntent pendingIntent) {
- if (mActivityContainer == null) {
- throw new IllegalStateException("Attempt to call startActivity after release");
- }
- if (mSurface == null) {
- throw new IllegalStateException("Surface not yet created.");
- }
- if (DEBUG) Log.v(TAG, "startActivityPendingIntent(): PendingIntent=" + pendingIntent + " "
- + (isAttachedToDisplay() ? "" : "not") + " attached");
- final IIntentSender iIntentSender = pendingIntent.getTarget();
- if (mActivityContainer.startActivityIntentSender(iIntentSender) == START_CANCELED) {
- throw new OperationCanceledException();
- }
- }
-
- public void release() {
- if (DEBUG) Log.v(TAG, "release() mActivityContainer=" + mActivityContainer +
- " mSurface=" + mSurface);
- if (mActivityContainer == null) {
- Log.e(TAG, "Duplicate call to release");
- return;
- }
- synchronized (mActivityContainerLock) {
- mActivityContainer.release();
- mActivityContainer = null;
- }
-
- if (mSurface != null) {
- mSurface.release();
- mSurface = null;
- }
-
- mTextureView.setSurfaceTextureListener(null);
- }
-
- private void setSurfaceAsync(final Surface surface, final int width, final int height,
- final int densityDpi, final boolean callback) {
- mExecutor.execute(new Runnable() {
- public void run() {
- try {
- synchronized (mActivityContainerLock) {
- if (mActivityContainer != null) {
- mActivityContainer.setSurface(surface, width, height, densityDpi);
- }
- }
- } catch (RemoteException e) {
- throw new RuntimeException(
- "ActivityView: Unable to set surface of ActivityContainer. ",
- e);
- }
- if (callback) {
- post(new Runnable() {
- @Override
- public void run() {
- if (mActivityViewCallback != null) {
- if (surface != null) {
- mActivityViewCallback.onSurfaceAvailable(ActivityView.this);
- } else {
- mActivityViewCallback.onSurfaceDestroyed(ActivityView.this);
- }
- }
- }
- });
- }
+ private boolean injectInputEvent(InputEvent event) {
+ if (mInputForwarder != null) {
+ try {
+ return mInputForwarder.forwardEvent(event);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
}
- });
- }
-
- /**
- * Set the callback to use to report certain state changes.
- *
- * Note: If the surface has been created prior to this call being made, then
- * ActivityViewCallback.onSurfaceAvailable will be called from within setCallback.
- *
- * @param callback The callback to report events to.
- *
- * @see ActivityViewCallback
- */
- public void setCallback(ActivityViewCallback callback) {
- mActivityViewCallback = callback;
-
- if (mSurface != null) {
- mActivityViewCallback.onSurfaceAvailable(this);
}
+ return false;
}
- public static abstract class ActivityViewCallback {
- /**
- * Called when all activities in the ActivityView have completed and been removed. Register
- * using {@link ActivityView#setCallback(ActivityViewCallback)}. Each ActivityView may
- * have at most one callback registered.
- */
- public abstract void onAllActivitiesComplete(ActivityView view);
- /**
- * Called when the surface is ready to be drawn to. Calling startActivity prior to this
- * callback will result in an IllegalStateException.
- */
- public abstract void onSurfaceAvailable(ActivityView view);
- /**
- * Called when the surface has been removed. Calling startActivity after this callback
- * will result in an IllegalStateException.
- */
- public abstract void onSurfaceDestroyed(ActivityView view);
- }
-
- private class ActivityViewSurfaceTextureListener implements SurfaceTextureListener {
+ private class SurfaceCallback implements SurfaceHolder.Callback {
@Override
- public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
- int height) {
- if (mActivityContainer == null) {
- return;
+ public void surfaceCreated(SurfaceHolder surfaceHolder) {
+ if (mVirtualDisplay == null) {
+ mSurface = mSurfaceView.getHolder().getSurface();
+ initVirtualDisplay();
+ if (mVirtualDisplay != null && mActivityViewCallback != null) {
+ mActivityViewCallback.onActivityViewReady(ActivityView.this);
+ }
+ } else {
+ mVirtualDisplay.setSurface(surfaceHolder.getSurface());
}
- if (DEBUG) Log.d(TAG, "onSurfaceTextureAvailable: width=" + width + " height="
- + height);
- mWidth = width;
- mHeight = height;
- mSurface = new Surface(surfaceTexture);
- setSurfaceAsync(mSurface, mWidth, mHeight, mDensityDpi, true);
}
@Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width,
- int height) {
- if (mActivityContainer == null) {
- return;
+ public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.resize(width, height, getBaseDisplayDensity());
}
- if (DEBUG) Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height);
}
@Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
- if (mActivityContainer == null) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "onSurfaceTextureDestroyed");
+ public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mSurface.release();
mSurface = null;
- setSurfaceAsync(null, mWidth, mHeight, mDensityDpi, true);
- return true;
- }
-
- @Override
- public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
-// Log.d(TAG, "onSurfaceTextureUpdated");
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.setSurface(null);
+ }
}
-
}
- private static class ActivityContainerCallback extends IActivityContainerCallback.Stub {
- private final WeakReference<ActivityView> mActivityViewWeakReference;
-
- ActivityContainerCallback(ActivityView activityView) {
- mActivityViewWeakReference = new WeakReference<>(activityView);
+ private void initVirtualDisplay() {
+ if (mVirtualDisplay != null) {
+ throw new IllegalStateException("Trying to initialize for the second time.");
}
- @Override
- public void setVisible(IBinder container, boolean visible) {
- if (DEBUG) Log.v(TAG, "setVisible(): container=" + container + " visible=" + visible +
- " ActivityView=" + mActivityViewWeakReference.get());
+ final int width = mSurfaceView.getWidth();
+ final int height = mSurfaceView.getHeight();
+ final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+ mVirtualDisplay = displayManager.createVirtualDisplay(
+ DISPLAY_NAME + "@" + System.identityHashCode(this),
+ width, height, getBaseDisplayDensity(), mSurface, 0 /* flags */);
+ if (mVirtualDisplay == null) {
+ Log.e(TAG, "Failed to initialize ActivityView");
+ return;
}
- @Override
- public void onAllActivitiesComplete(IBinder container) {
- final ActivityView activityView = mActivityViewWeakReference.get();
- if (activityView != null) {
- final ActivityViewCallback callback = activityView.mActivityViewCallback;
- if (callback != null) {
- final WeakReference<ActivityViewCallback> callbackRef =
- new WeakReference<>(callback);
- activityView.post(new Runnable() {
- @Override
- public void run() {
- ActivityViewCallback callback = callbackRef.get();
- if (callback != null) {
- callback.onAllActivitiesComplete(activityView);
- }
- }
- });
- }
- }
- }
+ mInputForwarder = InputManager.getInstance().createInputForwarder(
+ mVirtualDisplay.getDisplay().getDisplayId());
}
- private static class ActivityContainerWrapper {
- private final IActivityContainer mIActivityContainer;
- private final CloseGuard mGuard = CloseGuard.get();
- boolean mOpened; // Protected by mGuard.
-
- ActivityContainerWrapper(IActivityContainer container) {
- mIActivityContainer = container;
- mOpened = true;
- mGuard.open("release");
+ private void performRelease() {
+ if (!mOpened) {
+ return;
}
- void setSurface(Surface surface, int width, int height, int density)
- throws RemoteException {
- mIActivityContainer.setSurface(surface, width, height, density);
- }
+ mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
- int startActivity(Intent intent) {
- try {
- return mIActivityContainer.startActivity(intent);
- } catch (RemoteException e) {
- throw new RuntimeException("ActivityView: Unable to startActivity. " + e);
- }
+ if (mInputForwarder != null) {
+ mInputForwarder = null;
}
- int startActivityIntentSender(IIntentSender intentSender) {
- try {
- return mIActivityContainer.startActivityIntentSender(intentSender);
- } catch (RemoteException e) {
- throw new RuntimeException(
- "ActivityView: Unable to startActivity from IntentSender. " + e);
- }
+ final boolean displayReleased;
+ if (mVirtualDisplay != null) {
+ mVirtualDisplay.release();
+ mVirtualDisplay = null;
+ displayReleased = true;
+ } else {
+ displayReleased = false;
}
- int getDisplayId() {
- try {
- return mIActivityContainer.getDisplayId();
- } catch (RemoteException e) {
- return -1;
- }
+ if (mSurface != null) {
+ mSurface.release();
+ mSurface = null;
}
- boolean injectEvent(InputEvent event) {
- try {
- return mIActivityContainer.injectEvent(event);
- } catch (RemoteException e) {
- return false;
- }
+ if (displayReleased && mActivityViewCallback != null) {
+ mActivityViewCallback.onActivityViewDestroyed(this);
}
- void release() {
- synchronized (mGuard) {
- if (mOpened) {
- if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: release called");
- try {
- mIActivityContainer.release();
- mGuard.close();
- } catch (RemoteException e) {
- }
- mOpened = false;
- }
- }
- }
+ mGuard.close();
+ mOpened = false;
+ }
- @Override
- protected void finalize() throws Throwable {
- if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: finalize called");
- try {
- if (mGuard != null) {
- mGuard.warnIfOpen();
- release();
- }
- } finally {
- super.finalize();
+ /** Get density of the hosting display. */
+ private int getBaseDisplayDensity() {
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ final DisplayMetrics metrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(metrics);
+ return metrics.densityDpi;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (mGuard != null) {
+ mGuard.warnIfOpen();
+ performRelease();
}
+ } finally {
+ super.finalize();
}
-
}
}
diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl
deleted file mode 100644
index 1ff3c87bef6e..000000000000
--- a/core/java/android/app/IActivityContainer.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Copyright (c) 2013, 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.app;
-
-import android.app.IActivityContainerCallback;
-import android.content.Intent;
-import android.content.IIntentSender;
-import android.os.IBinder;
-import android.view.InputEvent;
-import android.view.Surface;
-
-/** @hide */
-interface IActivityContainer {
- void addToDisplay(int displayId);
- void setSurface(in Surface surface, int width, int height, int density);
- int startActivity(in Intent intent);
- int startActivityIntentSender(in IIntentSender intentSender);
- int getDisplayId();
- int getStackId();
- boolean injectEvent(in InputEvent event);
- void release();
-}
diff --git a/core/java/android/app/IActivityContainerCallback.aidl b/core/java/android/app/IActivityContainerCallback.aidl
deleted file mode 100644
index 99d0a6f8189e..000000000000
--- a/core/java/android/app/IActivityContainerCallback.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2013, 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.app;
-
-import android.os.IBinder;
-
-/** @hide */
-interface IActivityContainerCallback {
- oneway void setVisible(IBinder container, boolean visible);
- oneway void onAllActivitiesComplete(IBinder container);
-}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index df1a412d464e..fa9d7ca8ebc5 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -20,8 +20,6 @@ import android.app.ActivityManager;
import android.app.ApplicationErrorReport;
import android.app.ContentProviderHolder;
import android.app.IApplicationThread;
-import android.app.IActivityContainer;
-import android.app.IActivityContainerCallback;
import android.app.IActivityController;
import android.app.IAppTask;
import android.app.IInstrumentationWatcher;
@@ -355,8 +353,6 @@ interface IActivityManager {
void killUid(int appId, int userId, in String reason);
void setUserIsMonkey(boolean monkey);
void hang(in IBinder who, boolean allowRestart);
- IActivityContainer createVirtualActivityContainer(in IBinder parentActivityToken,
- in IActivityContainerCallback callback);
void moveTaskToStack(int taskId, int stackId, boolean toTop);
/**
* Resizes the input stack id to the given bounds.
@@ -436,7 +432,7 @@ interface IActivityManager {
// Start of M transactions
void notifyCleartextNetwork(int uid, in byte[] firstPacket);
- IActivityContainer createStackOnDisplay(int displayId);
+ int createStackOnDisplay(int displayId);
int getFocusedStackId();
void setTaskResizeable(int taskId, int resizeableMode);
boolean requestAssistContextExtras(int requestType, in IResultReceiver receiver,
diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml b/core/java/android/app/IInputForwarder.aidl
index acc3d16610ec..d6be63eb54e5 100644
--- a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/strings.xml
+++ b/core/java/android/app/IInputForwarder.aidl
@@ -1,5 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
/**
* Copyright (c) 2017, The Android Open Source Project
*
@@ -15,10 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="sysui_overlay_light">Light</string>
+package android.app;
-</resources>
+import android.view.InputEvent;
+/**
+ * Forwards input events into owned activity container, used in {@link android.app.ActivityView}.
+ * To forward input to other apps {@link android.Manifest.permission.INJECT_EVENTS} permission is
+ * required.
+ * @hide
+ */
+interface IInputForwarder {
+ boolean forwardEvent(in InputEvent event);
+} \ No newline at end of file
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 63a2cf002aa8..2d8249acb5bf 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -126,8 +126,8 @@ public abstract class Context {
* File creation mode: allow all other applications to have read access to
* the created file.
* <p>
- * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
- * mode will throw a {@link SecurityException}.
+ * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
+ * mode throws a {@link SecurityException}.
*
* @deprecated Creating world-readable files is very dangerous, and likely
* to cause security holes in applications. It is strongly
@@ -146,7 +146,7 @@ public abstract class Context {
* File creation mode: allow all other applications to have write access to
* the created file.
* <p>
- * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
+ * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
* mode will throw a {@link SecurityException}.
*
* @deprecated Creating world-writable files is very dangerous, and likely
@@ -1129,13 +1129,47 @@ public abstract class Context {
* </ul>
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
- * are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging to
- * other packages,
- * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
- * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * are required to read or write to the path that this method returns.
+ * However, starting from {@link android.os.Build.VERSION_CODES#M},
+ * to read the OBB expansion files, you must declare the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission in the app manifest and ask for
+ * permission at runtime as follows:
+ * </p>
+ * <p>
+ * {@code <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+ * android:maxSdkVersion="23" />}
+ * </p>
* <p>
+ * Starting from {@link android.os.Build.VERSION_CODES#N},
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
+ * permission is not required, so don’t ask for this
+ * permission at runtime. To handle both cases, your app must first try to read the OBB file,
+ * and if it fails, you must request
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission at runtime.
+ * </p>
+ *
+ * <p>
+ * The following code snippet shows how to do this:
+ * </p>
+ *
+ * <pre>
+ * File obb = new File(obb_filename);
+ * boolean open_failed = false;
+ *
+ * try {
+ * BufferedReader br = new BufferedReader(new FileReader(obb));
+ * open_failed = false;
+ * ReadObbFile(br);
+ * } catch (IOException e) {
+ * open_failed = true;
+ * }
+ *
+ * if (open_failed) {
+ * // request READ_EXTERNAL_STORAGE permission before reading OBB file
+ * ReadObbFileWithPermission();
+ * }
+ * </pre>
+ *
* On devices with multiple users (as described by {@link UserManager}),
* multiple users may share the same OBB storage location. Applications
* should ensure that multiple instances running under different users don't
diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java
index 663e6e476c5a..abf9cc91dbda 100644
--- a/core/java/android/content/SyncStatusInfo.java
+++ b/core/java/android/content/SyncStatusInfo.java
@@ -26,7 +26,7 @@ import java.util.ArrayList;
public class SyncStatusInfo implements Parcelable {
private static final String TAG = "Sync";
- static final int VERSION = 3;
+ static final int VERSION = 4;
private static final int MAX_EVENT_COUNT = 10;
@@ -102,6 +102,7 @@ public class SyncStatusInfo implements Parcelable {
parcel.writeLong(mLastEventTimes.get(i));
parcel.writeString(mLastEvents.get(i));
}
+ parcel.writeInt(numSourcePeriodic);
}
public SyncStatusInfo(Parcel parcel) {
@@ -146,6 +147,16 @@ public class SyncStatusInfo implements Parcelable {
}
}
}
+ if (version < 4) {
+ // Before version 4, numSourcePeriodic wasn't persisted.
+ numSourcePeriodic = numSyncs - numSourceLocal - numSourcePoll - numSourceServer
+ - numSourceUser;
+ if (numSourcePeriodic < 0) { // Sanity check.
+ numSourcePeriodic = 0;
+ }
+ } else {
+ numSourcePeriodic = parcel.readInt();
+ }
}
public SyncStatusInfo(SyncStatusInfo other) {
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 45863167fa1b..9e0c680cafa1 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -16,6 +16,7 @@
package android.hardware.input;
+import android.app.IInputForwarder;
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.IInputDevicesChangedListener;
@@ -88,4 +89,7 @@ interface IInputManager {
void setCustomPointerIcon(in PointerIcon icon);
void requestPointerCapture(IBinder windowToken, boolean enabled);
+
+ /** Create input forwarder to deliver touch events to owned display. */
+ IInputForwarder createInputForwarder(int displayId);
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 4898c1a0802f..c531a899f45d 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -19,8 +19,9 @@ package android.hardware.input;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
-import android.annotation.SystemService;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemService;
+import android.app.IInputForwarder;
import android.content.Context;
import android.media.AudioAttributes;
import android.os.Binder;
@@ -971,6 +972,25 @@ public final class InputManager {
}
}
+
+ /**
+ * Create an {@link IInputForwarder} targeted to provided display.
+ * {@link android.Manifest.permission.INJECT_EVENTS} permission is required to call this method.
+ *
+ * @param displayId Id of the target display where input events should be forwarded.
+ * Display must exist and must be owned by the caller.
+ * @return The forwarder instance.
+ *
+ * @hide
+ */
+ public IInputForwarder createInputForwarder(int displayId) {
+ try {
+ return mIm.createInputForwarder(displayId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
private void populateInputDevicesLocked() {
if (mInputDevicesChangedListener == null) {
final InputDevicesChangedListener listener = new InputDevicesChangedListener();
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 0e26ca215993..54d5860048ad 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -207,7 +207,7 @@ public abstract class BatteryStats implements Parcelable {
* New in version 22:
* - BLE scan result background count, BLE unoptimized scan time
*/
- static final String CHECKIN_VERSION = "23";
+ static final String CHECKIN_VERSION = "24";
/**
* Old version, we hit 9 and ran out of room, need to remove.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f5597b8eac8e..53c82e6c5237 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10132,22 +10132,6 @@ public final class Settings {
public static final String DEVICE_DEMO_MODE = "device_demo_mode";
/**
- * Retail mode specific settings. This is encoded as a key=value list, separated by commas.
- * Ex: "user_inactivity_timeout_ms=30000,warning_dialog_timeout_ms=10000". The following
- * keys are supported:
- *
- * <pre>
- * user_inactivity_timeout_ms (long)
- * warning_dialog_timeout_ms (long)
- * </pre>
- * <p>
- * Type: string
- *
- * @hide
- */
- public static final String RETAIL_DEMO_MODE_CONSTANTS = "retail_demo_mode_constants";
-
- /**
* Indicates the maximum time that an app is blocked for the network rules to get updated.
*
* Type: long
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index b22501823020..6ba11b9954c4 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -85,7 +85,7 @@ public class ZenModeConfig implements Parcelable {
private static final boolean DEFAULT_ALLOW_SCREEN_ON = true;
private static final int XML_VERSION = 2;
- private static final String ZEN_TAG = "zen";
+ public static final String ZEN_TAG = "zen";
private static final String ZEN_ATT_VERSION = "version";
private static final String ZEN_ATT_USER = "user";
private static final String ALLOW_TAG = "allow";
diff --git a/core/java/android/service/vr/IVrListener.aidl b/core/java/android/service/vr/IVrListener.aidl
index afb13d316503..acca3fa66ae4 100644
--- a/core/java/android/service/vr/IVrListener.aidl
+++ b/core/java/android/service/vr/IVrListener.aidl
@@ -20,5 +20,5 @@ import android.content.ComponentName;
/** @hide */
oneway interface IVrListener {
- void focusedActivityChanged(in ComponentName component);
+ void focusedActivityChanged(in ComponentName component, boolean running2dInVr, int pid);
}
diff --git a/core/java/android/service/vr/VrListenerService.java b/core/java/android/service/vr/VrListenerService.java
index 5da4560f688d..fa3d065d28a7 100644
--- a/core/java/android/service/vr/VrListenerService.java
+++ b/core/java/android/service/vr/VrListenerService.java
@@ -70,8 +70,10 @@ public abstract class VrListenerService extends Service {
private final IVrListener.Stub mBinder = new IVrListener.Stub() {
@Override
- public void focusedActivityChanged(ComponentName component) {
- mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, component).sendToTarget();
+ public void focusedActivityChanged(
+ ComponentName component, boolean running2dInVr, int pid) {
+ mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, running2dInVr ? 1 : 0,
+ pid, component).sendToTarget();
}
};
@@ -84,7 +86,8 @@ public abstract class VrListenerService extends Service {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ON_CURRENT_VR_ACTIVITY_CHANGED: {
- VrListenerService.this.onCurrentVrActivityChanged((ComponentName) msg.obj);
+ VrListenerService.this.onCurrentVrActivityChanged(
+ (ComponentName) msg.obj, msg.arg1 == 1, msg.arg2);
} break;
}
}
@@ -120,6 +123,29 @@ public abstract class VrListenerService extends Service {
}
/**
+ * An extended version of onCurrentVrActivityChanged
+ *
+ * <p>This will be called when this service is initially bound, but is not
+ * guaranteed to be called before onUnbind. In general, this is intended to be used to
+ * determine when user focus has transitioned between two VR activities, or between a
+ * VR activity and a 2D activity. This should be overridden instead of the above
+ * onCurrentVrActivityChanged as that version is deprecated.</p>
+ *
+ * @param component the {@link ComponentName} of the VR activity or the 2D intent.
+ * @param running2dInVr true if the component is a 2D component.
+ * @param pid the process the component is running in.
+ *
+ * @see android.app.Activity#setVrModeEnabled
+ * @see android.R.attr#enableVrMode
+ * @hide
+ */
+ public void onCurrentVrActivityChanged(
+ ComponentName component, boolean running2dInVr, int pid) {
+ // Override to implement. Default to old behaviour of sending null for 2D.
+ onCurrentVrActivityChanged(running2dInVr ? null : component);
+ }
+
+ /**
* Checks if the given component is enabled in user settings.
*
* <p>If this component is not enabled in the user's settings, it will not be started when
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 1b702326cc28..ecfc0b6cb00b 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -73,10 +73,12 @@ public class Surface implements Parcelable {
private static native long nativeGetNextFrameNumber(long nativeObject);
private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
- private static native void nativeSetBuffersTransform(long nativeObject, long transform);
private static native int nativeForceScopedDisconnect(long nativeObject);
private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
+ private static native int nativeSetSharedBufferModeEnabled(long nativeObject, boolean enabled);
+ private static native int nativeSetAutoRefreshEnabled(long nativeObject, boolean enabled);
+
public static final Parcelable.Creator<Surface> CREATOR =
new Parcelable.Creator<Surface>() {
@Override
@@ -114,6 +116,8 @@ public class Surface implements Parcelable {
private HwuiContext mHwuiContext;
private boolean mIsSingleBuffered;
+ private boolean mIsSharedBufferModeEnabled;
+ private boolean mIsAutoRefreshEnabled;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -630,6 +634,97 @@ public class Surface implements Parcelable {
}
/**
+ * <p>The shared buffer mode allows both the application and the surface compositor
+ * (SurfaceFlinger) to concurrently access this surface's buffer. While the
+ * application is still required to issue a present request
+ * (see {@link #unlockCanvasAndPost(Canvas)}) to the compositor when an update is required,
+ * the compositor may trigger an update at any time. Since the surface's buffer is shared
+ * between the application and the compositor, updates triggered by the compositor may
+ * cause visible tearing.</p>
+ *
+ * <p>The shared buffer mode can be used with
+ * {@link #setAutoRefreshEnabled(boolean) auto-refresh} to avoid the overhead of
+ * issuing present requests.</p>
+ *
+ * <p>If the application uses the shared buffer mode to reduce latency, it is
+ * recommended to use software rendering (see {@link #lockCanvas(Rect)} to ensure
+ * the graphics workloads are not affected by other applications and/or the system
+ * using the GPU. When using software rendering, the application should update the
+ * smallest possible region of the surface required.</p>
+ *
+ * <p class="note">The shared buffer mode might not be supported by the underlying
+ * hardware. Enabling shared buffer mode on hardware that does not support it will
+ * not yield an error but the application will not benefit from lower latency (and
+ * tearing will not be visible).</p>
+ *
+ * <p class="note">Depending on how many and what kind of surfaces are visible, the
+ * surface compositor may need to copy the shared buffer before it is displayed. When
+ * this happens, the latency benefits of shared buffer mode will be reduced.</p>
+ *
+ * @param enabled True to enable the shared buffer mode on this surface, false otherwise
+ *
+ * @see #isSharedBufferModeEnabled()
+ * @see #setAutoRefreshEnabled(boolean)
+ */
+ public void setSharedBufferModeEnabled(boolean enabled) {
+ if (mIsSharedBufferModeEnabled != enabled) {
+ int error = nativeSetSharedBufferModeEnabled(mNativeObject, enabled);
+ if (error != 0) {
+ throw new RuntimeException(
+ "Failed to set shared buffer mode on Surface (bad object?)");
+ } else {
+ mIsSharedBufferModeEnabled = enabled;
+ }
+ }
+ }
+
+ /**
+ * @return True if shared buffer mode is enabled on this surface, false otherwise
+ *
+ * @see #setSharedBufferModeEnabled(boolean)
+ */
+ public boolean isSharedBufferModeEnabled() {
+ return mIsSharedBufferModeEnabled;
+ }
+
+ /**
+ * <p>When auto-refresh is enabled, the surface compositor (SurfaceFlinger)
+ * automatically updates the display on a regular refresh cycle. The application
+ * can continue to issue present requests but it is not required. Enabling
+ * auto-refresh may result in visible tearing.</p>
+ *
+ * <p>Auto-refresh has no effect if the {@link #setSharedBufferModeEnabled(boolean)
+ * shared buffer mode} is not enabled.</p>
+ *
+ * <p>Because auto-refresh will trigger continuous updates of the display, it is
+ * recommended to turn it on only when necessary. For example, in a drawing/painting
+ * application auto-refresh should be enabled on finger/pen down and disabled on
+ * finger/pen up.</p>
+ *
+ * @param enabled True to enable auto-refresh on this surface, false otherwise
+ *
+ * @see #isAutoRefreshEnabled()
+ * @see #setSharedBufferModeEnabled(boolean)
+ */
+ public void setAutoRefreshEnabled(boolean enabled) {
+ if (mIsAutoRefreshEnabled != enabled) {
+ int error = nativeSetAutoRefreshEnabled(mNativeObject, enabled);
+ if (error != 0) {
+ throw new RuntimeException("Failed to set auto refresh on Surface (bad object?)");
+ } else {
+ mIsAutoRefreshEnabled = enabled;
+ }
+ }
+ }
+
+ /**
+ * @return True if auto-refresh is enabled on this surface, false otherwise
+ */
+ public boolean isAutoRefreshEnabled() {
+ return mIsAutoRefreshEnabled;
+ }
+
+ /**
* Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
* when a SurfaceTexture could not successfully be allocated.
*/
@@ -656,13 +751,13 @@ public class Surface implements Parcelable {
return "ROTATION_0";
}
case Surface.ROTATION_90: {
- return "ROATATION_90";
+ return "ROTATION_90";
}
case Surface.ROTATION_180: {
- return "ROATATION_180";
+ return "ROTATION_180";
}
case Surface.ROTATION_270: {
- return "ROATATION_270";
+ return "ROTATION_270";
}
default: {
throw new IllegalArgumentException("Invalid rotation: " + rotation);
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
index 68cf5cd74431..477285e63f37 100644
--- a/core/java/com/android/internal/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -29,7 +29,9 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.types.ExtractionType;
import com.android.internal.colorextraction.types.Tonal;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Iterator;
/**
* Class to process wallpaper colors and generate a tonal palette based on them.
@@ -44,7 +46,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
private static final String TAG = "ColorExtractor";
private final SparseArray<GradientColors[]> mGradientColors;
- private final ArrayList<OnColorsChangedListener> mOnColorsChangedListeners;
+ private final ArrayList<WeakReference<OnColorsChangedListener>> mOnColorsChangedListeners;
private final Context mContext;
private final ExtractionType mExtractionType;
private WallpaperColors mSystemColors;
@@ -167,8 +169,17 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
}
protected void triggerColorsChanged(int which) {
- for (OnColorsChangedListener listener: mOnColorsChangedListeners) {
- listener.onColorsChanged(this, which);
+ ArrayList<WeakReference<OnColorsChangedListener>> references =
+ new ArrayList<>(mOnColorsChangedListeners);
+ final int size = references.size();
+ for (int i = 0; i < size; i++) {
+ final WeakReference<OnColorsChangedListener> weakReference = references.get(i);
+ final OnColorsChangedListener listener = weakReference.get();
+ if (listener == null) {
+ mOnColorsChangedListeners.remove(weakReference);
+ } else {
+ listener.onColorsChanged(this, which);
+ }
}
}
@@ -187,11 +198,20 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
}
public void addOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
- mOnColorsChangedListeners.add(listener);
+ mOnColorsChangedListeners.add(new WeakReference<>(listener));
}
public void removeOnColorsChangedListener(@NonNull OnColorsChangedListener listener) {
- mOnColorsChangedListeners.remove(listener);
+ ArrayList<WeakReference<OnColorsChangedListener>> references =
+ new ArrayList<>(mOnColorsChangedListeners);
+ final int size = references.size();
+ for (int i = 0; i < size; i++) {
+ final WeakReference<OnColorsChangedListener> weakReference = references.get(i);
+ if (weakReference.get() == listener) {
+ mOnColorsChangedListeners.remove(weakReference);
+ break;
+ }
+ }
}
public static class GradientColors {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5129cf5c1ef3..cad1b7c51a54 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -6616,9 +6616,12 @@ public class BatteryStatsImpl extends BatteryStats {
* inactive so can be dropped.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public boolean reset() {
+ public boolean reset(long uptime, long realtime) {
boolean active = false;
+ mOnBatteryBackgroundTimeBase.init(uptime, realtime);
+ mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime);
+
if (mWifiRunningTimer != null) {
active |= !mWifiRunningTimer.reset(false);
active |= mWifiRunning;
@@ -6806,11 +6809,6 @@ public class BatteryStatsImpl extends BatteryStats {
mLastStepUserTime = mLastStepSystemTime = 0;
mCurStepUserTime = mCurStepSystemTime = 0;
- mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
- mBsi.mClocks.uptimeMillis() * 1000);
- mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
- mBsi.mClocks.uptimeMillis() * 1000);
-
if (!active) {
if (mWifiRunningTimer != null) {
mWifiRunningTimer.detach();
@@ -9463,7 +9461,7 @@ public class BatteryStatsImpl extends BatteryStats {
mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
for (int i=0; i<mUidStats.size(); i++) {
- if (mUidStats.valueAt(i).reset()) {
+ if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) {
mUidStats.remove(mUidStats.keyAt(i));
i--;
}
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 215a00e7384c..3ad4da6b6580 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -537,6 +537,20 @@ static jint nativeAttachAndQueueBuffer(JNIEnv *env, jclass clazz, jlong nativeOb
return err;
}
+static jint nativeSetSharedBufferModeEnabled(JNIEnv* env, jclass clazz, jlong nativeObject,
+ jboolean enabled) {
+ Surface* surface = reinterpret_cast<Surface*>(nativeObject);
+ return ((ANativeWindow*) nativeObject)->perform(surface,
+ NATIVE_WINDOW_SET_SHARED_BUFFER_MODE, enabled);
+}
+
+static jint nativeSetAutoRefreshEnabled(JNIEnv* env, jclass clazz, jlong nativeObject,
+ jboolean enabled) {
+ Surface* surface = reinterpret_cast<Surface*>(nativeObject);
+ return ((ANativeWindow*) nativeObject)->perform(surface,
+ NATIVE_WINDOW_SET_AUTO_REFRESH, enabled);
+}
+
namespace uirenderer {
using namespace android::uirenderer::renderthread;
@@ -618,6 +632,8 @@ static const JNINativeMethod gSurfaceMethods[] = {
{"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode },
{"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect},
{"nativeAttachAndQueueBuffer", "(JLandroid/graphics/GraphicBuffer;)I", (void*)nativeAttachAndQueueBuffer},
+ {"nativeSetSharedBufferModeEnabled", "(JZ)I", (void*)nativeSetSharedBufferModeEnabled},
+ {"nativeSetAutoRefreshEnabled", "(JZ)I", (void*)nativeSetAutoRefreshEnabled},
// HWUI context
{"nHwuiCreate", "(JJ)J", (void*) hwui::create },
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index e212c432558c..fa645f4d4c6a 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -315,7 +315,6 @@ message GlobalSettingsProto {
SettingProto boot_count = 270;
SettingProto safe_boot_disallowed = 271;
SettingProto device_demo_mode = 272;
- SettingProto retail_demo_mode_constants = 273;
SettingProto database_downgrade_reason = 274;
SettingProto contacts_database_wal_enabled = 275;
SettingProto multi_sim_voice_call_subscription = 276;
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index a35d61d544bd..5f894afbd61a 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Titelloos&gt;"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 9f67ea29c20d..de6ad70b4102 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"ኪባ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;ርዕስ አልባ&gt;"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index cc277561dec6..cad9ceb3fef4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"بايت"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"كيلوبايت"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"ميغابايت"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"غيغابايت"</string>
- <string name="terabyteShort" msgid="231613018159186962">"تيرابايت"</string>
<string name="petabyteShort" msgid="5637816680144990219">"بيتابايت"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"‏&lt;بلا عنوان&gt;"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index dad5802ec0c6..ae042bfba99a 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"Başlıqsız"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5f1ca49c6105..69038190aa68 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 7ec47510e490..5be57f6ce594 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"б"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"Тб"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Пб"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Без назвы&gt;"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index e61e49c981db..6303961bf40e 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"Б"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Без заглавие&gt;"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 939a45ca4b7a..4a4d938b1217 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"বাইট"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;শিরোনামহীন&gt;"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 1c1ec2565254..83e07dd4f389 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0dbae8b3973c..5ca03baef05a 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sense títol&gt;"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index a3072dcf603f..adf37f2466ee 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez názvu&gt;"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 22d4c3af1df5..c2ddb43f52d8 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"b"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Mb"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"Tb"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Pb"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Uden titel&gt;"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index b22322430af4..23df4b305308 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Unbenannt&gt;"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 88440cb1dfbf..15091c5378d4 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Χωρίς τίτλο&gt;"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 9b5528c32e1f..f3e01e2d3206 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9b5528c32e1f..f3e01e2d3206 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 9b5528c32e1f..f3e01e2d3206 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 5bf170bc4bbc..49b1837c5e1a 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sin título&gt;"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 6c5e7e566398..28aaff0b0cf5 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sin título&gt;"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index b4d4cff5c4c4..5f7802fc9cae 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Pealkirjata&gt;"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index b5234a8e3154..e72b12b09b85 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Izengabea&gt;"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9aeae4aff957..57e4317b5883 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"بایت"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"کیلوبایت"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"مگابایت"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"گیگابایت"</string>
- <string name="terabyteShort" msgid="231613018159186962">"ترابایت"</string>
<string name="petabyteShort" msgid="5637816680144990219">"پتابایت"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> ‏<xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"‏&lt;بدون عنوان&gt;"</string>
@@ -233,7 +229,7 @@
<string name="global_action_assist" msgid="3892832961594295030">"دستیار"</string>
<string name="global_action_voice_assist" msgid="7751191495200504480">"دستیار صوتی"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string>
- <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string>
+ <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"۹۹۹+"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string>
<string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"محتوا بر اساس خط‌مشی پنهان شده است"</string>
<string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"صفحه‌‌کلید مجازی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 44c5efa6c50b..4d1a8ef3b87c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"t"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kt"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Mt"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"Gt"</string>
- <string name="terabyteShort" msgid="231613018159186962">"Tt"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Pt"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Nimetön&gt;"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index c6881825bfe1..c31240d6143c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"o"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"ko"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Mo"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
- <string name="terabyteShort" msgid="231613018159186962">"To"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sans_titre&gt;"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a5c9b0f9c4fb..67962751125c 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"octet(s)"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"Ko"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Mo"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
- <string name="terabyteShort" msgid="231613018159186962">"To"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sans nom&gt;"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 8db169b0276e..fe39fc604286 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sen título&gt;"</string>
@@ -459,7 +455,7 @@
<string name="permlab_nfc" msgid="4423351274757876953">"controlar Near Field Communication"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Permite á aplicación comunicarse con etiquetas, tarxetas e lectores Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivar o bloqueo da pantalla"</string>
- <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguridade dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string>
+ <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguranza dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"xestionar hardware de impresión dixital"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"Permite que a aplicación invoque métodos para engadir e eliminar modelos de uso de impresión dixital."</string>
<string name="permlab_useFingerprint" msgid="3150478619915124905">"usar hardware de impresión dixital"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 8745c647816c..abc8da093346 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;અનામાંકિત&gt;"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index bffede48084f..cc86ecbc82a4 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;शीर्षक-रहित&gt;"</string>
@@ -516,10 +512,10 @@
<string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"ऐप्स को नेटवर्क नीतियां प्रबंधित करने और ऐप्स-विशिष्‍ट नियमों को परिभाषित करने देता है."</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क उपयोग हिसाब बदलें"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"ऐप्स को यह संशोधित करने देता है कि ऐप्स की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्‍य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string>
- <string name="permlab_accessNotifications" msgid="7673416487873432268">"नोटिफिकेशन तक पहुंचें"</string>
- <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप्स को नोटिफिकेशन को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य ऐप्स के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string>
- <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"नोटिफिकेशन श्रवणकर्ता सेवा से जुड़ें"</string>
- <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफिकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
+ <string name="permlab_accessNotifications" msgid="7673416487873432268">"नोटिफ़िकेशन तक पहुंचें"</string>
+ <string name="permdesc_accessNotifications" msgid="458457742683431387">"ऐप्स को नोटिफ़िकेशन को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य ऐप्स के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string>
+ <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"नोटिफ़िकेशन श्रवणकर्ता सेवा से जुड़ें"</string>
+ <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"धारक को नोटिफ़िकेशन श्रवणकर्ता सेवा के शीर्ष स्तरीय इंटरफ़ेस से जुड़ने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होनी चाहिए."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"किसी स्थिति प्रदाता सेवा से आबद्ध हों"</string>
<string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"धारक को किसी स्थिति प्रदाता सेवा के शीर्ष-स्तर के इंटरफ़ेस से आबद्ध होने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindDreamService" msgid="4153646965978563462">"भावी सेवा से आबद्ध करें"</string>
@@ -1072,13 +1068,13 @@
<string name="volume_call" msgid="3941680041282788711">"कॉल के दौरान वॉल्‍यूम"</string>
<string name="volume_bluetooth_call" msgid="2002891926351151534">"ब्लूटूथ कॉल के दौरान वॉल्‍यूम"</string>
<string name="volume_alarm" msgid="1985191616042689100">"अलार्म वॉल्‍यूम"</string>
- <string name="volume_notification" msgid="2422265656744276715">"नोटिफिकेशन वॉल्‍यूम"</string>
+ <string name="volume_notification" msgid="2422265656744276715">"नोटिफ़िकेशन वॉल्‍यूम"</string>
<string name="volume_unknown" msgid="1400219669770445902">"आवाज़"</string>
<string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"ब्लूटूथ वॉल्‍यूम"</string>
<string name="volume_icon_description_ringer" msgid="3326003847006162496">"रिंगटोन वॉल्‍यूम"</string>
<string name="volume_icon_description_incall" msgid="8890073218154543397">"कॉल वॉल्‍यूम"</string>
<string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया वॉल्‍यूम"</string>
- <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफिकेशन वॉल्‍यूम"</string>
+ <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफ़िकेशन वॉल्‍यूम"</string>
<string name="ringtone_default" msgid="3789758980357696936">"डिफ़ॉल्‍ट रिंगटोन"</string>
<string name="ringtone_default_with_actual" msgid="1767304850491060581">"डिफ़ॉल्ट (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"कोई नहीं"</string>
@@ -1277,7 +1273,7 @@
<string name="accessibility_binding_label" msgid="4148120742096474641">"सरल उपयोग"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"वॉलपेपर"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"वॉलपेपर बदलें"</string>
- <string name="notification_listener_binding_label" msgid="2014162835481906429">"नोटिफिकेशन श्रवणकर्ता"</string>
+ <string name="notification_listener_binding_label" msgid="2014162835481906429">"नोटिफ़िकेशन श्रवणकर्ता"</string>
<string name="vr_listener_binding_label" msgid="4316591939343607306">"VR श्रोता"</string>
<string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति प्रदाता"</string>
<string name="notification_ranker_binding_label" msgid="774540592299064747">"नोटिफ़िकेशन रैंकर सेवा"</string>
@@ -1691,7 +1687,7 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
</plurals>
<string name="default_notification_channel_label" msgid="5929663562028088222">"अवर्गीकृत"</string>
- <string name="importance_from_user" msgid="7318955817386549931">"आपने इन नोटिफिकेशन का महत्व सेट किया है."</string>
+ <string name="importance_from_user" msgid="7318955817386549931">"आपने इन नोटिफ़िकेशन का महत्व सेट किया है."</string>
<string name="importance_from_person" msgid="9160133597262938296">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string>
<string name="user_creation_account_exists" msgid="1942606193570143289">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें?"</string>
<string name="user_creation_adding" msgid="4482658054622099197">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के द्वारा एक नया उपयोगकर्ता बनाने दें (इस खाते वाला एक उपयोगकर्ता पहले से मौजूद है) ?"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 094af8d8110a..89c5d03afc16 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 29a79e54c890..c7a498c232be 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Névtelen&gt;"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 7cf7507e9100..b47cded04fe9 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"Բ"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"կԲ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"ՄԲ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ԳԲ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"ՏԲ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Անանուն&gt;"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 81fe2471a59e..ed04809d2629 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Tanpa judul&gt;"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 2ce334e187d9..5ba15a31bdc0 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Ónefnt&gt;"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 29ebdd8b4f3b..8272d11ea009 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Senza nome&gt;"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 426442c0734c..06ee4ac753f0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"‏&gt;ללא כותרת&lt;"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 0dcc4e013a1c..1206432ab158 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;新規&gt;"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 0ff01ab2100f..e4e8d30f10cf 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"ბაიტი"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"კბაიტი"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"მბაიტი"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"გბაიტი"</string>
- <string name="terabyteShort" msgid="231613018159186962">"ტბაიტი"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"უსათაურო"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 08e1e912391b..a56f246a671e 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"Б"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MБ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Атаусыз&gt;"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index f841721562d4..ef88958abf22 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"មេកាបៃ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ជីកាបៃ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"តេរ៉ាបៃ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;គ្មាន​ចំណង​ជើង&gt;"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 7527362f7aad..76af3638d156 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;ಶೀರ್ಷಿಕೆ ರಹಿತ&gt;"</string>
@@ -1094,7 +1090,7 @@
<item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
<item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
</plurals>
- <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string>
+ <string name="wifi_available_title" msgid="3817100557900599505">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಿ"</string>
<string name="wifi_available_title_connecting" msgid="1557292688310330032">"ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="wifi_available_title_connected" msgid="7542672851522241548">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
<string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
@@ -1419,7 +1415,7 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೊ"</string>
<string name="wireless_display_route_description" msgid="9070346425023979651">"ವಯರ್‌ಲೆಸ್ ಪ್ರದರ್ಶನ"</string>
<string name="media_route_button_content_description" msgid="591703006349356016">"ಪಾತ್ರ"</string>
- <string name="media_route_chooser_title" msgid="1751618554539087622">"ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಿ"</string>
+ <string name="media_route_chooser_title" msgid="1751618554539087622">"ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಿಸಿ"</string>
<string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ಸಾಧನಕ್ಕೆ ಬಿತ್ತರಿಸುವ ಪರದೆ"</string>
<string name="media_route_chooser_searching" msgid="4776236202610828706">"ಸಾಧನಗಳನ್ನು ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string>
<string name="media_route_chooser_extended_settings" msgid="87015534236701604">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index bab45194f54f..f1b7a01ce2d8 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;제목 없음&gt;"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 284253760f97..9daaf88ddfa9 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"Б"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"Кб"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"Гб"</string>
- <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Баш аты жок&gt;"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 52d5b0b4b8cf..a65b319be20c 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;ບໍ່ມີຊື່&gt;"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index a31dcc7e831e..befddc4f6817 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Be pavadinimo&gt;"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8cc3d909cb62..8970f5a84e4e 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez nosaukuma&gt;"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index efac04215fe9..43235219f09c 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"Б"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Без наслов&gt;"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 4f8d39dd6c3f..3ba18fead433 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;ശീർഷകമില്ലാത്ത&gt;"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 65b6b5b0a869..409e2247f9d9 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"килобайт"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Гарчиггүй&gt;"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index ea3705fae574..afd547703096 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;अशीर्षकांकित&gt;"</string>
@@ -191,7 +187,7 @@
<string name="silent_mode_vibrate" msgid="7072043388581551395">"रिंगर कंपन"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"रिंगर चालू"</string>
<string name="reboot_to_update_title" msgid="6212636802536823850">"Android सिस्टीम अद्यतन"</string>
- <string name="reboot_to_update_prepare" msgid="6305853831955310890">"अद्यतनित करण्यासाठी तयार करीत आहे…"</string>
+ <string name="reboot_to_update_prepare" msgid="6305853831955310890">"अपडेट करण्याची तयारी करत आहे…"</string>
<string name="reboot_to_update_package" msgid="3871302324500927291">"अद्यतन पॅकेजची प्रक्रिया करीत आहे…"</string>
<string name="reboot_to_update_reboot" msgid="6428441000951565185">"रीस्टार्ट करीत आहे..."</string>
<string name="reboot_to_reset_title" msgid="4142355915340627490">"फॅक्‍टरी डेटा रीसेट"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index f322d4ee581b..c2804566a4ca 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B."</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Tidak bertajuk&gt;"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 7234cd955f32..2f3a0d5a3238 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;ခေါင်းစဉ်မဲ့&gt;"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index dabe298900b2..4eca1657e892 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Uten navn&gt;"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 44f17bcb3b23..4d8dfc661562 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"के.बि."</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;बिना शीर्षक&gt;"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3c1f06775fbf..3e78d71d5b83 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">" KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Naamloos&gt;"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 64d267ee8e27..3f55342f8cff 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;ਬਿਨਾਂ ਸਿਰਲੇਖ&gt;"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 1747f2759d6d..cf786e5dbf13 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez nazwy&gt;"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 05af3261c9ea..22f8a3e5629c 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sem título&gt;"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 04a78cab1a17..068723bc3af2 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sem nome&gt;"</string>
@@ -51,7 +47,7 @@
<string name="needPuk2" msgid="4526033371987193070">"Introduza o PUK2 para desbloquear o cartão SIM."</string>
<string name="enablePin" msgid="209412020907207950">"Ação sem êxito. Ative o bloqueio do SIM/RUIM."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
- <item quantity="one">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+ <item quantity="one">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativa antes de o cartão SIM ficar bloqueado.</item>
<item quantity="other">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar bloqueado.</item>
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
@@ -164,7 +160,7 @@
<string name="low_memory" product="tv" msgid="516619861191025923">"O armazenamento da TV está cheio. Elimine alguns ficheiros para libertar espaço."</string>
<string name="low_memory" product="default" msgid="3475999286680000541">"O armazenamento do telemóvel está cheio. Elimine alguns ficheiros para libertar espaço."</string>
<plurals name="ssl_ca_cert_warning" formatted="false" msgid="5106721205300213569">
- <item quantity="one">Certificate authorities installed</item>
+ <item quantity="one">Autoridade de certificação instalada</item>
<item quantity="other">Autoridades de certificação instaladas</item>
</plurals>
<string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Por um terceiro desconhecido"</string>
@@ -220,7 +216,7 @@
<string name="bugreport_option_full_title" msgid="6354382025840076439">"Relatório completo"</string>
<string name="bugreport_option_full_summary" msgid="7210859858969115745">"Utilize esta opção para uma interferência mínima do sistema quando o dispositivo não responder ou estiver demasiado lento, ou quando precisar de todas as secções de relatório. Não permite introduzir mais detalhes ou tirar capturas de ecrã adicionais."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
- <item quantity="one">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
+ <item quantity="one">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundo…</item>
<item quantity="other">A tirar uma captura de ecrã do relatório de erro dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos.</item>
</plurals>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
@@ -856,7 +852,7 @@
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Há 1 mês"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Há mais de 1 mês"</string>
<plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
- <item quantity="one">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one">Últimos <xliff:g id="COUNT_1">%d</xliff:g> dia</item>
<item quantity="other">Últimos <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
</plurals>
<string name="last_month" msgid="3959346739979055432">"Último mês"</string>
@@ -878,67 +874,67 @@
<string name="years" msgid="6881577717993213522">"anos"</string>
<string name="now_string_shortest" msgid="8912796667087856402">"agora"</string>
<plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
- <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
</plurals>
<plurals name="duration_hours_shortest" formatted="false" msgid="3552182110578602356">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
- <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest" formatted="false" msgid="5213655532597081640">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
- <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> d</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> d</item>
</plurals>
<plurals name="duration_years_shortest" formatted="false" msgid="7848711145196397042">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
- <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>a</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_shortest_future" formatted="false" msgid="3277614521231489951">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
- <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>m</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> min</item>
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> min</item>
</plurals>
<plurals name="duration_hours_shortest_future" formatted="false" msgid="2152452368397489370">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
- <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>h</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> h</item>
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> h</item>
</plurals>
<plurals name="duration_days_shortest_future" formatted="false" msgid="8088331502820295701">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
- <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>d</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> d</item>
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> d</item>
</plurals>
<plurals name="duration_years_shortest_future" formatted="false" msgid="2317006667145250301">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
- <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>a</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> a</item>
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
+ <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> minuto</item>
<item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
+ <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> hora</item>
<item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
</plurals>
<plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
+ <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> dia</item>
<item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
</plurals>
<plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
- <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
+ <item quantity="one">há <xliff:g id="COUNT_1">%d</xliff:g> ano</item>
<item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
</plurals>
<plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> minuto</item>
<item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
</plurals>
<plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> hora</item>
<item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
</plurals>
<plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> dia</item>
<item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
</plurals>
<plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
- <item quantity="one">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_1">%d</xliff:g> ano</item>
<item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
</plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problema com o vídeo"</string>
@@ -1087,11 +1083,11 @@
<string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificação"</string>
<string name="ringtone_unknown" msgid="3914515995813061520">"Desconhecido"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
- <item quantity="one">Wi-Fi networks available</item>
+ <item quantity="one">Rede Wi-Fi disponível</item>
<item quantity="other">Redes Wi-Fi disponíveis</item>
</plurals>
<plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
- <item quantity="one">Open Wi-Fi networks available</item>
+ <item quantity="one">Rede Wi-Fi aberta disponível</item>
<item quantity="other">Redes Wi-Fi abertas disponíveis</item>
</plurals>
<string name="wifi_available_title" msgid="3817100557900599505">"Ligar à rede Wi-Fi aberta"</string>
@@ -1304,7 +1300,7 @@
<string name="no_matches" msgid="8129421908915840737">"Sem correspondências"</string>
<string name="find_on_page" msgid="1946799233822820384">"Localizar na página"</string>
<plurals name="matches_found" formatted="false" msgid="1210884353962081884">
- <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
+ <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Concluído"</string>
@@ -1590,7 +1586,7 @@
<string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Os PINs não correspondem. Tente novamente."</string>
<string name="restr_pin_error_too_short" msgid="8173982756265777792">"O PIN é demasiado pequeno. Deve ter, no mínimo, 4 dígitos."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
- <item quantity="one">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
+ <item quantity="one">Tente novamente dentro de <xliff:g id="COUNT">%d</xliff:g> segundo</item>
<item quantity="other">Tente novamente dentro de <xliff:g id="COUNT">%d</xliff:g> segundos</item>
</plurals>
<string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string>
@@ -1623,35 +1619,35 @@
<string name="data_saver_enable_title" msgid="4674073932722787417">"Ativar a Poupança de dados?"</string>
<string name="data_saver_enable_button" msgid="7147735965247211818">"Ativar"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
- <item quantity="one">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
- <item quantity="other">Durante %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">Durante %1$d minuto (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="other">Durante %1$d minutos (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="6830154222366042597">
- <item quantity="one">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
- <item quantity="other">Durante %1$d min (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">Durante %1$d min (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="other">Durante %1$d min (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
- <item quantity="one">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
- <item quantity="other">Durante %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">Durante %1$d hora (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="other">Durante %1$d horas (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="4787552595253082371">
- <item quantity="one">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
- <item quantity="other">Durante %1$d h (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="one">Durante %1$d h (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+ <item quantity="other">Durante %1$d h (até à(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
- <item quantity="one">For %d minutes</item>
+ <item quantity="one">Durante %d minuto</item>
<item quantity="other">Durante %d minutos</item>
</plurals>
<plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2199350154433426128">
- <item quantity="one">For %d min</item>
+ <item quantity="one">Durante %d min</item>
<item quantity="other">Durante %d min</item>
</plurals>
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
- <item quantity="one">For %d hours</item>
+ <item quantity="one">Durante %d hora</item>
<item quantity="other">Durante %d horas</item>
</plurals>
<plurals name="zen_mode_duration_hours_short" formatted="false" msgid="6748277774662434217">
- <item quantity="one">For %d hr</item>
+ <item quantity="one">Durante %d h</item>
<item quantity="other">Durante %d h</item>
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1687,7 +1683,7 @@
<string name="close_button_text" msgid="3937902162644062866">"Fechar"</string>
<string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<plurals name="selected_count" formatted="false" msgid="7187339492915744615">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
</plurals>
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sem categoria"</string>
@@ -1751,7 +1747,7 @@
<string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Não é possível preencher automaticamente o conteúdo"</string>
<string name="autofill_picker_no_suggestions" msgid="3908514303773350735">"Sem sugestões do preenchimento automático"</string>
<plurals name="autofill_picker_some_suggestions" formatted="false" msgid="5506565809835815274">
- <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
+ <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> sugestão do preenchimento automático</item>
<item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> sugestões do preenchimento automático</item>
</plurals>
<string name="autofill_save_title" msgid="3345527308992082601">"Pretende guardar no &lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;?"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 05af3261c9ea..22f8a3e5629c 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Sem título&gt;"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 795b71be31f4..84e1c968f8f6 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TO"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PO"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Fără titlu&gt;"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d22022d88b4d..b441503994b2 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"Б"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"КБ"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Без названия&gt;"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 0292f82bf37c..bc1e43333c79 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;නම් යොදා නැත&gt;"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4c22ae7ea01d..f93a9bf4f5ad 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez mena&gt;"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ac24366aadc1..4d3c3b2acf63 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Brez naslova&gt;"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index c31c8a4b9d88..a677d71e8844 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"terabajt"</string>
<string name="petabyteShort" msgid="5637816680144990219">"petabajt"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Pa titull&gt;"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 02dddb882bd7..319f0001eb7f 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Без наслова&gt;"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index b1a13511ecd7..808681c3e90e 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Okänd&gt;"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2eb17206205d..afac1d3bcd0c 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Haina jina&gt;"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 714602ffe568..06406c62635f 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"பை."</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"கி.பை."</string>
- <string name="megabyteShort" msgid="6355851576770428922">"மெ.பை."</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"ஜி.பை."</string>
- <string name="terabyteShort" msgid="231613018159186962">"டெ.பை."</string>
<string name="petabyteShort" msgid="5637816680144990219">"பெ.பை."</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;பெயரிடப்படாதது&gt;"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 92fba6ea1f5a..2a6c5b72050d 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;శీర్షిక లేనిది&gt;"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 3c33686d1a85..87a00b2b34ab 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;ไม่มีชื่อ&gt;"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 2976911b3a73..866292f22d49 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Walang pamagat&gt;"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 48c714b64658..58a69e55160c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Adsız&gt;"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 715a019d85d7..9399176cf25a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"б"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"Кб"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"Мб"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"Гб"</string>
- <string name="terabyteShort" msgid="231613018159186962">"Тб"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Пб"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Без назви&gt;"</string>
@@ -1015,7 +1011,7 @@
<string name="browse" msgid="6993590095938149861">"Веб-переглядач"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"Закінчується пам’ять"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"Деякі системні функції можуть не працювати"</string>
- <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 Мб вільного місця, і повторіть спробу."</string>
+ <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 МБ вільного місця, і повторіть спробу."</string>
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> працює"</string>
<string name="app_running_notification_text" msgid="1197581823314971177">"Торкніться, щоб дізнатися більше або зупинити додаток."</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index ca753697142e..33f74daa443c 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"بائٹس"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"‏‎&gt;‎بلا عنوان‎&lt;‎"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index e26289386e2e..07f41fc94137 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Nomsiz&gt;"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 73a65b727e6d..661ff16040d2 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Không có tiêu đề&gt;"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index dc0395adf6dd..40ab9e449e9b 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 57798ee01ad6..8644877153f4 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 39564ea543fc..9b1d9523464e 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"位元組"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"KB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 85180965d084..d144ad7e7d20 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -21,10 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="byteShort" msgid="8340973892742019101">"B"</string>
- <string name="kilobyteShort" msgid="7542884022844556968">"kB"</string>
- <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
- <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
- <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Akunasihloko&gt;"</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8c26db43fc41..65c52792226b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4538,22 +4538,10 @@
<!-- The representation of a time duration when negative. An example is -1:14. This can be used with a countdown timer for example.-->
<string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string>
- <!-- Title of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] -->
- <string name="reset_retail_demo_mode_title">Reset device?</string>
- <!-- Text of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] -->
- <string name="reset_retail_demo_mode_text">Tap to reset device</string>
<!-- Text of dialog shown when starting a demo user for the first time [CHAR LIMIT=40] -->
<string name="demo_starting_message">Starting demo\u2026</string>
<!-- Text of dialog shown when starting a new demo user in retail demo mode [CHAR LIMIT=40] -->
<string name="demo_restarting_message">Resetting device\u2026</string>
- <!-- Title of the dialog shown when user inactivity times out in retail demo mode [CHAR LIMIT=40] -->
- <string name="demo_user_inactivity_timeout_title">Reset device?</string>
- <!-- Warning message shown when user inactivity times out in retail demo mode [CHAR LIMIT=none] -->
- <string name="demo_user_inactivity_timeout_countdown">You\u2019ll lose any changes and the demo will start again in <xliff:g id="timeout" example="9">%1$s</xliff:g> seconds\u2026</string>
- <!-- Text of button to allow user to abort countdown and continue current session in retail demo mode [CHAR LIMIT=40] -->
- <string name="demo_user_inactivity_timeout_left_button">Cancel</string>
- <!-- Text of button to allow user to abort countdown and immediately start another session in retail demo mode [CHAR LIMIT=40] -->
- <string name="demo_user_inactivity_timeout_right_button">Reset now</string>
<!-- Accessibilty string added to a widget that has been suspended [CHAR LIMIT=20] -->
<string name="suspended_widget_accessibility">Disabled <xliff:g id="label" example="Calendar">%1$s</xliff:g></string>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 949fd166c14c..e292c9dfbe67 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -304,7 +304,6 @@ public class SettingsBackupTest {
Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT,
- Settings.Global.RETAIL_DEMO_MODE_CONSTANTS,
Settings.Global.SAFE_BOOT_DISALLOWED,
Settings.Global.SAMPLING_PROFILER_MS,
Settings.Global.SELINUX_STATUS,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
index af4a6d92cea6..8fd4e3110569 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
@@ -400,7 +400,7 @@ public class BatteryStatsSensorTest extends TestCase {
assertNotNull(sensor.getSensorBackgroundTime());
// Reset the stats. Since the sensor is still running, we should still see the timer
- bi.getUidStatsLocked(UID).reset();
+ bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
sensor = uid.getSensorStats().get(SENSOR_ID);
assertNotNull(sensor);
@@ -410,9 +410,111 @@ public class BatteryStatsSensorTest extends TestCase {
bi.noteStopSensorLocked(UID, SENSOR_ID);
// Now the sensor timer has stopped so this reset should also take out the sensor.
- bi.getUidStatsLocked(UID).reset();
+ bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
sensor = uid.getSensorStats().get(SENSOR_ID);
assertNull(sensor);
}
+
+ @SmallTest
+ public void testSensorResetTimes() throws Exception {
+ final MockClocks clocks = new MockClocks();
+ MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+ final int which = BatteryStats.STATS_SINCE_CHARGED;
+ bi.mForceOnBattery = true;
+ clocks.realtime = 100; // in ms
+ clocks.uptime = 100; // in ms
+
+ // TimeBases are on for some time.
+ BatteryStatsImpl.TimeBase timeBase = bi.getOnBatteryTimeBase();
+ BatteryStatsImpl.TimeBase bgTimeBase = bi.getOnBatteryBackgroundTimeBase(UID);
+ timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+ bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+ clocks.realtime += 100;
+ clocks.uptime += 100;
+
+ // TimeBases are turned off
+ timeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000);
+ bgTimeBase.setRunning(false, clocks.uptime * 1000, clocks.realtime * 1000);
+
+ clocks.realtime += 100;
+ clocks.uptime += 100;
+
+ // Timer is turned on
+ bi.noteStartSensorLocked(UID, SENSOR_ID);
+
+ clocks.realtime += 100;
+ clocks.uptime += 100;
+
+ // Timebase was off so times are all 0.
+ BatteryStats.Uid.Sensor sensor = bi.getUidStats().get(UID).getSensorStats().get(SENSOR_ID);
+ BatteryStats.Timer timer = sensor.getSensorTime();
+ BatteryStats.Timer bgTimer = sensor.getSensorBackgroundTime();
+ assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+ assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+ clocks.realtime += 100;
+ clocks.uptime += 100;
+
+ // Reset the stats. Since the sensor is still running, we should still see the timer
+ // but still with 0 times.
+ bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
+ assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+ assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+ clocks.realtime += 100;
+ clocks.uptime += 100;
+
+ // Now stop the timer. The times should still be 0.
+ bi.noteStopSensorLocked(UID, SENSOR_ID);
+ assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+ assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+ // Now repeat with the TimeBases turned on the entire time.
+ timeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+ bgTimeBase.setRunning(true, clocks.uptime * 1000, clocks.realtime * 1000);
+ clocks.realtime += 100;
+ clocks.uptime += 100;
+
+ // Timer is turned on
+ bi.noteStartSensorLocked(UID, SENSOR_ID);
+
+ clocks.realtime += 111;
+ clocks.uptime += 1111;
+
+ // Timebase and timer was on so times have increased.
+ assertEquals(111_000, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(111, timer.getTotalDurationMsLocked(clocks.realtime));
+ assertEquals(111_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(111, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+ clocks.realtime += 100;
+ clocks.uptime += 100;
+
+ // Reset the stats. Since the sensor is still running, we should still see the timer
+ // but with 0 times.
+ bi.getUidStatsLocked(UID).reset(clocks.uptime * 1000, clocks.realtime * 1000);
+ assertEquals(0, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, timer.getTotalDurationMsLocked(clocks.realtime));
+ assertEquals(0, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(0, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+
+ clocks.realtime += 112;
+ clocks.uptime += 112;
+
+ // Now stop the timer. The times should have increased since the timebase was on.
+ bi.noteStopSensorLocked(UID, SENSOR_ID);
+ assertEquals(112_000, timer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(112, timer.getTotalDurationMsLocked(clocks.realtime));
+ assertEquals(112_000, bgTimer.getTotalTimeLocked(1000*clocks.realtime, which));
+ assertEquals(112, bgTimer.getTotalDurationMsLocked(clocks.realtime));
+ }
}
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
index 8801f5d09801..8801f5d09801 100644
--- a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
+++ b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
diff --git a/packages/SystemUI/res/drawable/ic_signal_location.xml b/packages/SettingsLib/res/drawable/ic_signal_location.xml
index 2f605805eba2..2f605805eba2 100644
--- a/packages/SystemUI/res/drawable/ic_signal_location.xml
+++ b/packages/SettingsLib/res/drawable/ic_signal_location.xml
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
index fa41c8349540..f9dc0e4d090e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
@@ -91,8 +91,9 @@ public class SuggestionParser {
// Shared prefs keys for storing dismissed state.
// Index into current dismissed state.
+ @VisibleForTesting
+ static final String DISMISS_INDEX = "_dismiss_index";
public static final String SETUP_TIME = "_setup_time";
- private static final String DISMISS_INDEX = "_dismiss_index";
private static final String IS_DISMISSED = "_is_dismissed";
// Default dismiss control for smart suggestions.
@@ -353,7 +354,8 @@ public class SuggestionParser {
return elapsedTime > category.exclusiveExpireDaysInMillis;
}
- private boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
+ @VisibleForTesting
+ boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
if (dismissControl == null) {
return false;
@@ -370,7 +372,11 @@ public class SuggestionParser {
return false;
}
int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
- int currentDismiss = parseDismissString(dismissControl)[index];
+ int[] dismissRules = parseDismissString(dismissControl);
+ if (dismissRules.length <= index) {
+ return true;
+ }
+ int currentDismiss = dismissRules[index];
long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
if (System.currentTimeMillis() >= time) {
// Dismiss timeout has passed, undismiss it.
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
index 60933cfbbbda..83911360bdfe 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/suggestions/SuggestionParserTest.java
@@ -16,6 +16,8 @@
package com.android.settingslib.suggestions;
+import static com.google.common.truth.Truth.assertThat;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -42,8 +44,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import static com.google.common.truth.Truth.assertThat;
-
@RunWith(SettingLibRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SuggestionParserTest {
@@ -190,6 +190,24 @@ public class SuggestionParserTest {
assertThat(sl.getSuggestionForCategory("category2")).hasSize(1);
}
+ @Test
+ public void isSuggestionDismissed_mismatchRule_shouldDismiss() {
+ final Tile suggestion = new Tile();
+ suggestion.metaData = new Bundle();
+ suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3");
+ suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
+
+ // Dismiss suggestion when smart suggestion is not enabled.
+ mSuggestionParser.dismissSuggestion(suggestion, false /* isSmartSuggestionEnabled */);
+ final String suggestionKey = suggestion.intent.getComponent().flattenToShortString();
+ // And point to last rule in dismiss control
+ mPrefs.edit().putInt(suggestionKey + SuggestionParser.DISMISS_INDEX, 2).apply();
+
+ // Turn on smart suggestion, and check if suggestion is enabled.
+ assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */))
+ .isTrue();
+ }
+
private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
mSuggestionsBeforeDismiss = new ArrayList<>();
mSuggestionsAfterDismiss = new ArrayList<>();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index b328933cd1c5..819ee3ee57ff 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -915,9 +915,6 @@ class SettingsProtoDumpUtil {
Settings.Global.DEVICE_DEMO_MODE,
GlobalSettingsProto.DEVICE_DEMO_MODE);
dumpSetting(s, p,
- Settings.Global.RETAIL_DEMO_MODE_CONSTANTS,
- GlobalSettingsProto.RETAIL_DEMO_MODE_CONSTANTS);
- dumpSetting(s, p,
Settings.Global.DATABASE_DOWNGRADE_REASON,
GlobalSettingsProto.DATABASE_DOWNGRADE_REASON);
dumpSetting(s, p,
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index edd0d0df11b6..24f6c138e081 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -208,7 +208,7 @@
android:icon="@drawable/icon"
android:process="com.android.systemui"
android:supportsRtl="true"
- android:theme="@style/systemui_theme"
+ android:theme="@style/Theme.SystemUI"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
<!-- Keep theme in sync with SystemUIApplication.onCreate().
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index b821e7e76c60..9fdb00eebe10 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -43,7 +43,7 @@
android:layout_height="wrap_content"
android:layout_width="280dp"
android:layout_gravity="center_horizontal"
- android:theme="@style/PasswordTheme"
+ android:theme="?attr/passwordStyle"
>
<EditText android:id="@+id/passwordEntry"
diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml
index 802bd308d407..e2ce210efdcb 100644
--- a/packages/SystemUI/res-keyguard/values/attrs.xml
+++ b/packages/SystemUI/res-keyguard/values/attrs.xml
@@ -41,4 +41,6 @@
<declare-styleable name="CarrierText">
<attr name="allCaps" format="boolean" />
</declare-styleable>
+
+ <attr name="passwordStyle" format="reference" />
</resources>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index ea867eed08b4..c6f942356833 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -60,7 +60,13 @@
<item name="android:layout_gravity">center_horizontal|bottom</item>
</style>
- <style name="PasswordTheme" parent="systemui_theme">
+ <style name="PasswordTheme" parent="Theme.SystemUI">
+ <item name="android:textColor">?attr/wallpaperTextColor</item>
+ <item name="android:colorControlNormal">?attr/wallpaperTextColor</item>
+ <item name="android:colorControlActivated">?attr/wallpaperTextColor</item>
+ </style>
+
+ <style name="PasswordTheme.Light" parent="Theme.SystemUI.Light">
<item name="android:textColor">?attr/wallpaperTextColor</item>
<item name="android:colorControlNormal">?attr/wallpaperTextColor</item>
<item name="android:colorControlActivated">?attr/wallpaperTextColor</item>
diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/packages/SystemUI/res/drawable/ic_dnd.xml
index e658e687821b..9a1d502e21e5 100644
--- a/packages/SystemUI/res/drawable/ic_dnd.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -15,13 +15,13 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="48.0"
- android:viewportWidth="48.0"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
android:width="24dp"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z" />
+ android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
index 0515b35fb875..e7b9fa7e6988 100644
--- a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -22,9 +22,6 @@
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
+ android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm.xml b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
index e64f445bef27..996e488e8c81 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -15,13 +15,13 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24.0dp"
- android:viewportHeight="48.0"
- android:viewportWidth="48.0"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
android:width="24.0dp"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
- android:pathData="M44.0,11.44l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-28.24,-4.66l-2.57,-3.06 -9.19,7.71 2.57,3.06 9.19,-7.71zm9.24,9.22l-3.0,0.0l0.0,12.0l9.49,5.71 1.51,-2.47 -8.0,-4.74l0.0,-10.5zm-1.01,-8.0c-9.95,0.0 -17.99,8.06 -17.99,18.0s8.04,18.0 17.99,18.0 18.01,-8.06 18.01,-18.0 -8.06,-18.0 -18.01,-18.0zm0.01,32.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.26,14.0 -14.0,14.0z" />
+ android:pathData="M2.7,6.5c-0.4,-0.4 -0.3,-1 0.1,-1.4l3,-2.6c0.4,-0.4 1,-0.3 1.4,0.1C7.6,3 7.5,3.7 7.1,4l-3,2.6C3.6,7 3,6.9 2.7,6.5zM21.3,5.1l-3.1,-2.6c-0.4,-0.4 -0.99,-0.31 -1.4,0.1c-0.4,0.4 -0.3,1 0.1,1.4L20,6.6c0.41,0.37 1,0.3 1.4,-0.1C21.73,6.12 21.7,5.4 21.3,5.1zM21,13c0,5 -4,9 -9,9s-9,-4 -9,-9s4,-9 9,-9S21,8 21,13zM19.1,13c0,-3.9 -3.2,-7.1 -7.1,-7.1S4.9,9.1 4.9,13s3.2,7.1 7.1,7.1S19.1,16.9 19.1,13zM11.75,8C11.34,8 11,8.34 11,8.75V14l4.14,2.48c0.34,0.21 0.77,0.1 0.98,-0.24s0.09,-0.79 -0.25,-0.99l-3.37,-2v-4.5C12.5,8.34 12.16,8 11.75,8z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
index 37d769084b6d..02fb1e702438 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -15,13 +15,13 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24.0dp"
- android:viewportHeight="48.0"
- android:viewportWidth="48.0"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
android:width="24.0dp"
android:tint="?android:attr/colorControlNormal" >
<path
android:fillColor="#FFFFFF"
- android:pathData="M24.0,12.0c7.73,0.0 14.0,6.27 14.0,14.0 0.0,1.69 -0.31,3.3 -0.86,4.8l3.04,3.04c1.16,-2.37 1.82,-5.03 1.82,-7.84 0.0,-9.94 -8.06,-18.0 -18.01,-18.0 -2.81,0.0 -5.46,0.66 -7.84,1.81l3.05,3.05c1.5,-0.55 3.11,-0.86 4.8,-0.86zm20.0,-0.56l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-38.16,-6.85l-2.55,2.54 2.66,2.66 -2.22,1.86 2.84,2.84 2.22,-1.86 1.6,1.6c-2.73,3.16 -4.39,7.27 -4.39,11.77 0.0,9.94 8.04,18.0 17.99,18.0 4.51,0.0 8.62,-1.67 11.77,-4.4l4.4,4.4 2.54,-2.55 -34.91,-34.91 -1.95,-1.95zm27.1,32.19c-2.43,2.01 -5.54,3.22 -8.94,3.22 -7.73,0.0 -14.0,-6.27 -14.0,-14.0 0.0,-3.4 1.21,-6.51 3.22,-8.94l19.72,19.72zm-16.91,-30.23l-2.84,-2.84 -1.7,1.43 2.84,2.84 1.7,-1.43z" />
+ android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM20.72,20.09a0.9,0.9 0,0 1,0 1.27,0.9 0.9,0 0,1 -1.27,0l-1.57,-1.57A8.875,8.875 0,0 1,12 22c-4.98,0 -9,-4.03 -9,-9 0,-2.25 0.83,-4.31 2.2,-5.89l-0.8,-0.8 -0.41,0.35a1,1 0,0 1,-1.35 -0.06,1 1,0 0,1 0.07,-1.47l0.27,-0.23 -0.7,-0.7a0.9,0.9 0,0 1,0 -1.27c0.35,-0.35 0.93,-0.35 1.28,0l17.16,17.16zM16.54,18.45L6.55,8.46A7.041,7.041 0,0 0,4.9 13c0,3.91 3.19,7.1 7.1,7.1 1.73,0 3.31,-0.62 4.54,-1.65zM7.17,3.98A0.997,0.997 0,1 0,5.9 2.44l-0.16,0.13 1.42,1.42 0.01,-0.01zM12,4c-1.41,0 -2.73,0.33 -3.92,0.91l1.45,1.45c0.77,-0.29 1.6,-0.46 2.47,-0.46 3.91,0 7.1,3.18 7.1,7.1 0,0.87 -0.17,1.7 -0.45,2.47l1.44,1.44c0.58,-1.18 0.91,-2.5 0.91,-3.91a9,9 0,0 0,-9 -9z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml b/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
index 5c3c6503d7c6..b0b9404cef46 100644
--- a/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_bt_sco.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -15,13 +15,16 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24.0dp"
- android:viewportHeight="48.0"
- android:viewportWidth="48.0"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
android:width="24.0dp"
android:tint="?android:attr/colorControlNormal" >
<path
android:fillColor="#FFFFFF"
- android:pathData="M29.41,19.0L34.0,14.41L34.0,22.0l1.0,0.0l5.71,-5.71 -4.3,-4.29 4.29,-4.29L35.0,2.0l-1.0,0.0l0.0,7.59L29.41,5.0 28.0,6.41 33.59,12.0 28.0,17.59 29.41,19.0zM36.0,5.83l1.88,1.88L36.0,9.59L36.0,5.83zm0.0,8.58l1.88,1.88L36.0,18.17l0.0,-3.76zM40.0,31.0c-2.49,0.0 -4.89,-0.4 -7.14,-1.14 -0.69,-0.22 -1.48,-0.06 -2.0,0.49l-4.4,4.41c-5.67,-2.88 -10.29,-7.51 -13.18,-13.17l4.4,-4.41c0.55,-0.5 0.71,-1.3 0.49,-2.03C17.4,12.9 17.0,10.49 17.0,8.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0L8.0,6.0c-1.11,0.0 -2.0,0.89 -2.0,2.0 0.0,18.78 15.22,34.0 34.0,34.0 1.11,0.0 2.0,-0.89 2.0,-2.0l0.0,-7.0c0.0,-1.11 -0.89,-2.0 -2.0,-2.0z" />
+ android:pathData="M20,15.5c-1.25,0 -2.45,-0.2 -3.57,-0.57c-0.35,-0.11 -0.74,-0.03 -1.02,0.24l-2.2,2.2c-2.83,-1.44 -5.15,-3.75 -6.59,-6.59l2.2,-2.21c0.28,-0.26 0.36,-0.65 0.25,-1C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1H4C3.45,3 3,3.45 3,4c0,9.39 7.61,17 17,17c0.55,0 1,-0.45 1,-1v-3.5C21,15.95 20.55,15.5 20,15.5z"/>
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M17.97,6l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L17.6,1.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L16.49,6l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L17.97,6zM17.75,2.78l0.99,0.99l-0.99,0.99V2.78zM17.75,9.23V7.27l0.99,0.99L17.75,9.23z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media.xml b/packages/SystemUI/res/drawable/ic_volume_media.xml
index d6892077fa58..53c0740d88ea 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -22,6 +22,6 @@
<path
android:fillColor="#FFFFFF"
- android:pathData="M12.0,3.0l0.0,9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12.0 6.0,14.01 6.0,16.5S8.01,21.0 10.5,21.0c2.31,0.0 4.2,-1.75 4.45,-4.0L15.0,17.0L15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0z" />
+ android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
index 9b7b2da72b9c..60d0184c0ba2 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_bt.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -22,9 +22,6 @@
<path
android:fillColor="#FFFFFF"
- android:pathData="M17.0,3.0l-7.0,0.0l0.0,9.3C9.5,12.1 9.0,12.0 8.5,12.0C6.0,12.0 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0s4.5,-2.3 4.5,-4.5C13.0,14.7 13.0,6.0 13.0,6.0l4.0,0.0L17.0,3.0z"/>
- <path
- android:fillColor="#FFFFFF"
- android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/>
+ android:pathData="M16,3h-5c-0.55,0 -1,0.45 -1,1v8.3c-0.93,-0.39 -1.96,-0.4 -2.9,-0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26C4,19 6.01,21 8.49,21c0,0 0.01,0 0.01,0c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4C17,3.45 16.55,3 16,3zM20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l0.02,-0.02l2.23,-2.23c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,10.75V8.78l0.99,0.99L20.75,10.75zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
index 17ac01d078dd..49fcfc4d4919 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_bt_mute.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -22,12 +22,12 @@
<path
android:fillColor="#FFFFFF"
- android:pathData="M13.0,6.0l4.0,0.0L17.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C13.0,8.8 13.0,6.0 13.0,6.0z"/>
+ android:pathData="M13,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6z"/>
<path
android:fillColor="#FFFFFF"
- android:pathData="M2.1,5.7L8.4,12.0C6.0,12.1 4.0,14.0 4.0,16.5S6.0,21.0 8.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3l0.0,-0.1l3.9,3.9l1.3,-1.3L3.4,4.5L2.1,5.7z"/>
+ android:pathData="M4,5.1C3.67,4.76 3.12,4.75 2.78,5.08C2.41,5.42 2.4,6 2.75,6.35L8.4,12C6,12.1 4,14 4,16.5c0,2.51 2.33,4.67 4.84,4.48C11.35,20.81 13,18.62 13,16.7v-0.1l3.27,3.27c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L4,5.1z"/>
<path
android:fillColor="#FFFFFF"
- android:pathData="M23.4,9.9L20.5,7.0L20.0,7.0l0.0,3.8l-2.3,-2.3L17.0,9.2l2.8,2.8L17.0,14.8l0.7,0.7l2.3,-2.3L20.0,17.0l0.5,0.0l2.8,-2.8L21.2,12.0L23.4,9.9zM21.0,8.9l0.9,0.9l-0.9,1.0L21.0,8.9zM21.9,14.2L21.0,15.1l0.0,-1.9L21.9,14.2z"/>
+ android:pathData="M20.97,12l1.88,-1.87c0.21,-0.21 0.21,-0.54 0,-0.74L20.6,7.16l-0.01,-0.01c-0.21,-0.2 -0.53,-0.2 -0.73,0.01c-0.09,0.1 -0.15,0.23 -0.15,0.36v3.23l-2.03,-2.03c-0.21,-0.21 -0.53,-0.21 -0.74,0c-0.21,0.21 -0.21,0.53 0,0.74L19.49,12l-2.55,2.55c-0.21,0.21 -0.21,0.53 0,0.74c0.21,0.21 0.53,0.21 0.74,0l2.03,-2.03v3.23c0,0.29 0.24,0.52 0.52,0.52c0.13,0 0.26,-0.05 0.35,-0.15l2.25,-2.25c0.21,-0.21 0.21,-0.54 0,-0.74L20.97,12zM20.75,8.78l0.99,0.99l-0.99,0.98V8.78zM20.75,15.23v-1.96l0.99,0.99C21.73,14.25 20.75,15.23 20.75,15.23z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
index 267d09d7b84e..ebb86e896d21 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -22,9 +22,6 @@
<path
android:fillColor="#FFFFFF"
- android:pathData="M15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C15.0,8.8 15.0,6.0 15.0,6.0z" />
- <path
- android:fillColor="#FFFFFF"
- android:pathData="M4.8,3.9L3.5,5.1l6.9,6.9C8.0,12.1 6.0,14.0 6.0,16.5C6.0,19.0 8.0,21.0 10.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3c0.0,0.0 0.0,-0.1 0.0,-0.1l4.0,4.0l1.3,-1.3L4.8,3.9z" />
+ android:pathData="M15,6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1h-5c-0.55,0 -1,0.45 -1,1v4.6l3,3V6zM4.18,4.48c-0.37,0.34 -0.38,0.92 -0.03,1.27L10.4,12C8,12.1 6,14 6,16.5c0,2.51 2.33,4.67 4.84,4.48 2.51,-0.17 4.16,-2.36 4.16,-4.28v-0.1l3.37,3.37c0.35,0.35 0.91,0.35 1.25,0l0.05,-0.05c0.35,-0.35 0.35,-0.91 0,-1.25L5.4,4.5a0.866,0.866 0,0 0,-1.22 -0.02z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer.xml b/packages/SystemUI/res/drawable/ic_volume_ringer.xml
index 18af711a493f..f258856696bb 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -15,13 +15,17 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0"
+ android:viewportHeight="23.4"
+ android:viewportWidth="23.4"
android:width="24dp"
android:tint="?android:attr/colorControlNormal" >
- <path
- android:fillColor="#FFFFFF"
- android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z" />
+ <group
+ android:translateX="-0.78"
+ android:translateY="-0.5" >
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.63,5.36 6,7.92 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h15.6c0.45,0 0.67,-0.54 0.35,-0.85L18,16z"/>
+ </group>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
index bc926c3340a3..106d899f1b64 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_mute.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -15,13 +15,23 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="48.0"
- android:viewportWidth="48.0"
+ android:viewportHeight="23.4"
+ android:viewportWidth="23.3"
android:width="24dp"
android:tint="?android:attr/colorControlNormal" >
- <path
- android:fillColor="#FFFFFF"
- android:pathData="M23.000000,44.000000c2.200000,0.000000 4.000000,-1.800000 4.000000,-4.000000l-8.000000,0.000000C19.000000,42.200001 20.799999,44.000000 23.000000,44.000000zM36.000000,21.000000c0.000000,-6.100000 -4.300000,-11.300000 -10.000000,-12.600000L26.000000,7.000000c0.000000,-1.700000 -1.300000,-3.000000 -3.000000,-3.000000c-1.700000,0.000000 -3.000000,1.300000 -3.000000,3.000000l0.000000,1.400000c-1.000000,0.200000 -2.000000,0.600000 -2.900000,1.100000L36.000000,28.400000L36.000000,21.000000zM35.500000,38.000000l4.000000,4.000000l2.500000,-2.500000L8.500000,6.000000L6.000000,8.500000l5.800000,5.800000C10.700000,16.299999 10.000000,18.600000 10.000000,21.000000l0.000000,11.000000l-4.000000,4.000000l0.000000,2.000000L35.500000,38.000000z" />
+ <group
+ android:translateX="-0.85"
+ android:translateY="-0.5" >
+ <path
+ android:fillColor="#FF0"
+ android:pathData="M20.73,19.46l-0.6,-0.6c0,0 0,0 0,0L5.54,4.26c-0.35,-0.35 -0.92,-0.35 -1.27,0c-0.35,0.35 -0.35,0.92 0,1.27l2.4,2.4C6.25,8.85 6,9.88 6,11v5l-2.15,2.15c-0.19,0.2 -0.19,0.51 0.01,0.71C3.95,18.95 4.07,19 4.2,19h13.53l1.73,1.73c0.35,0.35 0.92,0.35 1.27,0C21.09,20.38 21.09,19.81 20.73,19.46z"/>
+ <path
+ android:fillColor="#FF0"
+ android:pathData="M18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.87,4.83 9.31,5.08 8.8,5.4l9.2,9.2V11z"/>
+ <path
+ android:fillColor="#FF0"
+ android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+ </group>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
index ffbffad690ec..9db8511c3623 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ Copyright (C) 2017 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.
@@ -22,6 +22,6 @@
<path
android:fillColor="#FFFFFF"
- android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z" />
+ android:pathData="M1,15c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4c0,0.55 0.45,1 1,1zM4,17c0.55,0 1,-0.45 1,-1L5,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM22,10v4c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1zM20,17c0.55,0 1,-0.45 1,-1L21,8c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM16.5,3h-9C6.67,3 6,3.67 6,4.5v15c0,0.83 0.67,1.5 1.5,1.5h9c0.83,0 1.5,-0.67 1.5,-1.5v-15c0,-0.83 -0.67,-1.5 -1.5,-1.5zM16,19L8,19L8,5h8v14z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 07f11a425fd7..18dab3d10a9e 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="RecentsTheme" parent="RecentsBase">
+ <style name="RecentsTheme" parent="@android:style/Theme.Material">
<!-- NoTitle -->
<item name="android:windowNoTitle">true</item>
<!-- Misc -->
@@ -27,13 +27,6 @@
<item name="android:ambientShadowAlpha">0.35</item>
</style>
- <!-- OverlayManager might replace this style entirely, use RecentsTheme to set a property
- that should exist in both light and dark versions of Recents -->
- <style name="RecentsBase" parent="@android:style/Theme.Material">
- <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_dark</item>
- <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_dark</item>
- </style>
-
<!-- Recents theme -->
<style name="RecentsTheme.Wallpaper">
<item name="android:windowBackground">@*android:color/transparent</item>
@@ -41,8 +34,13 @@
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowDisablePreview">true</item>
<item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item>
- <item name="wallpaperTextColor">?android:attr/textColorPrimaryInverse</item>
- <item name="wallpaperTextColorSecondary">?android:attr/textColorSecondaryInverse</item>
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+ <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
+ </style>
+
+ <style name="RecentsTheme.Wallpaper.Light">
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
+ <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
</style>
<style name="ClearAllButtonDefaultMargins">
@@ -300,22 +298,27 @@
<style name="Animation.StatusBar">
</style>
- <!-- Overlay manager may replace this theme -->
- <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings" />
-
- <style name="systemui_theme" parent="systemui_base">
+ <style name="Theme.SystemUI" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
<item name="lightIconTheme">@style/DualToneLightTheme</item>
<item name="darkIconTheme">@style/DualToneDarkTheme</item>
- <item name="wallpaperTextColor">?android:attr/textColorPrimaryInverse</item>
- <item name="wallpaperTextColorSecondary">?android:attr/textColorSecondaryInverse</item>
- <item name="android:colorControlHighlight">?android:attr/textColorSecondaryInverse</item>
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+ <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
+ <item name="android:colorControlHighlight">@*android:color/primary_text_material_dark</item>
<item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
+ <item name="passwordStyle">@style/PasswordTheme</item>
+ </style>
+
+ <style name="Theme.SystemUI.Light" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
+ <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
+ <item name="android:colorControlHighlight">@*android:color/primary_text_material_light</item>
+ <item name="passwordStyle">@style/PasswordTheme.Light</item>
</style>
<style name="LockPatternStyle">
- <item name="*android:regularColor">?android:attr/textColorPrimaryInverse</item>
- <item name="*android:successColor">?android:attr/textColorPrimaryInverse</item>
- <item name="*android:errorColor">?android:attr/colorError</item>
+ <item name="*android:regularColor">?attr/wallpaperTextColor</item>
+ <item name="*android:successColor">?attr/wallpaperTextColor</item>
+ <item name="*android:errorColor">?attr/colorError</item>
</style>
<!-- Overlay manager may replace this theme -->
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 211f0c75b5dd..d8da5ed71894 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -118,7 +118,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
// Set the application theme that is inherited by all services. Note that setting the
// application theme in the manifest does only work for activities. Keep this in sync with
// the theme set there.
- setTheme(R.style.systemui_theme);
+ setTheme(R.style.Theme_SystemUI);
SystemUIFactory.createFromConfig(this);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 81ec6a7c72a9..4e728f68890a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -19,13 +19,14 @@ package com.android.systemui.qs.tiles;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.os.SystemProperties;
import android.service.quicksettings.Tile;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Switch;
-
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.net.DataUsageController;
@@ -38,7 +39,6 @@ import com.android.systemui.plugins.qs.QSTile.SignalState;
import com.android.systemui.qs.CellTileView;
import com.android.systemui.qs.CellTileView.SignalIcon;
import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.SignalTileView;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
@@ -46,8 +46,17 @@ import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
/** Quick settings tile: Cellular **/
public class CellularTile extends QSTileImpl<SignalState> {
- static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
- "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
+ private static final ComponentName CELLULAR_SETTING_COMPONENT = new ComponentName(
+ "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity");
+ private static final ComponentName DATA_PLAN_CELLULAR_COMPONENT = new ComponentName(
+ "com.android.settings", "com.android.settings.Settings$DataPlanUsageSummaryActivity");
+
+ private static final Intent CELLULAR_SETTINGS =
+ new Intent().setComponent(CELLULAR_SETTING_COMPONENT);
+ private static final Intent DATA_PLAN_CELLULAR_SETTINGS =
+ new Intent().setComponent(DATA_PLAN_CELLULAR_COMPONENT);
+
+ private static final String ENABLE_SETTINGS_DATA_PLAN = "enable.settings.data.plan";
private final NetworkController mController;
private final DataUsageController mDataController;
@@ -90,7 +99,7 @@ public class CellularTile extends QSTileImpl<SignalState> {
@Override
public Intent getLongClickIntent() {
- return CELLULAR_SETTINGS;
+ return getCellularSettingIntent(mContext);
}
@Override
@@ -103,7 +112,9 @@ public class CellularTile extends QSTileImpl<SignalState> {
if (mDataController.isMobileDataSupported()) {
showDetail(true);
} else {
- mActivityStarter.postStartActivityDismissingKeyguard(CELLULAR_SETTINGS, 0);
+ mActivityStarter
+ .postStartActivityDismissingKeyguard(getCellularSettingIntent(mContext),
+ 0 /* delay */);
}
}
@@ -240,7 +251,28 @@ public class CellularTile extends QSTileImpl<SignalState> {
public void setMobileDataEnabled(boolean enabled) {
mDetailAdapter.setMobileDataEnabled(enabled);
}
- };
+ }
+
+ static Intent getCellularSettingIntent(Context context) {
+ // TODO(b/62349208): We should replace feature flag check below with data plans
+ // availability check. If the data plans are available we display the data plans usage
+ // summary otherwise we display data usage summary without data plans.
+ boolean isDataPlanFeatureEnabled =
+ SystemProperties.getBoolean(ENABLE_SETTINGS_DATA_PLAN, false /* default */);
+ context.getPackageManager()
+ .setComponentEnabledSetting(
+ DATA_PLAN_CELLULAR_COMPONENT,
+ isDataPlanFeatureEnabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ context.getPackageManager()
+ .setComponentEnabledSetting(
+ CELLULAR_SETTING_COMPONENT,
+ isDataPlanFeatureEnabled ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+ return isDataPlanFeatureEnabled ? DATA_PLAN_CELLULAR_SETTINGS : CELLULAR_SETTINGS;
+ }
private final class CellularDetailAdapter implements DetailAdapter {
@@ -258,7 +290,7 @@ public class CellularTile extends QSTileImpl<SignalState> {
@Override
public Intent getSettingsIntent() {
- return CELLULAR_SETTINGS;
+ return getCellularSettingIntent(mContext);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index b7964512a2fa..8b62beb861ba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -14,18 +14,16 @@
package com.android.systemui.qs.tiles;
-import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.service.quicksettings.Tile;
import android.widget.Switch;
-
-import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.Prefs;
import com.android.systemui.R;
-import com.android.systemui.qs.QSHost;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.DataSaverController;
@@ -57,9 +55,8 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements
@Override
public Intent getLongClickIntent() {
- return CellularTile.CELLULAR_SETTINGS;
+ return CellularTile.getCellularSettingIntent(mContext);
}
-
@Override
protected void handleClick() {
if (mState.value
@@ -73,12 +70,7 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements
dialog.setTitle(com.android.internal.R.string.data_saver_enable_title);
dialog.setMessage(com.android.internal.R.string.data_saver_description);
dialog.setPositiveButton(com.android.internal.R.string.data_saver_enable_button,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- toggleDataSaver();
- }
- });
+ (OnClickListener) (dialogInterface, which) -> toggleDataSaver());
dialog.setNegativeButton(com.android.internal.R.string.cancel, null);
dialog.setShowForAllUsers(true);
dialog.show();
@@ -126,4 +118,4 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements
public void onDataSaverChanged(boolean isDataSaving) {
refreshState(isDataSaving);
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index f2ea6a683e95..c0550b5c52e6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -20,11 +20,11 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.TaskStackBuilder;
+import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
@@ -41,12 +41,15 @@ import android.view.ViewTreeObserver.OnPreDrawListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
+import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.LatencyTracker;
import com.android.systemui.DejankUtils;
+import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
@@ -100,7 +103,8 @@ import java.util.List;
/**
* The main Recents activity that is started from RecentsComponent.
*/
-public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {
+public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreDrawListener,
+ ColorExtractor.OnColorsChangedListener {
private final static String TAG = "RecentsActivity";
private final static boolean DEBUG = false;
@@ -129,6 +133,10 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
private DozeTrigger mIterateTrigger;
private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
+ // Theme and colors
+ private SysuiColorExtractor mColorExtractor;
+ private boolean mUsingDarkText;
+
/**
* A common Runnable to finish Recents by launching Home with an animation depending on the
* last activity launch state. Generally we always launch home when we exit Recents rather than
@@ -329,6 +337,14 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
mPackageMonitor = new RecentsPackageMonitor();
mPackageMonitor.register(this);
+ // Select theme based on wallpaper colors
+ mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+ mColorExtractor.addOnColorsChangedListener(this);
+ mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK,
+ WallpaperManager.FLAG_SYSTEM, true).supportsDarkText();
+ setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
+ : R.style.RecentsTheme_Wallpaper);
+
// Set the Recents layout
setContentView(R.layout.recents);
takeKeyEvents(true);
@@ -375,13 +391,37 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
- // Make sure we have the right gradient and we're listening for update events
- mRecentsView.onStart();
+ // Getting system scrim colors ignoring wallpaper visibility since it should never be grey.
+ ColorExtractor.GradientColors systemColors = mColorExtractor.getColors(
+ ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true);
+ // We don't want to interpolate colors because we're defining the initial state.
+ // Gradient should be set/ready when you open "Recents".
+ mRecentsView.setScrimColors(systemColors, false);
+
// Notify of the next draw
mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);
}
@Override
+ public void onColorsChanged(ColorExtractor colorExtractor, int which) {
+ if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+ // Recents doesn't care about the wallpaper being visible or not, it always
+ // wants to scrim with wallpaper colors
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_SYSTEM,
+ ColorExtractor.TYPE_DARK, true /* ignoreVis */);
+ boolean darkText = colors.supportsDarkText();
+ if (darkText != mUsingDarkText) {
+ mUsingDarkText = darkText;
+ setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
+ : R.style.RecentsTheme_Wallpaper);
+ mRecentsView.reevaluateStyles();
+ }
+ mRecentsView.setScrimColors(colors, true /* animated */);
+ }
+ }
+
+ @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -483,12 +523,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
mLastConfig.orientation != newDeviceConfiguration.orientation,
mLastConfig.densityDpi != newDeviceConfiguration.densityDpi, numStackTasks > 0));
- int configDiff = mLastConfig.updateFrom(newDeviceConfiguration);
-
- // Recreate activity if an overlay was enabled/disabled
- if ((configDiff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
- recreate();
- }
+ mLastConfig.updateFrom(newDeviceConfiguration);
}
@Override
@@ -508,9 +543,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(false);
- // We don't need to update the gradient when we're not visible
- mRecentsView.onStop();
-
if (!isChangingConfigurations()) {
// Workaround for b/22542869, if the RecentsActivity is started again, but without going
// through SystemUI, we need to reset the config launch flags to ensure that we do not
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index fd37b17f3cd0..8e094813257c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -21,13 +21,12 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.app.ActivityOptions.OnAnimationStartedListener;
-import android.app.WallpaperColors;
-import android.app.WallpaperManager;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -43,12 +42,12 @@ import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.drawable.GradientDrawable;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Dependency;
+import com.android.settingslib.Utils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsActivity;
import com.android.systemui.recents.RecentsActivityLaunchState;
@@ -83,8 +82,6 @@ import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.internal.colorextraction.drawable.GradientDrawable;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -93,7 +90,7 @@ import java.util.List;
* This view is the the top level layout that contains TaskStacks (which are laid out according
* to their SpaceNode bounds.
*/
-public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsChangedListener {
+public class RecentsView extends FrameLayout {
private static final String TAG = "RecentsView";
@@ -107,6 +104,9 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC
private TaskStackView mTaskStackView;
private TextView mStackActionButton;
private TextView mEmptyView;
+ private final float mStackButtonShadowRadius;
+ private final PointF mStackButtonShadowDistance;
+ private final int mStackButtonShadowColor;
private boolean mAwaitingFirstLayout = true;
private boolean mLastTaskLaunchedWasFreeform;
@@ -117,7 +117,6 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC
private float mBusynessFactor;
private GradientDrawable mBackgroundScrim;
- private final SysuiColorExtractor mColorExtractor;
private Animator mBackgroundScrimAnimator;
private RecentsTransitionHelper mTransitionHelper;
@@ -148,29 +147,51 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC
mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
mBackgroundScrim = new GradientDrawable(context);
mBackgroundScrim.setCallback(this);
- mColorExtractor = Dependency.get(SysuiColorExtractor.class);
- LayoutInflater inflater = LayoutInflater.from(context);
+ boolean usingDarkText = Color.luminance(
+ Utils.getColorAttr(mContext, R.attr.wallpaperTextColor)) < 0.5f;
+ LayoutInflater inflater = LayoutInflater.from(context);
mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
addView(mEmptyView);
- boolean usingDarkText =
- Color.luminance(mEmptyView.getTextColors().getDefaultColor()) < 0.5f;
if (RecentsDebugFlags.Static.EnableStackActionButton) {
+ if (mStackActionButton != null) {
+ removeView(mStackActionButton);
+ }
mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
this, false);
- mStackActionButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- EventBus.getDefault().send(new DismissAllTaskViewsEvent());
- }
- });
- // Disable black shadow if text color is already dark.
+ mStackActionButton.setOnClickListener(
+ v -> EventBus.getDefault().send(new DismissAllTaskViewsEvent()));
+
+ mStackButtonShadowRadius = mStackActionButton.getShadowRadius();
+ mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(),
+ mStackActionButton.getShadowDy());
+ mStackButtonShadowColor = mStackActionButton.getShadowColor();
+ addView(mStackActionButton);
+ }
+
+ reevaluateStyles();
+ }
+
+ public void reevaluateStyles() {
+ int textColor = Utils.getColorAttr(mContext, R.attr.wallpaperTextColor);
+ boolean usingDarkText = Color.luminance(textColor) < 0.5f;
+
+ mEmptyView.setTextColor(textColor);
+ mEmptyView.setCompoundDrawableTintList(new ColorStateList(new int[][]{
+ {android.R.attr.state_enabled}}, new int[]{textColor}));
+
+ if (mStackActionButton != null) {
+ mStackActionButton.setTextColor(textColor);
+ // Enable/disable shadow if text color is already dark.
if (usingDarkText) {
mStackActionButton.setShadowLayer(0, 0, 0, 0);
+ } else {
+ mStackActionButton.setShadowLayer(mStackButtonShadowRadius,
+ mStackButtonShadowDistance.x, mStackButtonShadowDistance.y,
+ mStackButtonShadowColor);
}
- addView(mStackActionButton);
}
// Let's also require dark status and nav bars if the text is dark
@@ -369,6 +390,16 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC
}
}
+ /**
+ * Set the color of the scrim.
+ *
+ * @param scrimColors Colors to use.
+ * @param animated Interpolate colors if true.
+ */
+ public void setScrimColors(ColorExtractor.GradientColors scrimColors, boolean animated) {
+ mBackgroundScrim.setColors(scrimColors, animated);
+ }
+
@Override
protected void onAttachedToWindow() {
EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
@@ -888,29 +919,4 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC
mTaskStackView.dump(innerPrefix, writer);
}
}
-
- @Override
- public void onColorsChanged(ColorExtractor colorExtractor, int which) {
- if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
- // Recents doesn't care about the wallpaper being visible or not, it always
- // wants to scrim with wallpaper colors
- mBackgroundScrim.setColors(
- mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
- ColorExtractor.TYPE_DARK, true));
- }
- }
-
- public void onStart() {
- mColorExtractor.addOnColorsChangedListener(this);
- // Getting system scrim colors ignoring wallpaper visibility since it should never be grey.
- ColorExtractor.GradientColors systemColors = mColorExtractor.getColors(
- ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true);
- // We don't want to interpolate colors because we're defining the initial state.
- // Gradient should be set/ready when you open "Recents".
- mBackgroundScrim.setColors(systemColors, false);
- }
-
- public void onStop() {
- mColorExtractor.removeOnColorsChangedListener(this);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index 543666407fb9..d7c6443a6c3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
@@ -46,6 +47,10 @@ public class DismissView extends StackScrollerDecorView {
mDismissButton = (DismissViewButton) findContentView();
}
+ public void setTextColor(@ColorInt int color) {
+ mDismissButton.setTextColor(color);
+ }
+
public void setOnButtonClickListener(OnClickListener listener) {
mContent.setOnClickListener(listener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index 92b0890a5d2b..58adde269758 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
@@ -45,6 +46,10 @@ public class EmptyShadeView extends StackScrollerDecorView {
return findViewById(R.id.no_notifications);
}
+ public void setTextColor(@ColorInt int color) {
+ mEmptyText.setTextColor(color);
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 353b82b6fd6a..ec5edee94a31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -979,9 +979,6 @@ public class StatusBar extends SystemUI implements DemoMode,
Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
Dependency.get(ConfigurationController.class).addCallback(this);
-
- // Make sure that we're using the correct theme
- onOverlayChanged();
}
protected void createIconController() {
@@ -994,6 +991,7 @@ public class StatusBar extends SystemUI implements DemoMode,
final Context context = mContext;
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
+ updateTheme();
inflateStatusBarWindow(context);
mStatusBarWindow.setService(this);
@@ -1202,7 +1200,6 @@ public class StatusBar extends SystemUI implements DemoMode,
});
}
-
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
if (!pm.isScreenOn()) {
mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
@@ -1307,14 +1304,14 @@ public class StatusBar extends SystemUI implements DemoMode,
reevaluateStyles();
}
- public void onOverlayChanged() {
+ private void reinflateViews() {
reevaluateStyles();
// Clock and bottom icons
mNotificationPanel.onOverlayChanged();
-
+ // The status bar on the keyguard is a special layout.
+ mKeyguardStatusBar.onOverlayChanged();
// Recreate Indication controller because internal references changed
- // TODO: unregister callbacks before recreating
mKeyguardIndicationController =
SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
@@ -2862,17 +2859,6 @@ public class StatusBar extends SystemUI implements DemoMode,
updateTheme();
}
- public boolean isUsingDarkText() {
- OverlayInfo themeInfo = null;
- try {
- themeInfo = mOverlayManager.getOverlayInfo("com.android.systemui.theme.lightwallpaper",
- mCurrentUserId);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- return themeInfo != null && themeInfo.isEnabled();
- }
-
public boolean isUsingDarkTheme() {
OverlayInfo themeInfo = null;
try {
@@ -4580,24 +4566,13 @@ public class StatusBar extends SystemUI implements DemoMode,
* Switches theme from light to dark and vice-versa.
*/
private void updateTheme() {
+ final boolean inflated = mStackScroller != null;
- int which;
- if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
- which = WallpaperManager.FLAG_LOCK;
- } else {
- which = WallpaperManager.FLAG_SYSTEM;
- }
-
- // Gradient defines if text color should be light or dark.
- final boolean useDarkText = mColorExtractor.getColors(which, true /* ignoreVisibility */)
- .supportsDarkText();
- // And wallpaper defines if QS should be light or dark.
+ // The system wallpaper defines if QS should be light or dark.
WallpaperColors systemColors = mColorExtractor
.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
final boolean useDarkTheme = systemColors != null
&& (systemColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
-
- // Enable/disable dark UI.
if (isUsingDarkTheme() != useDarkTheme) {
try {
mOverlayManager.setEnabled("com.android.systemui.theme.dark",
@@ -4606,18 +4581,33 @@ public class StatusBar extends SystemUI implements DemoMode,
Log.w(TAG, "Can't change theme", e);
}
}
- // Enable/disable dark text overlay.
- if (isUsingDarkText() != useDarkText) {
- try {
- mOverlayManager.setEnabled("com.android.systemui.theme.lightwallpaper",
- useDarkText, mCurrentUserId);
- } catch (RemoteException e) {
- Log.w(TAG, "Can't change theme", e);
+
+ // Lock wallpaper defines the color of the majority of the views, hence we'll use it
+ // to set our default theme.
+ final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true
+ /* ignoreVisibility */).supportsDarkText();
+ final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
+ if (mContext.getThemeResId() != themeResId) {
+ mContext.setTheme(themeResId);
+ if (inflated) {
+ reinflateViews();
}
}
- // Make sure we have the correct navbar/statusbar colors.
- mStatusBarWindowManager.setKeyguardDark(useDarkText);
+ if (inflated) {
+ int which;
+ if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
+ which = WallpaperManager.FLAG_LOCK;
+ } else {
+ which = WallpaperManager.FLAG_SYSTEM;
+ }
+ final boolean useDarkText = mColorExtractor.getColors(which,
+ true /* ignoreVisibility */).supportsDarkText();
+ mStackScroller.updateDecorViews(useDarkText);
+
+ // Make sure we have the correct navbar/statusbar colors.
+ mStatusBarWindowManager.setKeyguardDark(useDarkText);
+ }
}
private void updateDozingState() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 42cebe2632bb..4bbe895da7ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -23,6 +23,7 @@ import android.animation.PropertyValuesHolder;
import android.animation.TimeAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.ColorInt;
import android.annotation.FloatRange;
import android.annotation.Nullable;
import android.content.Context;
@@ -44,6 +45,7 @@ import android.util.FloatProperty;
import android.util.Log;
import android.util.Pair;
import android.util.Property;
+import android.view.ContextThemeWrapper;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -61,6 +63,7 @@ import android.widget.ScrollView;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.Utils;
import com.android.systemui.ExpandHelper;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -363,6 +366,7 @@ public class NotificationStackScrollLayout extends ViewGroup
return object.getBackgroundFadeAmount();
}
};
+ private boolean mUsingLightTheme;
private boolean mQsExpanded;
private boolean mForwardScrollable;
private boolean mBackwardScrollable;
@@ -3653,6 +3657,23 @@ public class NotificationStackScrollLayout extends ViewGroup
mTmpSortedChildren.clear();
}
+ /**
+ * Update colors of "dismiss" and "empty shade" views.
+ *
+ * @param lightTheme True if light theme should be used.
+ */
+ public void updateDecorViews(boolean lightTheme) {
+ if (lightTheme == mUsingLightTheme) {
+ return;
+ }
+ mUsingLightTheme = lightTheme;
+ Context context = new ContextThemeWrapper(mContext,
+ lightTheme ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI);
+ final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor);
+ mDismissView.setTextColor(textColor);
+ mEmptyShadeView.setTextColor(textColor);
+ }
+
public void goToFullShade(long delay) {
if (mDismissView != null) {
mDismissView.setInvisible();
diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk b/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk
deleted file mode 100644
index 4782a166146b..000000000000
--- a/packages/overlays/SysuiLightWallpaperThemeOverlay/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_RRO_THEME := SysuiLightWallpaperTheme
-LOCAL_CERTIFICATE := platform
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_PACKAGE_NAME := SysuiLightWallpaperThemeOverlay
-
-include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml
deleted file mode 100644
index 0a8749c64ea2..000000000000
--- a/packages/overlays/SysuiLightWallpaperThemeOverlay/AndroidManifest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.systemui.theme.lightwallpaper"
- android:versionCode="1"
- android:versionName="1.0">
- <overlay android:targetPackage="com.android.systemui" android:priority="2"/>
-
- <application android:label="@string/sysui_overlay_light" android:hasCode="false"/>
-</manifest>
diff --git a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml b/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml
deleted file mode 100644
index 53912b50df00..000000000000
--- a/packages/overlays/SysuiLightWallpaperThemeOverlay/res/values/styles.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <style name="systemui_base" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
- <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item>
- <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item>
- </style>
-
- <style name="RecentsBase" parent="@android:style/Theme.Material">
- <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item>
- <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item>
- </style>
-</resources> \ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 53190869513b..6167d85f33c7 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4252,6 +4252,11 @@ message MetricsEvent {
// OS: O MR
FIELD_RANKED_POSITION = 1087;
+ // OPEN: Settings > Data plan usage
+ // CATEGORY: SETTINGS
+ // OS: O MR
+ DATA_PLAN_USAGE_SUMMARY = 1088;
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
diff --git a/services/Android.mk b/services/Android.mk
index 6a73d5f65351..0986e0a4aad4 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -34,7 +34,6 @@ services := \
net \
print \
restrictions \
- retaildemo \
usage \
usb \
voiceinteraction
diff --git a/services/art-profile b/services/art-profile
index bd6ed23fa993..140465a1c35e 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -11901,23 +11901,6 @@ PLcom/android/server/restrictions/RestrictionsManagerService$RestrictionsManager
PLcom/android/server/restrictions/RestrictionsManagerService;->-wrap0(Lcom/android/server/restrictions/RestrictionsManagerService;Ljava/lang/String;)Landroid/os/IBinder;
PLcom/android/server/restrictions/RestrictionsManagerService;-><init>(Landroid/content/Context;)V
PLcom/android/server/restrictions/RestrictionsManagerService;->onStart()V
-PLcom/android/server/retaildemo/RetailDemoModeService$1;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService;)V
-PLcom/android/server/retaildemo/RetailDemoModeService$1;->onUserActivity()V
-PLcom/android/server/retaildemo/RetailDemoModeService$Injector;-><init>(Landroid/content/Context;)V
-PLcom/android/server/retaildemo/RetailDemoModeService$Injector;->getContentResolver()Landroid/content/ContentResolver;
-PLcom/android/server/retaildemo/RetailDemoModeService$Injector;->getContext()Landroid/content/Context;
-PLcom/android/server/retaildemo/RetailDemoModeService$Injector;->publishLocalService(Lcom/android/server/retaildemo/RetailDemoModeService;Landroid/app/RetailDemoModeServiceInternal;)V
-PLcom/android/server/retaildemo/RetailDemoModeService$MainHandler;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService;Landroid/os/Looper;)V
-PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;->-wrap0(Lcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;)V
-PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService;Landroid/os/Handler;)V
-PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;->refreshTimeoutConstants()V
-PLcom/android/server/retaildemo/RetailDemoModeService$SettingsObserver;->register()V
-PLcom/android/server/retaildemo/RetailDemoModeService;->-get1(Lcom/android/server/retaildemo/RetailDemoModeService;)Lcom/android/server/retaildemo/RetailDemoModeService$Injector;
-PLcom/android/server/retaildemo/RetailDemoModeService;->-wrap2(Lcom/android/server/retaildemo/RetailDemoModeService;Ljava/lang/Class;Ljava/lang/Object;)V
-PLcom/android/server/retaildemo/RetailDemoModeService;-><init>(Landroid/content/Context;)V
-PLcom/android/server/retaildemo/RetailDemoModeService;-><init>(Lcom/android/server/retaildemo/RetailDemoModeService$Injector;)V
-PLcom/android/server/retaildemo/RetailDemoModeService;->onBootPhase(I)V
-PLcom/android/server/retaildemo/RetailDemoModeService;->onStart()V
PLcom/android/server/search/SearchManagerService$GlobalSearchProviderObserver;-><init>(Lcom/android/server/search/SearchManagerService;Landroid/content/ContentResolver;)V
PLcom/android/server/search/SearchManagerService$Lifecycle$1;-><init>(Lcom/android/server/search/SearchManagerService$Lifecycle;I)V
PLcom/android/server/search/SearchManagerService$Lifecycle$1;->run()V
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index a02802859ca7..41de97c8bcbb 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -698,6 +698,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
final SparseArray<Operation> mCurrentOperations = new SparseArray<Operation>();
final Object mCurrentOpLock = new Object();
final Random mTokenGenerator = new Random();
+ final AtomicInteger mNextToken = new AtomicInteger();
final SparseArray<AdbParams> mAdbBackupRestoreConfirmations = new SparseArray<AdbParams>();
@@ -770,15 +771,13 @@ public class BackupManagerService implements BackupManagerServiceInterface {
@GuardedBy("mQueueLock")
ArrayList<FullBackupEntry> mFullBackupQueue;
- // Utility: build a new random integer token
+ // Utility: build a new random integer token. The low bits are the ordinal of the
+ // operation for near-time uniqueness, and the upper bits are random for app-
+ // side unpredictability.
@Override
public int generateRandomIntegerToken() {
- int token;
- do {
- synchronized (mTokenGenerator) {
- token = mTokenGenerator.nextInt();
- }
- } while (token < 0);
+ int token = mTokenGenerator.nextInt() & ~0xFF;
+ token |= (mNextToken.incrementAndGet() & 0xFF);
return token;
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index eda283e82d79..966e553a6396 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -243,8 +243,9 @@ public class LocationManagerService extends ILocationManager.Stub {
private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;
- private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider;
private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;
+
+ private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider;
private IBatchedLocationCallback mGnssBatchingCallback;
private LinkedCallback mGnssBatchingDeathCallback;
private boolean mGnssBatchingInProgress = false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f59d18ebe6a4..b46e5e54d158 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -164,7 +164,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILIT
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
@@ -211,8 +210,6 @@ import android.app.ApplicationThreadConstants;
import android.app.BroadcastOptions;
import android.app.ContentProviderHolder;
import android.app.Dialog;
-import android.app.IActivityContainer;
-import android.app.IActivityContainerCallback;
import android.app.IActivityController;
import android.app.IActivityManager;
import android.app.IAppTask;
@@ -4122,8 +4119,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ri.activityInfo.packageName, ri.activityInfo.name));
mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
- null, 0, 0, 0, null, false, false, null, null, null,
- "startSetupActivity");
+ null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
}
}
}
@@ -4461,26 +4457,6 @@ public class ActivityManagerService extends IActivityManager.Stub
UserHandle.getCallingUserId());
}
- final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
- enforceNotIsolatedCaller("ActivityContainer.startActivity");
- final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
- ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
-
- // TODO: Switch to user app stacks here.
- String mimeType = intent.getType();
- final Uri data = intent.getData();
- if (mimeType == null && data != null && "content".equals(data.getScheme())) {
- mimeType = getProviderMimeType(data, userId);
- }
- container.checkEmbeddedAllowedInner(userId, intent, mimeType);
-
- intent.addFlags(FORCE_NEW_TASK_FLAGS);
- return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
- null, null, 0, 0, null, null, null, null, false, userId, container, null,
- "startActivity");
- }
-
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
@@ -4491,8 +4467,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
- profilerInfo, null, null, bOptions, false, userId, null, null,
- "startActivityAsUser");
+ profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}
@Override
@@ -4555,7 +4530,7 @@ public class ActivityManagerService extends IActivityManager.Stub
try {
int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
- null, null, bOptions, ignoreTargetSecurity, userId, null, null,
+ null, null, bOptions, ignoreTargetSecurity, userId, null,
"startActivityAsCaller");
return ret;
} catch (SecurityException e) {
@@ -4585,7 +4560,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// TODO: Switch to user app stacks here.
mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
- bOptions, false, userId, null, null, "startActivityAndWait");
+ bOptions, false, userId, null, "startActivityAndWait");
return res;
}
@@ -4599,7 +4574,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// TODO: Switch to user app stacks here.
int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
- null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
+ null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
return ret;
}
@@ -4630,7 +4605,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
- resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
+ resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
return ret;
}
@@ -4656,7 +4631,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
- null, bOptions, false, userId, null, null, "startVoiceActivity");
+ null, bOptions, false, userId, null, "startVoiceActivity");
}
@Override
@@ -4675,7 +4650,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ALLOW_FULL_ONLY, "startAssistantActivity", null);
return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
- userId, null, null, "startAssistantActivity");
+ userId, null, "startAssistantActivity");
}
@Override
@@ -4848,7 +4823,7 @@ public class ActivityManagerService extends IActivityManager.Stub
null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
- false, false, null, null, null, "startNextMatchingActivity");
+ false, false, null, null, "startNextMatchingActivity");
Binder.restoreCallingIdentity(origId);
r.finishing = wasFinishing;
@@ -4880,16 +4855,15 @@ public class ActivityManagerService extends IActivityManager.Stub
final int startActivityInPackage(int uid, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
- IActivityContainer container, TaskRecord inTask, String reason) {
+ TaskRecord inTask, String reason) {
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
// TODO: Switch to user app stacks here.
- int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
+ return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
- null, null, null, bOptions, false, userId, container, inTask, reason);
- return ret;
+ null, null, null, bOptions, false, userId, inTask, reason);
}
@Override
@@ -10479,44 +10453,25 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
- IActivityContainerCallback callback) throws RemoteException {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
- synchronized (this) {
- if (parentActivityToken == null) {
- throw new IllegalArgumentException("parent token must not be null");
- }
- ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
- if (r == null) {
- return null;
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback must not be null");
- }
- return mStackSupervisor.createVirtualActivityContainer(r, callback);
- }
- }
-
- @Override
- public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
+ public int createStackOnDisplay(int displayId) throws RemoteException {
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
synchronized (this) {
final int stackId = mStackSupervisor.getNextStackId();
final ActivityStack stack =
mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
if (stack == null) {
- return null;
+ return INVALID_STACK_ID;
}
- return stack.mActivityContainer;
+ return stack.mStackId;
}
}
@Override
public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
synchronized (this) {
- ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
- if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
- return stack.mActivityContainer.getDisplayId();
+ final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
+ if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
+ return stack.mDisplayId;
}
return DEFAULT_DISPLAY;
}
@@ -24364,7 +24319,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
resolvedType, null, null, null, null, 0, 0, null, null,
- null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
+ null, bOptions, false, callingUser, tr, "AppTaskImpl");
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 9273b3c49074..45357cb67fd1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -19,7 +19,6 @@ package com.android.server.am;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AppGlobals;
-import android.app.IActivityContainer;
import android.app.IActivityController;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
@@ -1959,9 +1958,17 @@ final class ActivityManagerShellCommand extends ShellCommand {
throw new RuntimeException(e.getMessage(), e);
}
- IActivityContainer container = mInterface.createStackOnDisplay(displayId);
- if (container != null) {
- container.startActivity(intent);
+ final int stackId = mInterface.createStackOnDisplay(displayId);
+ if (stackId != INVALID_STACK_ID) {
+ // TODO: Need proper support if this is used by test...
+// container.startActivity(intent);
+// ActivityOptions options = ActivityOptions.makeBasic();
+// options.setLaunchDisplayId(displayId);
+// options.setLaunchStackId(stackId);
+// mInterface.startAct
+// mInterface.startActivityAsUser(null, null, intent, mimeType,
+// null, null, 0, mStartFlags, profilerInfo,
+// options != null ? options.toBundle() : null, mUserId);
}
return 0;
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 6f68c7a1df5f..9a1d9282d9bc 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -164,7 +164,6 @@ import com.android.internal.util.XmlUtils;
import com.android.server.AttributeCache;
import com.android.server.AttributeCache.Entry;
import com.android.server.am.ActivityStack.ActivityState;
-import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import com.android.server.wm.AppWindowContainerController;
import com.android.server.wm.AppWindowContainerListener;
import com.android.server.wm.TaskWindowContainerController;
@@ -306,7 +305,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
int launchCount; // count of launches since last state
long lastLaunchTime; // time of last launch of this activity
ComponentName requestedVrComponent; // the requested component for handling VR mode.
- ArrayList<ActivityContainer> mChildContainers = new ArrayList<>();
String stringName; // for caching of toString().
@@ -320,7 +318,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
boolean mUpdateTaskThumbnailWhenHidden;
- ActivityContainer mInitialActivityContainer;
TaskDescription taskDescription; // the recents information for this activity
boolean mLaunchTaskBehind; // this activity is actively being launched with
@@ -798,8 +795,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
ActivityInfo aInfo, Configuration _configuration,
ActivityRecord _resultTo, String _resultWho, int _reqCode,
boolean _componentSpecified, boolean _rootVoiceInteraction,
- ActivityStackSupervisor supervisor,
- ActivityContainer container, ActivityOptions options, ActivityRecord sourceRecord) {
+ ActivityStackSupervisor supervisor, ActivityOptions options,
+ ActivityRecord sourceRecord) {
service = _service;
appToken = new Token(this);
info = aInfo;
@@ -830,7 +827,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
idle = false;
hasBeenLaunched = false;
mStackSupervisor = supervisor;
- mInitialActivityContainer = container;
mRotationAnimationHint = aInfo.rotationAnimation;
@@ -1595,11 +1591,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
mUpdateTaskThumbnailWhenHidden = false;
}
setVisibility(visible);
- final ArrayList<ActivityContainer> containers = mChildContainers;
- for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
- final ActivityContainer container = containers.get(containerNdx);
- container.setVisible(visible);
- }
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
}
@@ -2615,8 +2606,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
startFreezingScreenLocked(app, 0);
- mStackSupervisor.removeChildActivityContainers(this);
-
try {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
"Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
@@ -2795,7 +2784,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
- stackSupervisor, null /* container */, null /* options */, null /* sourceRecord */);
+ stackSupervisor, null /* options */, null /* sourceRecord */);
r.persistentState = persistentState;
r.taskDescription = taskDescription;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ab76529cf5f6..ce8aa5edad47 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -30,6 +30,7 @@ import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
+import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP;
@@ -124,7 +125,6 @@ import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService.ItemMatcher;
-import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import com.android.server.wm.StackWindowController;
import com.android.server.wm.StackWindowListener;
import com.android.server.wm.WindowManagerService;
@@ -205,7 +205,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
@Override
protected ConfigurationContainer getParent() {
- return mActivityContainer.mActivityDisplay;
+ return getDisplay();
}
@Override
@@ -336,8 +336,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
int mCurrentUser;
final int mStackId;
- final ActivityContainer mActivityContainer;
/** The other stacks, in order, on the attached display. Updated at attach/detach time. */
+ // TODO: This list doesn't belong here...
ArrayList<ActivityStack> mStacks;
/** The attached Display's unique identifier, or -1 if detached */
int mDisplayId;
@@ -447,24 +447,21 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
return count;
}
- ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer,
- RecentTasks recentTasks, boolean onTop) {
- mActivityContainer = activityContainer;
- mStackSupervisor = activityContainer.getOuter();
- mService = mStackSupervisor.mService;
+ ActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId,
+ ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) {
+ mStackSupervisor = supervisor;
+ mService = supervisor.mService;
mHandler = new ActivityStackHandler(mService.mHandler.getLooper());
mWindowManager = mService.mWindowManager;
- mStackId = activityContainer.mStackId;
+ mStackId = stackId;
mCurrentUser = mService.mUserController.getCurrentUserIdLocked();
mRecentTasks = recentTasks;
mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID
? new LaunchingTaskPositioner() : null;
- final ActivityStackSupervisor.ActivityDisplay display = mActivityContainer.mActivityDisplay;
mTmpRect2.setEmpty();
mWindowContainerController = createStackWindowController(display.mDisplayId, onTop,
mTmpRect2);
- activityContainer.mStack = this;
- mStackSupervisor.mActivityContainers.put(mStackId, activityContainer);
+ mStackSupervisor.mStacks.put(mStackId, this);
postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
}
@@ -521,7 +518,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
* either destroyed completely or re-parented.
*/
private void removeFromDisplay() {
- mDisplayId = Display.INVALID_DISPLAY;
+ final ActivityStackSupervisor.ActivityDisplay display = getDisplay();
+ if (display != null) {
+ display.detachStack(this);
+ }
+ mDisplayId = INVALID_DISPLAY;
mStacks = null;
if (mTaskPositioner != null) {
mTaskPositioner.reset();
@@ -537,14 +538,18 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
/** Removes the stack completely. Also calls WindowManager to do the same on its side. */
void remove() {
removeFromDisplay();
- mStackSupervisor.deleteActivityContainerRecord(mStackId);
+ mStackSupervisor.mStacks.remove(mStackId);
mWindowContainerController.removeContainer();
mWindowContainerController = null;
onParentChanged();
}
+ ActivityStackSupervisor.ActivityDisplay getDisplay() {
+ return mStackSupervisor.getActivityDisplay(mDisplayId);
+ }
+
void getDisplaySize(Point out) {
- mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
+ getDisplay().mDisplay.getSize(out);
}
/**
@@ -829,8 +834,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
final boolean isOnHomeDisplay() {
- return isAttached() &&
- mActivityContainer.mActivityDisplay.mDisplayId == DEFAULT_DISPLAY;
+ return isAttached() && mDisplayId == DEFAULT_DISPLAY;
}
void moveToFront(String reason) {
@@ -1257,12 +1261,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
return false;
}
- if (mActivityContainer.mParentActivity == null) {
- // Top level stack, not a child. Look for child stacks.
- mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming,
- pauseImmediately);
- }
-
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev);
else if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Start pausing: " + prev);
mResumedActivity = null;
@@ -1965,8 +1963,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
* {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
*/
private boolean canShowWithInsecureKeyguard() {
- final ActivityStackSupervisor.ActivityDisplay activityDisplay
- = mActivityContainer.mActivityDisplay;
+ final ActivityStackSupervisor.ActivityDisplay activityDisplay = getDisplay();
if (activityDisplay == null) {
throw new IllegalStateException("Stack is not attached to any display, stackId="
+ mStackId);
@@ -2108,7 +2105,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
* occurred and the activity will be notified immediately.
*/
void notifyActivityDrawnLocked(ActivityRecord r) {
- mActivityContainer.setDrawn();
if ((r == null)
|| (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
@@ -2236,12 +2232,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
final boolean hasRunningActivity = next != null;
- final ActivityRecord parent = mActivityContainer.mParentActivity;
- final boolean isParentNotResumed = parent != null && parent.state != ActivityState.RESUMED;
- if (hasRunningActivity
- && (isParentNotResumed || !mActivityContainer.isAttachedLocked())) {
- // Do not resume this stack if its parent is not resumed.
- // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
+ // TODO: Maybe this entire condition can get removed?
+ if (hasRunningActivity && getDisplay() == null) {
return false;
}
@@ -3809,7 +3801,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
}
if (noActivitiesInStack) {
- mActivityContainer.onTaskListEmptyLocked();
+ remove();
}
}
@@ -3920,7 +3912,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
destIntent, null /*ephemeralIntent*/, null, aInfo, null /*rInfo*/, null,
null, parent.appToken, null, 0, -1, parent.launchedFromUid,
parent.launchedFromPackage, -1, parent.launchedFromUid, 0, null,
- false, true, null, null, null, "navigateUpTo");
+ false, true, null, null, "navigateUpTo");
foundParentInTask = res == ActivityManager.START_SUCCESS;
} catch (RemoteException e) {
foundParentInTask = false;
@@ -4005,7 +3997,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
}
private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
- mStackSupervisor.removeChildActivityContainers(r);
finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
r.makeFinishingLocked();
if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
@@ -4620,7 +4611,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
* focus may be on another display.
*/
private ActivityStack getTopStackOnDisplay() {
- final ArrayList<ActivityStack> stacks = mActivityContainer.mActivityDisplay.mStacks;
+ final ArrayList<ActivityStack> stacks = getDisplay().mStacks;
return stacks.isEmpty() ? null : stacks.get(stacks.size() - 1);
}
@@ -5097,7 +5088,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
mStacks.add(0, this);
}
if (!isHomeOrRecentsStack()) {
- mActivityContainer.onTaskListEmptyLocked();
+ remove();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 90d9149a2f66..d9b7d761a7d2 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -36,8 +36,6 @@ import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
-import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.SYSTEM_UID;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
@@ -50,7 +48,6 @@ import static android.view.Display.TYPE_VIRTUAL;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
@@ -72,7 +69,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityManagerService.ANIMATE;
@@ -112,7 +108,6 @@ import android.app.ActivityManager.StackId;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
-import android.app.IActivityContainerCallback;
import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.app.StatusBarManager;
@@ -120,7 +115,6 @@ import android.app.WaitResult;
import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
-import android.content.IIntentSender;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -132,10 +126,7 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
-import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.DisplayManagerInternal;
-import android.hardware.display.VirtualDisplay;
-import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
import android.os.Binder;
import android.os.Bundle;
@@ -151,7 +142,6 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
-import android.os.TransactionTooLargeException;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
@@ -168,9 +158,8 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;
-import android.view.InputEvent;
-import android.view.Surface;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.TransferPipe;
@@ -194,7 +183,6 @@ import java.util.Set;
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
- private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
@@ -205,7 +193,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
private static final String TAG_STATES = TAG + POSTFIX_STATES;
private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
static final String TAG_TASKS = TAG + POSTFIX_TASKS;
- private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
/** How long we wait until giving up on the last activity telling us it is idle. */
static final int IDLE_TIMEOUT = 10 * 1000;
@@ -224,10 +211,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
static final int HANDLE_DISPLAY_ADDED = FIRST_SUPERVISOR_STACK_MSG + 5;
static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
- static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
- static final int CONTAINER_CALLBACK_TASK_LIST_EMPTY = FIRST_SUPERVISOR_STACK_MSG + 11;
static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
static final int SHOW_LOCK_TASK_ESCAPE_MESSAGE_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
@@ -414,7 +399,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// TODO: Add listener for removal of references.
/** Mapping from (ActivityStack/TaskStack).mStackId to their current state */
- SparseArray<ActivityContainer> mActivityContainers = new SparseArray<>();
+ SparseArray<ActivityStack> mStacks = new SparseArray<>();
// TODO: There should be an ActivityDisplayController coordinating am/wm interaction.
/** Mapping from displayId to display current state */
@@ -680,31 +665,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
boolean isFocusedStack(ActivityStack stack) {
- if (stack == null) {
- return false;
- }
-
- final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
- if (parent != null) {
- stack = parent.getStack();
- }
- return stack == mFocusedStack;
+ return stack != null && stack == mFocusedStack;
}
/** The top most stack on its display. */
boolean isFrontStackOnDisplay(ActivityStack stack) {
- return isFrontOfStackList(stack, stack.mActivityContainer.mActivityDisplay.mStacks);
+ return isFrontOfStackList(stack, stack.getDisplay().mStacks);
}
private boolean isFrontOfStackList(ActivityStack stack, List<ActivityStack> stackList) {
- if (stack == null) {
- return false;
- }
-
- final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
- if (parent != null) {
- stack = parent.getStack();
- }
return stack == stackList.get((stackList.size() - 1));
}
@@ -1097,21 +1066,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
return pausing;
}
- void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
- ActivityRecord resuming, boolean dontWait) {
- // TODO: Put all stacks in supervisor and iterate through them instead.
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- if (stack.mResumedActivity != null &&
- stack.mActivityContainer.mParentActivity == parent) {
- stack.startPausingLocked(userLeaving, uiSleeping, resuming, dontWait);
- }
- }
- }
- }
-
void cancelInitializingActivities() {
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -2210,9 +2164,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
protected <T extends ActivityStack> T getStack(int stackId, boolean createStaticStackIfNeeded,
boolean createOnTop) {
- final ActivityContainer activityContainer = mActivityContainers.get(stackId);
- if (activityContainer != null) {
- return (T) activityContainer.mStack;
+ final ActivityStack stack = mStacks.get(stackId);
+ if (stack != null) {
+ return (T) stack;
}
if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
return null;
@@ -2355,33 +2309,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
(StackId.isResizeableByDockedStack(stackId) && getStack(DOCKED_STACK_ID) != null);
}
- ActivityContainer createVirtualActivityContainer(ActivityRecord parentActivity,
- IActivityContainerCallback callback) {
- ActivityContainer activityContainer =
- new VirtualActivityContainer(parentActivity, callback);
- mActivityContainers.put(activityContainer.mStackId, activityContainer);
- if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
- "createActivityContainer: " + activityContainer);
- parentActivity.mChildContainers.add(activityContainer);
- return activityContainer;
- }
-
- void removeChildActivityContainers(ActivityRecord parentActivity) {
- final ArrayList<ActivityContainer> childStacks = parentActivity.mChildContainers;
- for (int containerNdx = childStacks.size() - 1; containerNdx >= 0; --containerNdx) {
- ActivityContainer container = childStacks.remove(containerNdx);
- if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "removeChildActivityContainers: removing "
- + container);
- container.release();
- }
- }
-
- void deleteActivityContainerRecord(int stackId) {
- if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
- "deleteActivityContainerRecord: callers=" + Debug.getCallers(4));
- mActivityContainers.remove(stackId);
- }
-
void resizeStackLocked(int stackId, Rect bounds, Rect tempTaskBounds, Rect tempTaskInsetBounds,
boolean preserveWindows, boolean allowResizeInDockedMode, boolean deferResume) {
if (stackId == DOCKED_STACK_ID) {
@@ -2646,12 +2573,18 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
if (activityDisplay == null) {
return null;
}
+ return createStack(stackId, activityDisplay, onTop);
- final ActivityContainer activityContainer =
- new ActivityContainer(stackId, activityDisplay, onTop);
- return activityContainer.mStack;
}
+ ActivityStack createStack(int stackId, ActivityDisplay display, boolean onTop) {
+ switch (stackId) {
+ case PINNED_STACK_ID:
+ return new PinnedActivityStack(display, stackId, this, mRecentTasks, onTop);
+ default:
+ return new ActivityStack(display, stackId, this, mRecentTasks, onTop);
+ }
+ }
void removeStackInSurfaceTransaction(int stackId) {
final ActivityStack stack = getStack(stackId);
@@ -2879,23 +2812,24 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId="
+ displayId);
}
- final ActivityContainer activityContainer = mActivityContainers.get(stackId);
- if (activityContainer != null) {
- if (activityContainer.isAttachedLocked()) {
- if (activityContainer.getDisplayId() == displayId) {
- throw new IllegalArgumentException("Trying to move stackId=" + stackId
- + " to its current displayId=" + displayId);
- }
-
- activityContainer.moveToDisplayLocked(activityDisplay, onTop);
- } else {
- throw new IllegalStateException("moveStackToDisplayLocked: Stack with stackId="
- + stackId + " is not attached to any display.");
- }
- } else {
+ final ActivityStack stack = mStacks.get(stackId);
+ if (stack == null) {
throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown stackId="
+ stackId);
}
+
+ final ActivityDisplay currentDisplay = stack.getDisplay();
+ if (currentDisplay == null) {
+ throw new IllegalStateException("moveStackToDisplayLocked: Stack with stack=" + stack
+ + " is not attached to any display.");
+ }
+
+ if (currentDisplay.mDisplayId == displayId) {
+ throw new IllegalArgumentException("Trying to move stack=" + stack
+ + " to its current displayId=" + displayId);
+ }
+
+ stack.reparent(activityDisplay, onTop);
// TODO(multi-display): resize stacks properly if moved from split-screen.
}
@@ -2923,7 +2857,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// Ensure that we're not moving a task to a dynamic stack if device doesn't support
// multi-display.
// TODO(multi-display): Support non-dynamic stacks on secondary displays.
- // TODO: Check ActivityView after fixing b/35349678.
if (StackId.isDynamicStack(stackId) && !mService.mSupportsMultiDisplay) {
throw new IllegalArgumentException("Device doesn't support multi-display, can not"
+ " reparent task=" + task + " to stackId=" + stackId);
@@ -3107,11 +3040,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
+ stack);
continue;
}
- if (!stack.mActivityContainer.isEligibleForNewTasks()) {
- if (DEBUG_TASKS) Slog.d(TAG_TASKS,
- "Skipping stack: (new task not allowed) " + stack);
- continue;
- }
stack.findTaskLocked(r, mTmpFindTaskResult);
// It is possible to have tasks in multiple stacks with the same root affinity, so
// we should keep looking after finding an affinity match to see if there is a
@@ -3626,7 +3554,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
pw.print(prefix);
pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
- pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
+ pw.print(prefix); pw.println("mStacks=" + mStacks);
pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
final SparseArray<String[]> packages = mService.mLockTaskPackages;
if (packages.size() > 0) {
@@ -3920,6 +3848,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
return getActivityDisplayOrCreateLocked(displayId) != null;
}
+ ActivityDisplay getActivityDisplay(int displayId) {
+ return mActivityDisplays.get(displayId);
+ }
+
/**
* Get an existing instance of {@link ActivityDisplay} or create new if there is a
* corresponding record in display manager.
@@ -4481,16 +4413,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
case HANDLE_DISPLAY_REMOVED: {
handleDisplayRemoved(msg.arg1);
} break;
- case CONTAINER_CALLBACK_VISIBILITY: {
- final ActivityContainer container = (ActivityContainer) msg.obj;
- final IActivityContainerCallback callback = container.mCallback;
- if (callback != null) {
- try {
- callback.setVisible(container.asBinder(), msg.arg1 == 1);
- } catch (RemoteException e) {
- }
- }
- } break;
case LOCK_TASK_START_MSG: {
// When lock task starts, we disable the status bars.
try {
@@ -4563,16 +4485,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
mLockTaskNotify.showToast(LOCK_TASK_MODE_PINNED);
} break;
- case CONTAINER_CALLBACK_TASK_LIST_EMPTY: {
- final ActivityContainer container = (ActivityContainer) msg.obj;
- final IActivityContainerCallback callback = container.mCallback;
- if (callback != null) {
- try {
- callback.onAllActivitiesComplete(container.asBinder());
- } catch (RemoteException e) {
- }
- }
- } break;
case LAUNCH_TASK_BEHIND_COMPLETE: {
synchronized (mService) {
ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
@@ -4586,340 +4498,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
}
- class ActivityContainer extends android.app.IActivityContainer.Stub {
- final static int FORCE_NEW_TASK_FLAGS = FLAG_ACTIVITY_NEW_TASK |
- FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION;
- final int mStackId;
- IActivityContainerCallback mCallback = null;
- ActivityStack mStack;
- ActivityRecord mParentActivity = null;
- String mIdString;
-
- boolean mVisible = true;
-
- /** Display this ActivityStack is currently on. Null if not attached to a Display. */
- ActivityDisplay mActivityDisplay;
-
- final static int CONTAINER_STATE_HAS_SURFACE = 0;
- final static int CONTAINER_STATE_NO_SURFACE = 1;
- final static int CONTAINER_STATE_FINISHING = 2;
- int mContainerState = CONTAINER_STATE_HAS_SURFACE;
-
- ActivityContainer(int stackId, ActivityDisplay activityDisplay, boolean onTop) {
- synchronized (mService) {
- mStackId = stackId;
- mActivityDisplay = activityDisplay;
- mIdString = "ActivtyContainer{" + mStackId + "}";
-
- createStack(stackId, onTop);
- if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
- }
- }
-
- protected void createStack(int stackId, boolean onTop) {
- switch (stackId) {
- case PINNED_STACK_ID:
- new PinnedActivityStack(this, mRecentTasks, onTop);
- break;
- default:
- new ActivityStack(this, mRecentTasks, onTop);
- break;
- }
- }
-
- /**
- * Adds the stack to specified display. Also calls WindowManager to do the same from
- * {@link ActivityStack#reparent(ActivityDisplay, boolean)}.
- * @param activityDisplay The display to add the stack to.
- */
- void addToDisplayLocked(ActivityDisplay activityDisplay) {
- if (DEBUG_STACK) Slog.d(TAG_STACK, "addToDisplayLocked: " + this
- + " to display=" + activityDisplay);
- if (mActivityDisplay != null) {
- throw new IllegalStateException("ActivityContainer is already attached, " +
- "displayId=" + mActivityDisplay.mDisplayId);
- }
- mActivityDisplay = activityDisplay;
- mStack.reparent(activityDisplay, true /* onTop */);
- }
-
- @Override
- public void addToDisplay(int displayId) {
- synchronized (mService) {
- final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
- if (activityDisplay == null) {
- return;
- }
- addToDisplayLocked(activityDisplay);
- }
- }
-
- @Override
- public int getDisplayId() {
- synchronized (mService) {
- if (mActivityDisplay != null) {
- return mActivityDisplay.mDisplayId;
- }
- }
- return -1;
- }
-
- @Override
- public int getStackId() {
- synchronized (mService) {
- return mStackId;
- }
- }
-
- @Override
- public boolean injectEvent(InputEvent event) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (mService) {
- if (mActivityDisplay != null) {
- return mInputManagerInternal.injectInputEvent(event,
- mActivityDisplay.mDisplayId,
- InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
- }
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public void release() {
- synchronized (mService) {
- if (mContainerState == CONTAINER_STATE_FINISHING) {
- return;
- }
- mContainerState = CONTAINER_STATE_FINISHING;
-
- long origId = Binder.clearCallingIdentity();
- try {
- mStack.finishAllActivitiesLocked(false);
- mService.mActivityStarter.removePendingActivityLaunchesLocked(mStack);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
-
- /**
- * Remove the stack completely. Must be called only when there are no tasks left in it,
- * as this method does not finish running activities.
- */
- void removeLocked() {
- if (DEBUG_STACK) Slog.d(TAG_STACK, "removeLocked: " + this + " from display="
- + mActivityDisplay + " Callers=" + Debug.getCallers(2));
- if (mActivityDisplay != null) {
- removeFromDisplayLocked();
- }
- mStack.remove();
- }
-
- /**
- * Remove the stack from its current {@link ActivityDisplay}, so it can be either destroyed
- * completely or re-parented.
- */
- private void removeFromDisplayLocked() {
- if (DEBUG_STACK) Slog.d(TAG_STACK, "removeFromDisplayLocked: " + this
- + " current displayId=" + mActivityDisplay.mDisplayId);
-
- mActivityDisplay.detachStack(mStack);
- mActivityDisplay = null;
- }
-
- /**
- * Move the stack to specified display.
- * @param activityDisplay Target display to move the stack to.
- * @param onTop Indicates whether container should be place on top or on bottom.
- */
- void moveToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
- if (DEBUG_STACK) Slog.d(TAG_STACK, "moveToDisplayLocked: " + this + " from display="
- + mActivityDisplay + " to display=" + activityDisplay
- + " Callers=" + Debug.getCallers(2));
-
- removeFromDisplayLocked();
-
- mActivityDisplay = activityDisplay;
- mStack.reparent(activityDisplay, onTop);
- }
-
- @Override
- public final int startActivity(Intent intent) {
- return mService.startActivity(intent, this);
- }
-
- @Override
- public final int startActivityIntentSender(IIntentSender intentSender)
- throws TransactionTooLargeException {
- mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");
-
- if (!(intentSender instanceof PendingIntentRecord)) {
- throw new IllegalArgumentException("Bad PendingIntent object");
- }
-
- final int userId = mService.mUserController.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), mCurrentUser, false,
- ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
-
- final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;
- checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,
- pendingIntent.key.requestResolvedType);
-
- return pendingIntent.sendInner(0, null, null, null, null, null, null, null, 0,
- FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);
- }
-
- void checkEmbeddedAllowedInner(int userId, Intent intent, String resolvedType) {
- ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, userId);
- if (aInfo != null && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
- throw new SecurityException(
- "Attempt to embed activity that has not set allowEmbedded=\"true\"");
- }
- }
-
- @Override
- public IBinder asBinder() {
- return this;
- }
-
- @Override
- public void setSurface(Surface surface, int width, int height, int density) {
- mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");
- }
-
- ActivityStackSupervisor getOuter() {
- return ActivityStackSupervisor.this;
- }
-
- boolean isAttachedLocked() {
- return mActivityDisplay != null;
- }
-
- // TODO: Make sure every change to ActivityRecord.visible results in a call to this.
- void setVisible(boolean visible) {
- if (mVisible != visible) {
- mVisible = visible;
- if (mCallback != null) {
- mHandler.obtainMessage(CONTAINER_CALLBACK_VISIBILITY, visible ? 1 : 0,
- 0 /* unused */, this).sendToTarget();
- }
- }
- }
-
- void setDrawn() {
- }
-
- // You can always start a new task on a regular ActivityStack.
- boolean isEligibleForNewTasks() {
- return true;
- }
-
- void onTaskListEmptyLocked() {
- removeLocked();
- mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
- }
-
- @Override
- public String toString() {
- return mIdString + (mActivityDisplay == null ? "N" : "A");
- }
- }
-
- private class VirtualActivityContainer extends ActivityContainer {
- Surface mSurface;
- boolean mDrawn = false;
-
- VirtualActivityContainer(ActivityRecord parent, IActivityContainerCallback callback) {
- super(getNextStackId(), parent.getStack().mActivityContainer.mActivityDisplay,
- true /* onTop */);
- mParentActivity = parent;
- mCallback = callback;
- mContainerState = CONTAINER_STATE_NO_SURFACE;
- mIdString = "VirtualActivityContainer{" + mStackId + ", parent=" + mParentActivity + "}";
- }
-
- @Override
- public void setSurface(Surface surface, int width, int height, int density) {
- super.setSurface(surface, width, height, density);
-
- synchronized (mService) {
- final long origId = Binder.clearCallingIdentity();
- try {
- setSurfaceLocked(surface, width, height, density);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
-
- private void setSurfaceLocked(Surface surface, int width, int height, int density) {
- if (mContainerState == CONTAINER_STATE_FINISHING) {
- return;
- }
- VirtualActivityDisplay virtualActivityDisplay =
- (VirtualActivityDisplay) mActivityDisplay;
- if (virtualActivityDisplay == null) {
- virtualActivityDisplay =
- new VirtualActivityDisplay(width, height, density);
- mActivityDisplay = virtualActivityDisplay;
- mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
- addToDisplayLocked(virtualActivityDisplay);
- }
-
- if (mSurface != null) {
- mSurface.release();
- }
-
- mSurface = surface;
- if (surface != null) {
- resumeFocusedStackTopActivityLocked();
- } else {
- mContainerState = CONTAINER_STATE_NO_SURFACE;
- ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
- if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
- mStack.startPausingLocked(false, true, null, false);
- }
- }
-
- setSurfaceIfReadyLocked();
-
- if (DEBUG_STACK) Slog.d(TAG_STACK,
- "setSurface: " + this + " to display=" + virtualActivityDisplay);
- }
-
- @Override
- boolean isAttachedLocked() {
- return mSurface != null && super.isAttachedLocked();
- }
-
- @Override
- void setDrawn() {
- synchronized (mService) {
- mDrawn = true;
- setSurfaceIfReadyLocked();
- }
- }
-
- // Never start a new task on an ActivityView if it isn't explicitly specified.
- @Override
- boolean isEligibleForNewTasks() {
- return false;
- }
-
- private void setSurfaceIfReadyLocked() {
- if (DEBUG_STACK) Slog.v(TAG_STACK, "setSurfaceIfReadyLocked: mDrawn=" + mDrawn +
- " mContainerState=" + mContainerState + " mSurface=" + mSurface);
- if (mDrawn && mSurface != null && mContainerState == CONTAINER_STATE_NO_SURFACE) {
- ((VirtualActivityDisplay) mActivityDisplay).setSurface(mSurface);
- mContainerState = CONTAINER_STATE_HAS_SURFACE;
- }
- }
- }
-
+ // TODO: Move to its own file.
/** Exactly one of these classes per Display in the system. Capable of holding zero or more
* attached {@link ActivityStack}s */
class ActivityDisplay extends ConfigurationContainer {
@@ -4934,7 +4513,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
/** Array of all UIDs that are present on the display. */
private IntArray mDisplayAccessUIDs = new IntArray();
+ @VisibleForTesting
ActivityDisplay() {
+ mActivityDisplays.put(mDisplayId, this);
}
// After instantiation, check that mDisplay is not null before using this. The alternative
@@ -5011,43 +4592,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
}
- class VirtualActivityDisplay extends ActivityDisplay {
- VirtualDisplay mVirtualDisplay;
-
- VirtualActivityDisplay(int width, int height, int density) {
- DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
- mVirtualDisplay = dm.createVirtualDisplay(mService.mContext, null /* projection */,
- VIRTUAL_DISPLAY_BASE_NAME, width, height, density, null /* surface */,
- DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
- DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, null /* callback */,
- null /* handler */, null /* uniqueId */);
-
- init(mVirtualDisplay.getDisplay());
-
- mWindowManager.onDisplayAdded(mDisplayId);
- }
-
- void setSurface(Surface surface) {
- if (mVirtualDisplay != null) {
- mVirtualDisplay.setSurface(surface);
- }
- }
-
- @Override
- void detachStack(ActivityStack stack) {
- super.detachStack(stack);
- if (mVirtualDisplay != null) {
- mVirtualDisplay.release();
- mVirtualDisplay = null;
- }
- }
-
- @Override
- public String toString() {
- return "VirtualActivityDisplay={" + mDisplayId + "}";
- }
- }
-
ActivityStack findStackBehind(ActivityStack stack) {
// TODO(multi-display): We are only looking for stacks on the default display.
final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
@@ -5154,7 +4698,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
userId = task.userId;
int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
- null, null, 0, 0, bOptions, userId, null, task, "startActivityFromRecents");
+ null, null, 0, 0, bOptions, userId, task, "startActivityFromRecents");
if (launchStackId == DOCKED_STACK_ID) {
setResizingDuringAnimation(task);
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 4f04066c6076..749583225bb2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -90,12 +90,10 @@ import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AppGlobals;
-import android.app.IActivityContainer;
import android.app.IApplicationThread;
import android.app.PendingIntent;
import android.app.ProfilerInfo;
import android.app.WaitResult;
-import android.content.ComponentName;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
@@ -260,8 +258,7 @@ class ActivityStarter {
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
- ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
- TaskRecord inTask, String reason) {
+ ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
@@ -274,7 +271,7 @@ class ActivityStarter {
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
- container, inTask);
+ inTask);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
@@ -292,8 +289,7 @@ class ActivityStarter {
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
- ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
- TaskRecord inTask) {
+ ActivityRecord[] outActivity, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle
@@ -505,10 +501,8 @@ class ActivityStarter {
if (DEBUG_PERMISSIONS_REVIEW) {
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
true, false) + "} from uid " + callingUid + " on display "
- + (container == null ? (mSupervisor.mFocusedStack == null ?
- DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId) :
- (container.mActivityDisplay == null ? DEFAULT_DISPLAY :
- container.mActivityDisplay.mDisplayId)));
+ + (mSupervisor.mFocusedStack == null
+ ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
}
}
}
@@ -530,7 +524,7 @@ class ActivityStarter {
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
- mSupervisor, container, options, sourceRecord);
+ mSupervisor, options, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}
@@ -649,7 +643,7 @@ class ActivityStarter {
null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
- null /*container*/, null /*inTask*/, "startHomeActivity: " + reason);
+ null /*inTask*/, "startHomeActivity: " + reason);
if (mSupervisor.inResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
@@ -674,7 +668,7 @@ class ActivityStarter {
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
- IActivityContainer iContainer, TaskRecord inTask, String reason) {
+ TaskRecord inTask, String reason) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -727,14 +721,7 @@ class ActivityStarter {
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
ActivityOptions options = ActivityOptions.fromBundle(bOptions);
- ActivityStackSupervisor.ActivityContainer container =
- (ActivityStackSupervisor.ActivityContainer)iContainer;
synchronized (mService) {
- if (container != null && container.mParentActivity != null &&
- container.mParentActivity.state != RESUMED) {
- // Cannot start a child activity if the parent is not resumed.
- return ActivityManager.START_CANCELED;
- }
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
int callingPid;
@@ -747,12 +734,7 @@ class ActivityStarter {
callingPid = callingUid = -1;
}
- final ActivityStack stack;
- if (container == null || container.mStack.isOnHomeDisplay()) {
- stack = mSupervisor.mFocusedStack;
- } else {
- stack = container.mStack;
- }
+ final ActivityStack stack = mSupervisor.mFocusedStack;
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -828,8 +810,8 @@ class ActivityStarter {
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
- options, ignoreTargetSecurity, componentSpecified, outRecord, container,
- inTask, reason);
+ options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
+ reason);
Binder.restoreCallingIdentity(origId);
@@ -954,7 +936,7 @@ class ActivityStarter {
resolvedTypes[i], aInfo, null /*rInfo*/, null, null, resultTo, null, -1,
callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, 0,
- options, false, componentSpecified, outActivity, null, null, reason);
+ options, false, componentSpecified, outActivity, null, reason);
if (res < 0) {
return res;
}
@@ -2069,13 +2051,6 @@ class ActivityStarter {
return currentStack;
}
- final ActivityStackSupervisor.ActivityContainer container = r.mInitialActivityContainer;
- if (container != null) {
- // The first time put it on the desired stack, after this put on task stack.
- r.mInitialActivityContainer = null;
- return container.mStack;
- }
-
if (canLaunchIntoFocusedStack(r, newTask)) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
@@ -2140,13 +2115,11 @@ class ActivityStarter {
default:
// Dynamic stacks behave similarly to the fullscreen stack and can contain any
// resizeable task.
- // TODO: Check ActivityView after fixing b/35349678.
canUseFocusedStack = isDynamicStack(focusedStackId)
&& r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
}
- return canUseFocusedStack
- && (!newTask || focusedStack.mActivityContainer.isEligibleForNewTasks())
+ return canUseFocusedStack && !newTask
// We strongly prefer to launch activities on the same display as their source.
&& (mSourceDisplayId == focusedStack.mDisplayId);
}
@@ -2212,9 +2185,7 @@ class ActivityStarter {
// The parent activity doesn't want to launch the activity on top of itself, but
// instead tries to put it onto other side in side-by-side mode.
- final ActivityStack parentStack = task != null ? task.getStack()
- : r.mInitialActivityContainer != null ? r.mInitialActivityContainer.mStack
- : mSupervisor.mFocusedStack;
+ final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
if (parentStack != mSupervisor.mFocusedStack) {
// If task's parent stack is not focused - use it during adjacent launch.
@@ -2265,7 +2236,6 @@ class ActivityStarter {
case ASSISTANT_STACK_ID:
return r.isAssistantActivity();
default:
- // TODO: Check ActivityView after fixing b/35349678.
if (StackId.isDynamicStack(stackId)) {
return r.canBeLaunchedOnDisplay(displayId);
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 0d1c579f2b81..fc03db1203bd 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -409,10 +409,9 @@ class AppErrors {
final Set<String> cats = task.intent.getCategories();
if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) {
mService.startActivityInPackage(task.mCallingUid,
- task.mCallingPackage, task.intent,
- null, null, null, 0, 0,
- ActivityOptions.makeBasic().toBundle(),
- task.userId, null, null, "AppErrors");
+ task.mCallingPackage, task.intent, null, null, null, 0, 0,
+ ActivityOptions.makeBasic().toBundle(), task.userId, null,
+ "AppErrors");
}
}
}
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index cad5dcf6b565..ee593866da68 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -20,7 +20,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.app.ActivityManager;
-import android.app.IActivityContainer;
import android.content.IIntentSender;
import android.content.IIntentReceiver;
import android.app.PendingIntent;
@@ -37,7 +36,6 @@ import android.util.Slog;
import android.util.TimeUtils;
import com.android.internal.os.IResultReceiver;
-import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -234,30 +232,23 @@ final class PendingIntentRecord extends IIntentSender.Stub {
public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver,
- requiredPermission, null, null, 0, 0, 0, options, null);
+ requiredPermission, null, null, 0, 0, 0, options);
}
public int sendWithResult(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
return sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver,
- requiredPermission, null, null, 0, 0, 0, options, null);
+ requiredPermission, null, null, 0, 0, 0, options);
}
int sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver,
String requiredPermission, IBinder resultTo, String resultWho, int requestCode,
- int flagsMask, int flagsValues, Bundle options, IActivityContainer container) {
+ int flagsMask, int flagsValues, Bundle options) {
if (intent != null) intent.setDefusable(true);
if (options != null) options.setDefusable(true);
synchronized (owner) {
- final ActivityContainer activityContainer = (ActivityContainer)container;
- if (activityContainer != null && activityContainer.mParentActivity != null &&
- activityContainer.mParentActivity.state
- != ActivityStack.ActivityState.RESUMED) {
- // Cannot start a child activity if the parent is not resumed.
- return ActivityManager.START_CANCELED;
- }
if (!canceled) {
sent = true;
if ((key.flags&PendingIntent.FLAG_ONE_SHOT) != 0) {
@@ -346,7 +337,7 @@ final class PendingIntentRecord extends IIntentSender.Stub {
} else {
owner.startActivityInPackage(uid, key.packageName, finalIntent,
resolvedType, resultTo, resultWho, requestCode, 0,
- options, userId, container, null, "PendingIntentRecord");
+ options, userId, null, "PendingIntentRecord");
}
} catch (RuntimeException e) {
Slog.w(TAG, "Unable to send startActivity intent", e);
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 2010c24000e8..392fbb29d091 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -20,7 +20,6 @@ import android.app.RemoteAction;
import android.content.res.Configuration;
import android.graphics.Rect;
-import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import com.android.server.wm.PinnedStackWindowController;
import com.android.server.wm.PinnedStackWindowListener;
@@ -33,9 +32,9 @@ import java.util.List;
class PinnedActivityStack extends ActivityStack<PinnedStackWindowController>
implements PinnedStackWindowListener {
- PinnedActivityStack(ActivityContainer activityContainer,
- RecentTasks recentTasks, boolean onTop) {
- super(activityContainer, recentTasks, onTop);
+ PinnedActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId,
+ ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) {
+ super(display, stackId, supervisor, recentTasks, onTop);
}
@Override
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 96d857354f1a..751ecef63728 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1045,8 +1045,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
}
// We need to provide the current orientation of the display on which this task resides,
// not the orientation of the task.
- final int orientation =
- getStack().mActivityContainer.mActivityDisplay.getConfiguration().orientation;
+ final int orientation = getStack().getDisplay().getConfiguration().orientation;
return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, orientation);
}
diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java
index 048bef7b19f5..feddfe3a2169 100644
--- a/services/core/java/com/android/server/am/VrController.java
+++ b/services/core/java/com/android/server/am/VrController.java
@@ -163,6 +163,7 @@ final class VrController {
ComponentName requestedPackage;
ComponentName callingPackage;
int userId;
+ int processId = -1;
boolean changed = false;
synchronized (mGlobalAmLock) {
vrMode = record.requestedVrComponent != null;
@@ -172,11 +173,15 @@ final class VrController {
// Tell the VrController that a VR mode change is requested.
changed = changeVrModeLocked(vrMode, record.app);
+
+ if (record.app != null) {
+ processId = record.app.pid;
+ }
}
// Tell VrManager that a VR mode changed is requested, VrManager will handle
// notifying all non-AM dependencies if needed.
- vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
+ vrService.setVrMode(vrMode, requestedPackage, userId, processId, callingPackage);
return changed;
}
diff --git a/services/core/java/com/android/server/input/InputForwarder.java b/services/core/java/com/android/server/input/InputForwarder.java
new file mode 100644
index 000000000000..bebbc93e9ea5
--- /dev/null
+++ b/services/core/java/com/android/server/input/InputForwarder.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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.input;
+
+import android.app.IInputForwarder;
+import android.hardware.input.InputManagerInternal;
+import android.view.InputEvent;
+import android.os.Binder;
+
+import com.android.server.LocalServices;
+
+import static android.hardware.input.InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
+
+/**
+ * Basic implementation of {@link IInputForwarder}.
+ */
+class InputForwarder extends IInputForwarder.Stub {
+
+ private final InputManagerInternal mInputManagerInternal;
+ private final int mDisplayId;
+
+ InputForwarder(int displayId) {
+ mDisplayId = displayId;
+ mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
+ }
+
+ @Override
+ public boolean forwardEvent(InputEvent event) {
+ return mInputManagerInternal.injectInputEvent(event, mDisplayId,
+ INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 717efbf714db..fa9b1078e8ad 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -37,6 +37,7 @@ import com.android.server.Watchdog;
import org.xmlpull.v1.XmlPullParser;
import android.Manifest;
+import android.app.IInputForwarder;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -57,6 +58,7 @@ import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
+import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayViewport;
import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.IInputManager;
@@ -85,6 +87,7 @@ import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.util.Xml;
+import android.view.Display;
import android.view.IInputFilter;
import android.view.IInputFilterHost;
import android.view.IWindow;
@@ -1862,6 +1865,29 @@ public class InputManagerService extends IInputManager.Stub
nativeMonitor(mPtr);
}
+ // Binder call
+ @Override
+ public IInputForwarder createInputForwarder(int displayId) throws RemoteException {
+ if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS,
+ "createInputForwarder()")) {
+ throw new SecurityException("Requires INJECT_EVENTS permission");
+ }
+ final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+ final Display display = displayManager.getDisplay(displayId);
+ if (display == null) {
+ throw new IllegalArgumentException(
+ "Can't create input forwarder for non-existent displayId: " + displayId);
+ }
+ final int callingUid = Binder.getCallingUid();
+ final int displayOwnerUid = display.getOwnerUid();
+ if (callingUid != displayOwnerUid) {
+ throw new SecurityException(
+ "Only owner of the display can forward input events to it.");
+ }
+
+ return new InputForwarder(displayId);
+ }
+
// Native callback.
private void notifyConfigurationChanged(long whenNanos) {
mWindowManagerCallbacks.notifyConfigurationChanged();
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 83bb17eeaf3c..cdf25cfe65f6 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1754,20 +1754,32 @@ public class GnssLocationProvider implements LocationProviderInterface {
}
/**
- * called from native code - Gps measurements callback
+ * called from native code - GNSS measurements callback
*/
private void reportMeasurementData(GnssMeasurementsEvent event) {
if (!mItarSpeedLimitExceeded) {
- mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+ // send to handler to allow native to return quickly
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+ }
+ });
}
}
/**
- * called from native code - GPS navigation message callback
+ * called from native code - GNSS navigation message callback
*/
private void reportNavigationMessage(GnssNavigationMessage event) {
if (!mItarSpeedLimitExceeded) {
- mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+ // send to handler to allow native to return quickly
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index caf1d6ca5e35..924520b5a0f1 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -54,9 +54,8 @@ public abstract class GnssMeasurementsProvider
}
public void onGpsEnabledChanged() {
- if (tryUpdateRegistrationWithService()) {
- updateResult();
- }
+ tryUpdateRegistrationWithService();
+ updateResult();
}
@Override
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 8d2192892f74..df3c49bd2ed5 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -55,9 +55,8 @@ public abstract class GnssNavigationMessageProvider
}
public void onGpsEnabledChanged() {
- if (tryUpdateRegistrationWithService()) {
- updateResult();
- }
+ tryUpdateRegistrationWithService();
+ updateResult();
}
@Override
diff --git a/services/core/java/com/android/server/location/RemoteListenerHelper.java b/services/core/java/com/android/server/location/RemoteListenerHelper.java
index ec2828b1a59f..f51bc871c04f 100644
--- a/services/core/java/com/android/server/location/RemoteListenerHelper.java
+++ b/services/core/java/com/android/server/location/RemoteListenerHelper.java
@@ -25,6 +25,7 @@ import android.os.IInterface;
import android.os.RemoteException;
import android.util.Log;
+import java.lang.Runnable;
import java.util.HashMap;
import java.util.Map;
@@ -45,7 +46,7 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
private final Map<IBinder, LinkedListener> mListenerMap = new HashMap<>();
- private boolean mIsRegistered;
+ private boolean mIsRegistered; // must access only on handler thread
private boolean mHasIsSupported;
private boolean mIsSupported;
@@ -83,12 +84,12 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
} else if (mHasIsSupported && !mIsSupported) {
result = RESULT_NOT_SUPPORTED;
} else if (!isGpsEnabled()) {
- result = RESULT_GPS_LOCATION_DISABLED;
- } else if (!tryRegister()) {
// only attempt to register if GPS is enabled, otherwise we will register once GPS
// becomes available
- result = RESULT_INTERNAL_ERROR;
+ result = RESULT_GPS_LOCATION_DISABLED;
} else if (mHasIsSupported && mIsSupported) {
+ tryRegister();
+ // initially presume success, possible internal error could follow asynchornously
result = RESULT_SUCCESS;
} else {
// at this point if the supported flag is not set, the notification will be sent
@@ -117,8 +118,8 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
protected abstract boolean isAvailableInPlatform();
protected abstract boolean isGpsEnabled();
- protected abstract boolean registerWithService();
- protected abstract void unregisterFromService();
+ protected abstract boolean registerWithService(); // must access only on handler thread
+ protected abstract void unregisterFromService(); // must access only on handler thread
protected abstract ListenerOperation<TListener> getHandlerOperation(int result);
protected interface ListenerOperation<TListener extends IInterface> {
@@ -138,22 +139,16 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
}
}
- protected boolean tryUpdateRegistrationWithService() {
+ protected void tryUpdateRegistrationWithService() {
synchronized (mListenerMap) {
if (!isGpsEnabled()) {
tryUnregister();
- return true;
+ return;
}
if (mListenerMap.isEmpty()) {
- return true;
- }
- if (tryRegister()) {
- // registration was successful, there is no need to update the state
- return true;
+ return;
}
- ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
- foreachUnsafe(operation);
- return false;
+ tryRegister();
}
}
@@ -180,19 +175,40 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
}
}
- private boolean tryRegister() {
- if (!mIsRegistered) {
- mIsRegistered = registerWithService();
- }
- return mIsRegistered;
+ private void tryRegister() {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (!mIsRegistered) {
+ mIsRegistered = registerWithService();
+ }
+ if (!mIsRegistered) {
+ // post back a failure
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mListenerMap) {
+ ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
+ foreachUnsafe(operation);
+ }
+ }
+ });
+ }
+ }
+ });
}
private void tryUnregister() {
- if (!mIsRegistered) {
- return;
- }
- unregisterFromService();
- mIsRegistered = false;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (!mIsRegistered) {
+ return;
+ }
+ unregisterFromService();
+ mIsRegistered = false;
+ }
+ });
}
private int calculateCurrentResultUnsafe() {
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 5cc14b5ed520..3444ef3ec2fa 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -35,6 +35,7 @@ import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.notification.NotificationManagerService.DumpFilter;
import java.io.PrintWriter;
@@ -43,7 +44,8 @@ import java.util.Arrays;
public class ConditionProviders extends ManagedServices {
- private static final String TAG_ENABLED_DND_APPS = "dnd_apps";
+ @VisibleForTesting
+ static final String TAG_ENABLED_DND_APPS = "dnd_apps";
private final ArrayList<ConditionRecord> mRecords = new ArrayList<>();
private final ArraySet<String> mSystemConditionProviderNames;
@@ -84,7 +86,7 @@ public class ConditionProviders extends ManagedServices {
c.caption = "condition provider";
c.serviceInterface = ConditionProviderService.SERVICE_INTERFACE;
c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES;
- c.managedServiceTypeTag = TAG_ENABLED_DND_APPS;
+ c.xmlTag = TAG_ENABLED_DND_APPS;
c.secondarySettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS;
c.bindPermission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
c.settingsAction = Settings.ACTION_CONDITION_PROVIDER_SETTINGS;
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 2f88740cd01b..80878131ae44 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -52,6 +52,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.util.XmlUtils;
import com.android.server.notification.NotificationManagerService.DumpFilter;
import org.xmlpull.v1.XmlPullParser;
@@ -226,7 +227,7 @@ abstract public class ManagedServices {
}
public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
- out.startTag(null, getConfig().managedServiceTypeTag);
+ out.startTag(null, getConfig().xmlTag);
if (forBackup) {
trimApprovedListsAccordingToInstalledServices();
@@ -241,7 +242,7 @@ abstract public class ManagedServices {
for (int j = 0; j < M; j++) {
final boolean isPrimary = approvedByType.keyAt(j);
final Set<String> approved = approvedByType.valueAt(j);
- if (approved != null && approved.size() > 0) {
+ if (approved != null) {
String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
out.startTag(null, TAG_MANAGED_SERVICES);
out.attribute(null, ATT_APPROVED_LIST, allowedItems);
@@ -260,43 +261,34 @@ abstract public class ManagedServices {
}
}
- out.endTag(null, getConfig().managedServiceTypeTag);
+ out.endTag(null, getConfig().xmlTag);
}
- /**
- * @return false if modifications were made to the data on load that requires the xml file
- * to be re-written
- */
- public boolean readXml(XmlPullParser parser)
+ protected void migrateToXml() {
+ loadAllowedComponentsFromSettings();
+ }
+
+ public void readXml(XmlPullParser parser)
throws XmlPullParserException, IOException {
- boolean rewriteXml = false;
- int type = parser.getEventType();
- String tag = parser.getName();
- if (type != XmlPullParser.START_TAG || !getConfig().managedServiceTypeTag.equals(tag)) {
- // xml empty/invalid - read from setting instead
- loadAllowedComponentsFromSettings();
- rewriteXml = true;
- } else {
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
- tag = parser.getName();
- if (type == XmlPullParser.END_TAG
- && getConfig().managedServiceTypeTag.equals(tag)) {
- break;
- }
- if (type == XmlPullParser.START_TAG) {
- if (TAG_MANAGED_SERVICES.equals(tag)) {
- final String approved = XmlUtils.safeString(parser, ATT_APPROVED_LIST, "");
- final int userId = XmlUtils.safeInt(parser, ATT_USER_ID, 0);
- final boolean isPrimary = XmlUtils.safeBool(parser, ATT_IS_PRIMARY, true);
- addApprovedList(approved, userId, isPrimary);
- }
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ String tag = parser.getName();
+ if (type == XmlPullParser.END_TAG
+ && getConfig().xmlTag.equals(tag)) {
+ break;
+ }
+ if (type == XmlPullParser.START_TAG) {
+ if (TAG_MANAGED_SERVICES.equals(tag)) {
+ final String approved = XmlUtils.readStringAttribute(parser, ATT_APPROVED_LIST);
+ final int userId = XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
+ final boolean isPrimary =
+ XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true);
+ addApprovedList(approved, userId, isPrimary);
+ mUseXml = true;
}
}
- mUseXml = true;
}
rebindServices(false);
-
- return rewriteXml;
}
private void loadAllowedComponentsFromSettings() {
@@ -1119,7 +1111,7 @@ abstract public class ManagedServices {
public String serviceInterface;
public String secureSettingName;
public String secondarySettingName;
- public String managedServiceTypeTag;
+ public String xmlTag;
public String bindPermission;
public String settingsAction;
public int clientLabel;
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index 12b29cff5c13..91fee4669846 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -16,14 +16,14 @@
package com.android.server.notification;
-import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.net.Uri;
-import android.service.notification.NotificationListenerService;
import android.util.Log;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+
/**
* This {@link com.android.server.notification.NotificationSignalExtractor} notices noisy
* notifications and marks them to get a temporary ranking bump.
@@ -34,7 +34,8 @@ public class NotificationIntrusivenessExtractor implements NotificationSignalExt
/** Length of time (in milliseconds) that an intrusive or noisy notification will stay at
the top of the ranking order, before it falls back to its natural position. */
- private static final long HANG_TIME_MS = 10000;
+ @VisibleForTesting
+ static final long HANG_TIME_MS = 10000;
public void initialize(Context ctx, NotificationUsageStats usageStats) {
if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
@@ -46,7 +47,8 @@ public class NotificationIntrusivenessExtractor implements NotificationSignalExt
return null;
}
- if (record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT) {
+ if (record.getFreshnessMs(System.currentTimeMillis()) < HANG_TIME_MS
+ && record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT) {
if (record.getSound() != null && record.getSound() != Uri.EMPTY) {
record.setRecentlyIntrusive(true);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c04124a4b8a0..fb391f885874 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -55,7 +55,6 @@ import static android.service.notification.NotificationListenerService.TRIM_LIGH
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
-import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import android.Manifest;
import android.annotation.NonNull;
@@ -162,6 +161,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.XmlUtils;
import com.android.server.DeviceIdleController;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -342,7 +342,7 @@ public class NotificationManagerService extends SystemService {
private final UserProfiles mUserProfiles = new UserProfiles();
private NotificationListeners mListeners;
- private NotificationAssistants mNotificationAssistants;
+ private NotificationAssistants mAssistants;
private ConditionProviders mConditionProviders;
private NotificationUsageStats mUsageStats;
@@ -441,24 +441,38 @@ public class NotificationManagerService extends SystemService {
}
}
- private void readPolicyXml(InputStream stream, boolean forRestore)
+ void readPolicyXml(InputStream stream, boolean forRestore)
throws XmlPullParserException, NumberFormatException, IOException {
final XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, StandardCharsets.UTF_8.name());
-
- boolean saveXml = false;
- while (parser.next() != END_DOCUMENT) {
- mZenModeHelper.readXml(parser, forRestore);
- mRankingHelper.readXml(parser, forRestore);
+ XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY);
+ boolean migratedManagedServices = false;
+ int outerDepth = parser.getDepth();
+ while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+ if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) {
+ mZenModeHelper.readXml(parser, forRestore);
+ } else if (RankingHelper.TAG_RANKING.equals(parser.getName())){
+ mRankingHelper.readXml(parser, forRestore);
+ }
// No non-system managed services are allowed on low ram devices
if (!ActivityManager.isLowRamDeviceStatic()) {
- saveXml |= mListeners.readXml(parser);
- saveXml |= mNotificationAssistants.readXml(parser);
- saveXml |= mConditionProviders.readXml(parser);
+ if (mListeners.getConfig().xmlTag.equals(parser.getName())) {
+ mListeners.readXml(parser);
+ migratedManagedServices = true;
+ } else if (mAssistants.getConfig().xmlTag.equals(parser.getName())) {
+ mAssistants.readXml(parser);
+ migratedManagedServices = true;
+ } else if (mConditionProviders.getConfig().xmlTag.equals(parser.getName())) {
+ mConditionProviders.readXml(parser);
+ migratedManagedServices = true;
+ }
}
}
- if (saveXml) {
+ if (!migratedManagedServices) {
+ mListeners.migrateToXml();
+ mAssistants.migrateToXml();
+ mConditionProviders.migrateToXml();
savePolicyFile();
}
}
@@ -467,7 +481,7 @@ public class NotificationManagerService extends SystemService {
if (DBG) Slog.d(TAG, "loadPolicyFile");
synchronized (mPolicyFile) {
- FileInputStream infile = null;
+ InputStream infile = null;
try {
infile = mPolicyFile.openRead();
readPolicyXml(infile, false /*forRestore*/);
@@ -523,7 +537,7 @@ public class NotificationManagerService extends SystemService {
mZenModeHelper.writeXml(out, forBackup);
mRankingHelper.writeXml(out, forBackup);
mListeners.writeXml(out, forBackup);
- mNotificationAssistants.writeXml(out, forBackup);
+ mAssistants.writeXml(out, forBackup);
mConditionProviders.writeXml(out, forBackup);
out.endTag(null, TAG_NOTIFICATION_POLICY);
out.endDocument();
@@ -898,7 +912,7 @@ public class NotificationManagerService extends SystemService {
}
}
mListeners.onPackagesChanged(removingPackage, pkgList, uidList);
- mNotificationAssistants.onPackagesChanged(removingPackage, pkgList, uidList);
+ mAssistants.onPackagesChanged(removingPackage, pkgList, uidList);
mConditionProviders.onPackagesChanged(removingPackage, pkgList, uidList);
mRankingHelper.onPackagesChanged(removingPackage, changeUserId, pkgList, uidList);
savePolicyFile();
@@ -970,7 +984,7 @@ public class NotificationManagerService extends SystemService {
// Refresh managed services
mConditionProviders.onUserSwitched(user);
mListeners.onUserSwitched(user);
- mNotificationAssistants.onUserSwitched(user);
+ mAssistants.onUserSwitched(user);
mZenModeHelper.onUserSwitched(user);
} else if (action.equals(Intent.ACTION_USER_ADDED)) {
mUserProfiles.updateCache(context);
@@ -983,7 +997,7 @@ public class NotificationManagerService extends SystemService {
final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
mConditionProviders.onUserUnlocked(user);
mListeners.onUserUnlocked(user);
- mNotificationAssistants.onUserUnlocked(user);
+ mAssistants.onUserUnlocked(user);
mZenModeHelper.onUserUnlocked(user);
}
}
@@ -1231,7 +1245,7 @@ public class NotificationManagerService extends SystemService {
mListeners = notificationListeners;
// This is a MangedServices object that keeps track of the assistant.
- mNotificationAssistants = notificationAssistants;
+ mAssistants = notificationAssistants;
mPolicyFile = policyFile;
loadPolicyFile();
@@ -1400,7 +1414,7 @@ public class NotificationManagerService extends SystemService {
// bind to listener services.
mSettingsObserver.observe();
mListeners.onBootPhaseAppsCanStart();
- mNotificationAssistants.onBootPhaseAppsCanStart();
+ mAssistants.onBootPhaseAppsCanStart();
mConditionProviders.onBootPhaseAppsCanStart();
}
}
@@ -1569,7 +1583,6 @@ public class NotificationManagerService extends SystemService {
Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback);
return ;
}
-
final boolean isSystemToast = isCallerSystemOrPhone() || ("android".equals(pkg));
final boolean isPackageSuspended =
isPackageSuspendedForUser(pkg, Binder.getCallingUid());
@@ -1928,7 +1941,7 @@ public class NotificationManagerService extends SystemService {
// Listener & assistant
mListeners.onPackagesChanged(true, packages, uids);
- mNotificationAssistants.onPackagesChanged(true, packages, uids);
+ mAssistants.onPackagesChanged(true, packages, uids);
// Zen
mConditionProviders.onPackagesChanged(true, packages, uids);
@@ -2134,8 +2147,8 @@ public class NotificationManagerService extends SystemService {
long identity = Binder.clearCallingIdentity();
try {
ManagedServices manager =
- mNotificationAssistants.isComponentEnabledForCurrentProfiles(component)
- ? mNotificationAssistants
+ mAssistants.isComponentEnabledForCurrentProfiles(component)
+ ? mAssistants
: mListeners;
manager.setComponentState(component, true);
} finally {
@@ -2255,7 +2268,7 @@ public class NotificationManagerService extends SystemService {
try {
synchronized (mNotificationLock) {
final ManagedServiceInfo info =
- mNotificationAssistants.checkServiceTokenLocked(token);
+ mAssistants.checkServiceTokenLocked(token);
unsnoozeNotificationInt(key, info);
}
} finally {
@@ -2788,7 +2801,7 @@ public class NotificationManagerService extends SystemService {
public boolean isNotificationAssistantAccessGranted(ComponentName assistant) {
Preconditions.checkNotNull(assistant);
checkCallerIsSystemOrSameApp(assistant.getPackageName());
- return mNotificationAssistants.isPackageOrComponentAllowed(assistant.flattenToString(),
+ return mAssistants.isPackageOrComponentAllowed(assistant.flattenToString(),
getCallingUserHandle().getIdentifier());
}
@@ -2835,7 +2848,7 @@ public class NotificationManagerService extends SystemService {
if (!mActivityManager.isLowRamDevice()) {
mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(),
userId, false, granted);
- mNotificationAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
+ mAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
userId, true, granted);
getContext().sendBroadcastAsUser(new Intent(
@@ -2854,7 +2867,7 @@ public class NotificationManagerService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
- mNotificationAssistants.checkServiceTokenLocked(token);
+ mAssistants.checkServiceTokenLocked(token);
int N = mEnqueuedNotifications.size();
for (int i = 0; i < N; i++) {
final NotificationRecord n = mEnqueuedNotifications.get(i);
@@ -2876,7 +2889,7 @@ public class NotificationManagerService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
- mNotificationAssistants.checkServiceTokenLocked(token);
+ mAssistants.checkServiceTokenLocked(token);
NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
applyAdjustment(n, adjustment);
}
@@ -2893,7 +2906,7 @@ public class NotificationManagerService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
- mNotificationAssistants.checkServiceTokenLocked(token);
+ mAssistants.checkServiceTokenLocked(token);
for (Adjustment adjustment : adjustments) {
NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
applyAdjustment(n, adjustment);
@@ -2989,9 +3002,11 @@ public class NotificationManagerService extends SystemService {
if (r == null) {
return;
}
- addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY);
- EventLogTags.writeNotificationAutogrouped(key);
- mRankingHandler.requestSort();
+ if (r.sbn.getOverrideGroupKey() == null) {
+ addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY);
+ EventLogTags.writeNotificationAutogrouped(key);
+ mRankingHandler.requestSort();
+ }
}
@GuardedBy("mNotificationLock")
@@ -3000,9 +3015,11 @@ public class NotificationManagerService extends SystemService {
if (r == null) {
return;
}
- addAutoGroupAdjustment(r, null);
- EventLogTags.writeNotificationUnautogrouped(key);
- mRankingHandler.requestSort();
+ if (r.sbn.getOverrideGroupKey() != null) {
+ addAutoGroupAdjustment(r, null);
+ EventLogTags.writeNotificationUnautogrouped(key);
+ mRankingHandler.requestSort();
+ }
}
private void addAutoGroupAdjustment(NotificationRecord r, String overrideGroupKey) {
@@ -3273,7 +3290,7 @@ public class NotificationManagerService extends SystemService {
}
pw.println(')');
pw.println("\n Notification assistant services:");
- mNotificationAssistants.dump(pw, filter);
+ mAssistants.dump(pw, filter);
}
if (!filter.filtered || zenOnly) {
@@ -3664,7 +3681,7 @@ public class NotificationManagerService extends SystemService {
cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted);
updateLightsLocked();
if (mSnoozeCriterionId != null) {
- mNotificationAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId);
+ mAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId);
mSnoozeHelper.snooze(r);
} else {
mSnoozeHelper.snooze(r, mDuration);
@@ -3728,8 +3745,8 @@ public class NotificationManagerService extends SystemService {
mRankingHelper.extractSignals(r);
// tell the assistant service about the notification
- if (mNotificationAssistants.isEnabled()) {
- mNotificationAssistants.onNotificationEnqueued(r);
+ if (mAssistants.isEnabled()) {
+ mAssistants.onNotificationEnqueued(r);
mHandler.postDelayed(new PostNotificationRunnable(r.getKey()),
DELAY_FOR_ASSISTANT_TIME);
} else {
@@ -5238,7 +5255,7 @@ public class NotificationManagerService extends SystemService {
Config c = new Config();
c.caption = "notification assistant service";
c.serviceInterface = NotificationAssistantService.SERVICE_INTERFACE;
- c.managedServiceTypeTag = TAG_ENABLED_NOTIFICATION_ASSISTANTS;
+ c.xmlTag = TAG_ENABLED_NOTIFICATION_ASSISTANTS;
c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT;
c.bindPermission = Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE;
c.settingsAction = Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS;
@@ -5350,7 +5367,7 @@ public class NotificationManagerService extends SystemService {
Config c = new Config();
c.caption = "notification listener";
c.serviceInterface = NotificationListenerService.SERVICE_INTERFACE;
- c.managedServiceTypeTag = TAG_ENABLED_NOTIFICATION_LISTENERS;
+ c.xmlTag = TAG_ENABLED_NOTIFICATION_LISTENERS;
c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS;
c.bindPermission = android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE;
c.settingsAction = Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS;
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 0d5cc2c112d5..9622a24a2d4d 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -20,6 +20,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.XmlUtils;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -64,7 +65,7 @@ public class RankingHelper implements RankingConfig {
private static final int XML_VERSION = 1;
- private static final String TAG_RANKING = "ranking";
+ static final String TAG_RANKING = "ranking";
private static final String TAG_PACKAGE = "package";
private static final String TAG_CHANNEL = "channel";
private static final String TAG_GROUP = "channelGroup";
@@ -169,7 +170,7 @@ public class RankingHelper implements RankingConfig {
}
if (type == XmlPullParser.START_TAG) {
if (TAG_PACKAGE.equals(tag)) {
- int uid = XmlUtils.safeInt(parser, ATT_UID, Record.UNKNOWN_UID);
+ int uid = XmlUtils.readIntAttribute(parser, ATT_UID, Record.UNKNOWN_UID);
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
if (forRestore) {
@@ -182,14 +183,21 @@ public class RankingHelper implements RankingConfig {
}
Record r = getOrCreateRecord(name, uid,
- XmlUtils.safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
- XmlUtils.safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
- XmlUtils.safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
- XmlUtils.safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
- r.importance = XmlUtils.safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
- r.priority = XmlUtils.safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
- r.visibility = XmlUtils.safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
- r.showBadge = XmlUtils.safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
+ XmlUtils.readIntAttribute(
+ parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
+ XmlUtils.readIntAttribute(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
+ XmlUtils.readIntAttribute(
+ parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
+ XmlUtils.readBooleanAttribute(
+ parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
+ r.importance = XmlUtils.readIntAttribute(
+ parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
+ r.priority = XmlUtils.readIntAttribute(
+ parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+ r.visibility = XmlUtils.readIntAttribute(
+ parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
+ r.showBadge = XmlUtils.readBooleanAttribute(
+ parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
final int innerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -214,7 +222,7 @@ public class RankingHelper implements RankingConfig {
if (TAG_CHANNEL.equals(tagName)) {
String id = parser.getAttributeValue(null, ATT_ID);
String channelName = parser.getAttributeValue(null, ATT_NAME);
- int channelImportance = XmlUtils.safeInt(
+ int channelImportance = XmlUtils.readIntAttribute(
parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
if (!TextUtils.isEmpty(id) && !TextUtils.isEmpty(channelName)) {
NotificationChannel channel = new NotificationChannel(id,
@@ -419,8 +427,7 @@ public class RankingHelper implements RankingConfig {
record.setAuthoritativeRank(i);
final String groupKey = record.getGroupKey();
NotificationRecord existingProxy = mProxyByGroupTmp.get(groupKey);
- if (existingProxy == null
- || record.getImportance() > existingProxy.getImportance()) {
+ if (existingProxy == null) {
mProxyByGroupTmp.put(groupKey, record);
}
}
diff --git a/services/core/java/com/android/server/notification/XmlUtils.java b/services/core/java/com/android/server/notification/XmlUtils.java
deleted file mode 100644
index 831d03970fe3..000000000000
--- a/services/core/java/com/android/server/notification/XmlUtils.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright (c) 2017, 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.notification;
-
-import android.annotation.NonNull;
-import android.text.TextUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-
-class XmlUtils {
-
- static @NonNull String safeString(XmlPullParser parser, String att, String defValue) {
- final String value = parser.getAttributeValue(null, att);
- if (value == null) return defValue;
- return value;
- }
-
- static @NonNull boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
- final String value = parser.getAttributeValue(null, att);
- if (TextUtils.isEmpty(value)) return defValue;
- return Boolean.parseBoolean(value);
- }
-
- static @NonNull int safeInt(XmlPullParser parser, String att, int defValue) {
- final String val = parser.getAttributeValue(null, att);
- return tryParseInt(val, defValue);
- }
-
- private static int tryParseInt(String value, int defValue) {
- if (TextUtils.isEmpty(value)) return defValue;
- try {
- return Integer.parseInt(value);
- } catch (NumberFormatException e) {
- return defValue;
- }
- }
-
-}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c68854286a19..0c72326095a6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -53,6 +53,7 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
+import android.os.UserManager;
import android.os.WorkSource;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -197,6 +198,9 @@ public final class PowerManagerService extends SystemService
// System property indicating that the screen should remain off until an explicit user action
private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
+ // System Property indicating that retail demo mode is currently enabled.
+ private static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled";
+
// Possible reasons for shutting down for use in data/misc/reboot/last_shutdown_reason
private static final String REASON_SHUTDOWN = "shutdown";
private static final String REASON_REBOOT = "reboot";
@@ -805,6 +809,9 @@ public final class PowerManagerService extends SystemService
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DOUBLE_TAP_TO_WAKE),
false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.DEVICE_DEMO_MODE),
+ false, mSettingsObserver, UserHandle.USER_SYSTEM);
IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE);
if (vrManager != null) {
try {
@@ -912,6 +919,11 @@ public final class PowerManagerService extends SystemService
}
}
+ final String retailDemoValue = UserManager.isDeviceInDemoMode(mContext) ? "1" : "0";
+ if (!retailDemoValue.equals(SystemProperties.get(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED))) {
+ SystemProperties.set(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, retailDemoValue);
+ }
+
final int oldScreenBrightnessSetting = getCurrentBrightnessSettingLocked();
mScreenBrightnessForVrSetting = Settings.System.getIntForUser(resolver,
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 1f7564027166..bdd9de011186 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -52,10 +52,11 @@ public abstract class VrManagerInternal {
* @param enabled {@code true} to enable VR mode.
* @param packageName The package name of the requested VrListenerService to bind.
* @param userId the user requesting the VrListenerService component.
+ * @param processId the process the component is running in.
* @param calling the component currently using VR mode, or null to leave unchanged.
*/
public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName,
- int userId, @NonNull ComponentName calling);
+ int userId, int processId, @NonNull ComponentName calling);
/**
* Set whether the system has acquired a sleep token.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index b10c9a3fd2ac..a6b8d94fb6b5 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -128,6 +128,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
private boolean mVrModeAllowed;
private boolean mVrModeEnabled;
private boolean mPersistentVrModeEnabled;
+ private boolean mRunning2dInVr;
+ private int mVrAppProcessId;
private EnabledComponentsObserver mComponentObserver;
private ManagedApplicationService mCurrentVrService;
private ComponentName mDefaultVrService;
@@ -178,7 +180,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
}
consumeAndApplyPendingStateLocked();
if (mBootsToVr && !mVrModeEnabled) {
- setVrMode(true, mDefaultVrService, 0, null);
+ setVrMode(true, mDefaultVrService, 0, -1, null);
}
} else {
// Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
@@ -187,12 +189,12 @@ public class VrManagerService extends SystemService implements EnabledComponentC
// Set pending state to current state.
mPendingState = (mVrModeEnabled && mCurrentVrService != null)
- ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
- mCurrentVrService.getUserId(), mCurrentVrModeComponent)
+ ? new VrState(mVrModeEnabled, mRunning2dInVr, mCurrentVrService.getComponent(),
+ mCurrentVrService.getUserId(), mVrAppProcessId, mCurrentVrModeComponent)
: null;
// Unbind current VR service and do necessary callbacks.
- updateCurrentVrServiceLocked(false, null, 0, null);
+ updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
}
}
}
@@ -274,26 +276,33 @@ public class VrManagerService extends SystemService implements EnabledComponentC
private static class VrState {
final boolean enabled;
+ final boolean running2dInVr;
final int userId;
+ final int processId;
final ComponentName targetPackageName;
final ComponentName callingPackage;
final long timestamp;
final boolean defaultPermissionsGranted;
- VrState(boolean enabled, ComponentName targetPackageName, int userId,
- ComponentName callingPackage) {
+
+ VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
+ int processId, ComponentName callingPackage) {
this.enabled = enabled;
+ this.running2dInVr = running2dInVr;
this.userId = userId;
+ this.processId = processId;
this.targetPackageName = targetPackageName;
this.callingPackage = callingPackage;
this.defaultPermissionsGranted = false;
this.timestamp = System.currentTimeMillis();
}
- VrState(boolean enabled, ComponentName targetPackageName, int userId,
- ComponentName callingPackage, boolean defaultPermissionsGranted) {
+ VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
+ int processId, ComponentName callingPackage, boolean defaultPermissionsGranted) {
this.enabled = enabled;
+ this.running2dInVr = running2dInVr;
this.userId = userId;
+ this.processId = processId;
this.targetPackageName = targetPackageName;
this.callingPackage = callingPackage;
this.defaultPermissionsGranted = defaultPermissionsGranted;
@@ -394,8 +403,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC
}
// There is an active service, update it if needed
- updateCurrentVrServiceLocked(mVrModeEnabled, mCurrentVrService.getComponent(),
- mCurrentVrService.getUserId(), mCurrentVrModeComponent);
+ updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr,
+ mCurrentVrService.getComponent(), mCurrentVrService.getUserId(),
+ mVrAppProcessId, mCurrentVrModeComponent);
}
}
@@ -531,9 +541,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC
*/
private final class LocalService extends VrManagerInternal {
@Override
- public void setVrMode(boolean enabled, ComponentName packageName, int userId,
+ public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
ComponentName callingPackage) {
- VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage);
+ VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
}
@Override
@@ -710,14 +720,16 @@ public class VrManagerService extends SystemService implements EnabledComponentC
* Note: Must be called while holding {@code mLock}.
*
* @param enabled new state for VR mode.
+ * @param running2dInVr true if we have a top-level 2D intent.
* @param component new component to be bound as a VR listener.
* @param userId user owning the component to be bound.
- * @param calling the component currently using VR mode.
+ * @param processId the process hosting the activity specified by calling.
+ * @param calling the component currently using VR mode or a 2D intent.
*
* @return {@code true} if the component/user combination specified is valid.
*/
- private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component,
- int userId, ComponentName calling) {
+ private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
+ @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
boolean sendUpdatedCaller = false;
final long identity = Binder.clearCallingIdentity();
@@ -777,6 +789,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
sendUpdatedCaller = true;
}
mCurrentVrModeComponent = calling;
+ mRunning2dInVr = running2dInVr;
+ mVrAppProcessId = processId;
if (mCurrentVrModeUser != userId) {
mCurrentVrModeUser = userId;
@@ -794,11 +808,13 @@ public class VrManagerService extends SystemService implements EnabledComponentC
if (mCurrentVrService != null && sendUpdatedCaller) {
final ComponentName c = mCurrentVrModeComponent;
+ final boolean b = running2dInVr;
+ final int pid = processId;
mCurrentVrService.sendEvent(new PendingEvent() {
@Override
public void runEvent(IInterface service) throws RemoteException {
IVrListener l = (IVrListener) service;
- l.focusedActivityChanged(c);
+ l.focusedActivityChanged(c, b, pid);
}
});
}
@@ -1001,20 +1017,20 @@ public class VrManagerService extends SystemService implements EnabledComponentC
*/
private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
if (mPendingState != null) {
- updateCurrentVrServiceLocked(mPendingState.enabled,
- mPendingState.targetPackageName, mPendingState.userId,
+ updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
+ mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
mPendingState.callingPackage);
mPendingState = null;
} else if (disconnectIfNoPendingState) {
- updateCurrentVrServiceLocked(false, null, 0, null);
+ updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
}
}
private void logStateLocked() {
ComponentName currentBoundService = (mCurrentVrService == null) ? null :
mCurrentVrService.getComponent();
- VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser,
- mCurrentVrModeComponent, mWasDefaultGranted);
+ VrState current = new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
+ mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted);
if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
mLoggingDeque.removeFirst();
}
@@ -1058,27 +1074,24 @@ public class VrManagerService extends SystemService implements EnabledComponentC
* Implementation of VrManagerInternal calls. These are callable from system services.
*/
private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
- int userId, @NonNull ComponentName callingPackage) {
+ int userId, int processId, @NonNull ComponentName callingPackage) {
synchronized (mLock) {
VrState pending;
ComponentName targetListener;
- ComponentName foregroundVrComponent;
// If the device is in persistent VR mode, then calls to disable VR mode are ignored,
// and the system default VR listener is used.
boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
- if (!enabled && mPersistentVrModeEnabled) {
+ boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
+ if (running2dInVr) {
targetListener = mDefaultVrService;
-
- // Current foreground component isn't a VR one (in 2D app case)
- foregroundVrComponent = null;
} else {
targetListener = targetPackageName;
- foregroundVrComponent = callingPackage;
}
- pending = new VrState(
- targetEnabledState, targetListener, userId, foregroundVrComponent);
+
+ pending = new VrState(targetEnabledState, running2dInVr, targetListener,
+ userId, processId, callingPackage);
if (!mVrModeAllowed) {
// We're not allowed to be in VR mode. Make this state pending. This will be
@@ -1103,8 +1116,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC
mPendingState = null;
}
- updateCurrentVrServiceLocked(
- targetEnabledState, targetListener, userId, foregroundVrComponent);
+ updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
+ userId, processId, callingPackage);
}
}
@@ -1113,7 +1126,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
setPersistentModeAndNotifyListenersLocked(enabled);
// Disabling persistent mode when not showing a VR should disable the overall vr mode.
if (!enabled && mCurrentVrModeComponent == null) {
- setVrMode(false, null, 0, null);
+ setVrMode(false, null, 0, -1, null);
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9b8d1a7c1c0c..847e7d2c88ab 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3584,7 +3584,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
private void updateCircularDisplayMaskIfNeeded() {
- // we're fullscreen and not hosted in an ActivityView
if (mContext.getResources().getConfiguration().isScreenRound()
&& mContext.getResources().getBoolean(
com.android.internal.R.bool.config_windowShowCircularMask)) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 85747287cf93..3757b7d0c53d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -99,7 +99,6 @@ import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
import com.android.server.broadcastradio.BroadcastRadioService;
import com.android.server.restrictions.RestrictionsManagerService;
-import com.android.server.retaildemo.RetailDemoModeService;
import com.android.server.security.KeyAttestationApplicationIdProviderService;
import com.android.server.security.KeyChainSystemService;
import com.android.server.soundtrigger.SoundTriggerService;
@@ -1536,10 +1535,6 @@ public final class SystemServer {
mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
traceEnd();
- traceBeginAndSlog("StartRetailDemoModeService");
- mSystemServiceManager.startService(RetailDemoModeService.class);
- traceEnd();
-
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOFILL)) {
traceBeginAndSlog("StartAutoFillService");
mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS);
diff --git a/services/retaildemo/Android.mk b/services/retaildemo/Android.mk
deleted file mode 100644
index 670c6bfa1e6a..000000000000
--- a/services/retaildemo/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := services.retaildemo
-
-LOCAL_SRC_FILES += \
- $(call all-java-files-under,java)
-
-LOCAL_JAVA_LIBRARIES := services.core
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
deleted file mode 100644
index 90c58d0279a7..000000000000
--- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2016 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.retaildemo;
-
-import android.app.AppGlobals;
-import android.app.PackageInstallObserver;
-import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Helper class for installing preloaded APKs
- */
-class PreloadAppsInstaller {
- private static final String SYSTEM_SERVER_PACKAGE_NAME = "android";
- private static String TAG = PreloadAppsInstaller.class.getSimpleName();
- private static final String PRELOAD_APK_EXT = ".apk.preload";
- private static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private final IPackageManager mPackageManager;
- private final File preloadsAppsDirectory;
- private final Context mContext;
-
- private final Map<String, String> mApkToPackageMap;
-
- PreloadAppsInstaller(Context context) {
- this(context, AppGlobals.getPackageManager(), Environment.getDataPreloadsAppsDirectory());
- }
-
- @VisibleForTesting
- PreloadAppsInstaller(Context context, IPackageManager packageManager, File preloadsAppsDirectory) {
- mContext = context;
- mPackageManager = packageManager;
- mApkToPackageMap = Collections.synchronizedMap(new ArrayMap<>());
- this.preloadsAppsDirectory = preloadsAppsDirectory;
- }
-
- void installApps(int userId) {
- File[] files = preloadsAppsDirectory.listFiles();
- AppInstallCounter counter = new AppInstallCounter(mContext, userId);
- if (ArrayUtils.isEmpty(files)) {
- counter.setExpectedAppsCount(0);
- return;
- }
- int expectedCount = 0;
- for (File file : files) {
- String apkName = file.getName();
- if (apkName.endsWith(PRELOAD_APK_EXT) && file.isFile()) {
- String packageName = mApkToPackageMap.get(apkName);
- if (packageName != null) {
- try {
- expectedCount++;
- installExistingPackage(packageName, userId, counter);
- } catch (Exception e) {
- Slog.e(TAG, "Failed to install existing package " + packageName, e);
- }
- } else {
- try {
- installPackage(file, userId, counter);
- expectedCount++;
- } catch (Exception e) {
- Slog.e(TAG, "Failed to install package from " + file, e);
- }
- }
- }
- }
- counter.setExpectedAppsCount(expectedCount);
- }
-
- private void installExistingPackage(String packageName, int userId,
- AppInstallCounter counter) {
- if (DEBUG) {
- Log.d(TAG, "installExistingPackage " + packageName + " u" + userId);
- }
- try {
- mPackageManager.installExistingPackageAsUser(packageName, userId,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } finally {
- counter.appInstallFinished();
- }
- }
-
- private void installPackage(File file, final int userId, AppInstallCounter counter)
- throws IOException, RemoteException {
- final String apkName = file.getName();
- if (DEBUG) {
- Log.d(TAG, "installPackage " + apkName + " u" + userId);
- }
- mPackageManager.installPackageAsUser(file.getPath(), new PackageInstallObserver() {
- @Override
- public void onPackageInstalled(String basePackageName, int returnCode, String msg,
- Bundle extras) {
- if (DEBUG) {
- Log.d(TAG, "Package " + basePackageName + " installed u" + userId
- + " returnCode: " + returnCode + " msg: " + msg);
- }
- // Don't notify the counter for now, we'll do it in installExistingPackage
- if (returnCode == PackageManager.INSTALL_SUCCEEDED) {
- mApkToPackageMap.put(apkName, basePackageName);
- // Install on user 0 so that the package is cached when demo user is re-created
- installExistingPackage(basePackageName, UserHandle.USER_SYSTEM, counter);
- } else if (returnCode == PackageManager.INSTALL_FAILED_ALREADY_EXISTS) {
- // This can only happen in first session after a reboot
- if (!mApkToPackageMap.containsKey(apkName)) {
- mApkToPackageMap.put(apkName, basePackageName);
- }
- installExistingPackage(basePackageName, userId, counter);
- } else {
- Log.e(TAG, "Package " + basePackageName + " cannot be installed from "
- + apkName + ": " + msg + " (returnCode " + returnCode + ")");
- counter.appInstallFinished();
- }
- }
- }.getBinder(), 0, SYSTEM_SERVER_PACKAGE_NAME, userId);
- }
-
- private static class AppInstallCounter {
- private int expectedCount = -1; // -1 means expectedCount not set
- private int finishedCount;
- private final Context mContext;
- private final int userId;
-
- AppInstallCounter(Context context, int userId) {
- mContext = context;
- this.userId = userId;
- }
-
- synchronized void appInstallFinished() {
- this.finishedCount++;
- checkIfAllFinished();
- }
-
- synchronized void setExpectedAppsCount(int expectedCount) {
- this.expectedCount = expectedCount;
- checkIfAllFinished();
- }
-
- private void checkIfAllFinished() {
- if (expectedCount == finishedCount) {
- Log.i(TAG, "All preloads finished installing for user " + userId);
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.DEMO_USER_SETUP_COMPLETE, "1", userId);
- }
- }
- }
-}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
deleted file mode 100644
index 711d4d9d8a91..000000000000
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * Copyright (C) 2016 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.retaildemo;
-
-import android.Manifest;
-import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
-import android.app.AppGlobals;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.RetailDemoModeServiceInternal;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.Environment;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.CallLog;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.KeyValueListParser;
-import android.util.Slog;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.os.BackgroundThread;
-import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.LocalServices;
-import com.android.server.PreloadsFileCacheExpirationJobService;
-import com.android.server.ServiceThread;
-import com.android.server.SystemService;
-import com.android.server.am.ActivityManagerService;
-import com.android.server.retaildemo.UserInactivityCountdownDialog.OnCountDownExpiredListener;
-
-import java.io.File;
-import java.util.ArrayList;
-
-public class RetailDemoModeService extends SystemService {
- private static final boolean DEBUG = false;
-
- private static final String TAG = RetailDemoModeService.class.getSimpleName();
- private static final String DEMO_USER_NAME = "Demo";
- private static final String ACTION_RESET_DEMO =
- "com.android.server.retaildemo.ACTION_RESET_DEMO";
- @VisibleForTesting
- static final String SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED = "sys.retaildemo.enabled";
-
- private static final int MSG_TURN_SCREEN_ON = 0;
- private static final int MSG_INACTIVITY_TIME_OUT = 1;
- private static final int MSG_START_NEW_SESSION = 2;
-
- private static final long SCREEN_WAKEUP_DELAY = 2500;
- private static final long USER_INACTIVITY_TIMEOUT_MIN = 10000;
- private static final long USER_INACTIVITY_TIMEOUT_DEFAULT = 90000;
- private static final long WARNING_DIALOG_TIMEOUT_DEFAULT = 0;
- private static final long MILLIS_PER_SECOND = 1000;
-
- @VisibleForTesting
- static final int[] VOLUME_STREAMS_TO_MUTE = {
- AudioSystem.STREAM_RING,
- AudioSystem.STREAM_MUSIC
- };
-
- // Tron Vars
- private static final String DEMO_SESSION_COUNT = "retail_demo_session_count";
- private static final String DEMO_SESSION_DURATION = "retail_demo_session_duration";
-
- boolean mDeviceInDemoMode;
- boolean mIsCarrierDemoMode;
- int mCurrentUserId = UserHandle.USER_SYSTEM;
- long mUserInactivityTimeout;
- long mWarningDialogTimeout;
- private Injector mInjector;
- Handler mHandler;
- private ServiceThread mHandlerThread;
- private String[] mCameraIdsWithFlash;
- private PreloadAppsInstaller mPreloadAppsInstaller;
-
- final Object mActivityLock = new Object();
- // Whether the newly created demo user has interacted with the screen yet
- @GuardedBy("mActivityLock")
- boolean mUserUntouched;
- @GuardedBy("mActivityLock")
- long mFirstUserActivityTime;
- @GuardedBy("mActivityLock")
- long mLastUserActivityTime;
-
- private boolean mSafeBootRestrictionInitialState;
- private int mPackageVerifierEnableInitialState;
-
- private IntentReceiver mBroadcastReceiver = null;
-
- private final class IntentReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!mDeviceInDemoMode) {
- return;
- }
- final String action = intent.getAction();
- switch (action) {
- case Intent.ACTION_SCREEN_OFF:
- mHandler.removeMessages(MSG_TURN_SCREEN_ON);
- mHandler.sendEmptyMessageDelayed(MSG_TURN_SCREEN_ON, SCREEN_WAKEUP_DELAY);
- break;
- case ACTION_RESET_DEMO:
- mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
- break;
- }
- }
- };
-
- final class MainHandler extends Handler {
-
- MainHandler(Looper looper) {
- super(looper, null, true);
- }
-
- @Override
- public void handleMessage(Message msg) {
- if (!mDeviceInDemoMode) {
- return;
- }
- switch (msg.what) {
- case MSG_TURN_SCREEN_ON:
- if (mInjector.isWakeLockHeld()) {
- mInjector.releaseWakeLock();
- }
- mInjector.acquireWakeLock();
- break;
- case MSG_INACTIVITY_TIME_OUT:
- if (!mIsCarrierDemoMode && isDemoLauncherDisabled()) {
- Slog.i(TAG, "User inactivity timeout reached");
- showInactivityCountdownDialog();
- }
- break;
- case MSG_START_NEW_SESSION:
- if (DEBUG) {
- Slog.d(TAG, "Switching to a new demo user");
- }
- removeMessages(MSG_START_NEW_SESSION);
- removeMessages(MSG_INACTIVITY_TIME_OUT);
- if (!mIsCarrierDemoMode && mCurrentUserId != UserHandle.USER_SYSTEM) {
- logSessionDuration();
- }
-
- final UserManager um = mInjector.getUserManager();
- UserInfo demoUser = null;
- if (mIsCarrierDemoMode) {
- // Re-use the existing demo user in carrier demo mode.
- for (UserInfo user : um.getUsers()) {
- if (user.isDemo()) {
- demoUser = user;
- break;
- }
- }
- }
-
- if (demoUser == null) {
- // User in carrier demo mode should survive reboots.
- final int flags = UserInfo.FLAG_DEMO
- | (mIsCarrierDemoMode ? 0 : UserInfo.FLAG_EPHEMERAL);
- demoUser = um.createUser(DEMO_USER_NAME, flags);
- }
-
- if (demoUser != null && mCurrentUserId != demoUser.id) {
- setupDemoUser(demoUser);
- mInjector.switchUser(demoUser.id);
- }
- break;
- }
- }
- }
-
- @VisibleForTesting
- class SettingsObserver extends ContentObserver {
-
- private final static String KEY_USER_INACTIVITY_TIMEOUT = "user_inactivity_timeout_ms";
- private final static String KEY_WARNING_DIALOG_TIMEOUT = "warning_dialog_timeout_ms";
-
- private final Uri mDeviceDemoModeUri = Settings.Global
- .getUriFor(Settings.Global.DEVICE_DEMO_MODE);
- private final Uri mDeviceProvisionedUri = Settings.Global
- .getUriFor(Settings.Global.DEVICE_PROVISIONED);
- private final Uri mRetailDemoConstantsUri = Settings.Global
- .getUriFor(Settings.Global.RETAIL_DEMO_MODE_CONSTANTS);
-
- private final KeyValueListParser mParser = new KeyValueListParser(',');
-
- public SettingsObserver(Handler handler) {
- super(handler);
- }
-
- public void register() {
- final ContentResolver cr = mInjector.getContentResolver();
- cr.registerContentObserver(mDeviceDemoModeUri, false, this, UserHandle.USER_SYSTEM);
- cr.registerContentObserver(mDeviceProvisionedUri, false, this, UserHandle.USER_SYSTEM);
- cr.registerContentObserver(mRetailDemoConstantsUri, false, this,
- UserHandle.USER_SYSTEM);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (mRetailDemoConstantsUri.equals(uri)) {
- refreshTimeoutConstants();
- return;
- }
-
- // If device is provisioned and left demo mode - run the cleanup in demo folder
- if (isDeviceProvisioned()) {
- if (UserManager.isDeviceInDemoMode(getContext())) {
- startDemoMode();
- } else {
- mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "0");
-
- // Run on the bg thread to not block the fg thread
- BackgroundThread.getHandler().post(() -> {
- if (!deletePreloadsFolderContents()) {
- Slog.w(TAG, "Failed to delete preloads folder contents");
- }
- PreloadsFileCacheExpirationJobService.schedule(mInjector.getContext());
- });
-
- stopDemoMode();
-
- if (mInjector.isWakeLockHeld()) {
- mInjector.releaseWakeLock();
- }
- }
- }
- }
-
- private void refreshTimeoutConstants() {
- try {
- mParser.setString(Settings.Global.getString(mInjector.getContentResolver(),
- Settings.Global.RETAIL_DEMO_MODE_CONSTANTS));
- } catch (IllegalArgumentException exc) {
- Slog.e(TAG, "Invalid string passed to KeyValueListParser");
- // Consuming the exception to fall back to default values.
- }
- mWarningDialogTimeout = mParser.getLong(KEY_WARNING_DIALOG_TIMEOUT,
- WARNING_DIALOG_TIMEOUT_DEFAULT);
- mUserInactivityTimeout = mParser.getLong(KEY_USER_INACTIVITY_TIMEOUT,
- USER_INACTIVITY_TIMEOUT_DEFAULT);
- mUserInactivityTimeout = Math.max(mUserInactivityTimeout, USER_INACTIVITY_TIMEOUT_MIN);
- }
- }
-
- private void showInactivityCountdownDialog() {
- UserInactivityCountdownDialog dialog = new UserInactivityCountdownDialog(getContext(),
- mWarningDialogTimeout, MILLIS_PER_SECOND);
- dialog.setNegativeButtonClickListener(null);
- dialog.setPositiveButtonClickListener(new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
- }
- });
- dialog.setOnCountDownExpiredListener(new OnCountDownExpiredListener() {
- @Override
- public void onCountDownExpired() {
- mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
- }
- });
- dialog.show();
- }
-
- public RetailDemoModeService(Context context) {
- this(new Injector(context));
- }
-
- @VisibleForTesting
- RetailDemoModeService(Injector injector) {
- super(injector.getContext());
-
- mInjector = injector;
- synchronized (mActivityLock) {
- mFirstUserActivityTime = mLastUserActivityTime = SystemClock.uptimeMillis();
- }
- }
-
- boolean isDemoLauncherDisabled() {
- int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
- try {
- final IPackageManager iPm = mInjector.getIPackageManager();
- final String demoLauncherComponent =
- getContext().getString(R.string.config_demoModeLauncherComponent);
- enabledState = iPm.getComponentEnabledSetting(
- ComponentName.unflattenFromString(demoLauncherComponent), mCurrentUserId);
- } catch (RemoteException re) {
- Slog.e(TAG, "Error retrieving demo launcher enabled setting", re);
- }
- return enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
- }
-
- private void setupDemoUser(UserInfo userInfo) {
- final UserManager um = mInjector.getUserManager();
- final UserHandle user = UserHandle.of(userInfo.id);
- um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
- um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
- um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
- um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
- um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
- um.setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user);
- // Set this to false because the default is true on user creation
- um.setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user);
- // Disallow rebooting in safe mode - controlled by user 0
- um.setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM);
- if (mIsCarrierDemoMode) {
- // Enable SMS in carrier demo mode.
- um.setUserRestriction(UserManager.DISALLOW_SMS, false, user);
- }
-
- Settings.Secure.putIntForUser(mInjector.getContentResolver(),
- Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
- Settings.Global.putInt(mInjector.getContentResolver(),
- Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
-
- grantRuntimePermissionToCamera(user);
- clearPrimaryCallLog();
-
- if (!mIsCarrierDemoMode) {
- // Enable demo launcher.
- final String demoLauncher = getContext().getString(
- R.string.config_demoModeLauncherComponent);
- if (!TextUtils.isEmpty(demoLauncher)) {
- final ComponentName componentToEnable =
- ComponentName.unflattenFromString(demoLauncher);
- final String packageName = componentToEnable.getPackageName();
- try {
- final IPackageManager iPm = AppGlobals.getPackageManager();
- iPm.setComponentEnabledSetting(componentToEnable,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id);
- iPm.setApplicationEnabledSetting(packageName,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null);
- } catch (RemoteException re) {
- // Internal, shouldn't happen
- }
- }
- } else {
- // Set the carrier demo mode setting for the demo user.
- final String carrierDemoModeSetting = getContext().getString(
- R.string.config_carrierDemoModeSetting);
- Settings.Secure.putIntForUser(getContext().getContentResolver(),
- carrierDemoModeSetting, 1, userInfo.id);
-
- // Enable packages for carrier demo mode.
- final String packageList = getContext().getString(
- R.string.config_carrierDemoModePackages);
- final String[] packageNames = packageList == null ? new String[0]
- : TextUtils.split(packageList, ",");
- final IPackageManager iPm = AppGlobals.getPackageManager();
- for (String packageName : packageNames) {
- try {
- iPm.setApplicationEnabledSetting(packageName,
- PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, userInfo.id, null);
- } catch (RemoteException re) {
- Slog.e(TAG, "Error enabling application: " + packageName, re);
- }
- }
- }
- }
-
- private void grantRuntimePermissionToCamera(UserHandle user) {
- final Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- final PackageManager pm = mInjector.getPackageManager();
- final ResolveInfo handler = pm.resolveActivityAsUser(cameraIntent,
- PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
- if (handler == null || handler.activityInfo == null) {
- return;
- }
- try {
- pm.grantRuntimePermission(handler.activityInfo.packageName,
- Manifest.permission.ACCESS_FINE_LOCATION, user);
- } catch (Exception e) {
- // Ignore
- }
- }
-
- private void clearPrimaryCallLog() {
- final ContentResolver resolver = mInjector.getContentResolver();
-
- // Deleting primary user call log so that it doesn't get copied to the new demo user
- final Uri uri = CallLog.Calls.CONTENT_URI;
- try {
- resolver.delete(uri, null, null);
- } catch (Exception e) {
- Slog.w(TAG, "Deleting call log failed: " + e);
- }
- }
-
- void logSessionDuration() {
- final int sessionDuration;
- synchronized (mActivityLock) {
- sessionDuration = (int) ((mLastUserActivityTime - mFirstUserActivityTime) / 1000);
- }
- mInjector.logSessionDuration(sessionDuration);
- }
-
- private boolean isDeviceProvisioned() {
- return Settings.Global.getInt(
- mInjector.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
- }
-
- /**
- * Deletes contents of {@link Environment#getDataPreloadsDirectory()},
- * but leave {@link Environment#getDataPreloadsFileCacheDirectory()}
- * @return true if contents was sucessfully deleted
- */
- private boolean deletePreloadsFolderContents() {
- final File dir = mInjector.getDataPreloadsDirectory();
- final File[] files = FileUtils.listFilesOrEmpty(dir);
- final File fileCacheDirectory = mInjector.getDataPreloadsFileCacheDirectory();
- Slog.i(TAG, "Deleting contents of " + dir);
- boolean success = true;
- for (File file : files) {
- if (file.isFile()) {
- if (!file.delete()) {
- success = false;
- Slog.w(TAG, "Cannot delete file " + file);
- }
- } else {
- // Do not remove file_cache dir
- if (!file.equals(fileCacheDirectory)) {
- if (!FileUtils.deleteContentsAndDir(file)) {
- success = false;
- Slog.w(TAG, "Cannot delete dir and its content " + file);
- }
- } else {
- Slog.i(TAG, "Skipping directory with file cache " + file);
- }
- }
- }
- return success;
- }
-
- private void registerBroadcastReceiver() {
- if (mBroadcastReceiver != null) {
- return;
- }
-
- final IntentFilter filter = new IntentFilter();
- if (!mIsCarrierDemoMode) {
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- }
- filter.addAction(ACTION_RESET_DEMO);
- mBroadcastReceiver = new IntentReceiver();
- getContext().registerReceiver(mBroadcastReceiver, filter);
- }
-
- private void unregisterBroadcastReceiver() {
- if (mBroadcastReceiver != null) {
- getContext().unregisterReceiver(mBroadcastReceiver);
- mBroadcastReceiver = null;
- }
- }
-
- private String[] getCameraIdsWithFlash() {
- ArrayList<String> cameraIdsList = new ArrayList<String>();
- final CameraManager cm = mInjector.getCameraManager();
- if (cm != null) {
- try {
- for (String cameraId : cm.getCameraIdList()) {
- CameraCharacteristics c = cm.getCameraCharacteristics(cameraId);
- if (Boolean.TRUE.equals(c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE))) {
- cameraIdsList.add(cameraId);
- }
- }
- } catch (CameraAccessException e) {
- Slog.e(TAG, "Unable to access camera while getting camera id list", e);
- }
- }
- return cameraIdsList.toArray(new String[cameraIdsList.size()]);
- }
-
- private void muteVolumeStreams() {
- for (int stream : VOLUME_STREAMS_TO_MUTE) {
- mInjector.getAudioManager().setStreamVolume(stream,
- mInjector.getAudioManager().getStreamMinVolume(stream), 0);
- }
- }
-
- private void startDemoMode() {
- mDeviceInDemoMode = true;
-
- mPreloadAppsInstaller = mInjector.getPreloadAppsInstaller();
- mInjector.initializeWakeLock();
- if (mCameraIdsWithFlash == null) {
- mCameraIdsWithFlash = getCameraIdsWithFlash();
- }
- registerBroadcastReceiver();
-
- final String carrierDemoModeSetting =
- getContext().getString(R.string.config_carrierDemoModeSetting);
- mIsCarrierDemoMode = !TextUtils.isEmpty(carrierDemoModeSetting)
- && (Settings.Secure.getInt(getContext().getContentResolver(),
- carrierDemoModeSetting, 0) == 1);
-
- mInjector.systemPropertiesSet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED, "1");
- mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
-
- mSafeBootRestrictionInitialState = mInjector.getUserManager().hasUserRestriction(
- UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM);
- mPackageVerifierEnableInitialState = Settings.Global.getInt(mInjector.getContentResolver(),
- Settings.Global.PACKAGE_VERIFIER_ENABLE, 1);
- }
-
- private void stopDemoMode() {
- mPreloadAppsInstaller = null;
- mCameraIdsWithFlash = null;
- mInjector.destroyWakeLock();
- unregisterBroadcastReceiver();
-
- if (mDeviceInDemoMode) {
- mInjector.getUserManager().setUserRestriction(UserManager.DISALLOW_SAFE_BOOT,
- mSafeBootRestrictionInitialState, UserHandle.SYSTEM);
- Settings.Global.putInt(mInjector.getContentResolver(),
- Settings.Global.PACKAGE_VERIFIER_ENABLE,
- mPackageVerifierEnableInitialState);
- }
-
- mDeviceInDemoMode = false;
- mIsCarrierDemoMode = false;
- }
-
- @Override
- public void onStart() {
- if (DEBUG) {
- Slog.d(TAG, "Service starting up");
- }
- mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND,
- false);
- mHandlerThread.start();
- mHandler = new MainHandler(mHandlerThread.getLooper());
- mInjector.publishLocalService(this, mLocalService);
- }
-
- @Override
- public void onBootPhase(int bootPhase) {
- switch (bootPhase) {
- case PHASE_THIRD_PARTY_APPS_CAN_START:
- final SettingsObserver settingsObserver = new SettingsObserver(mHandler);
- settingsObserver.register();
- settingsObserver.refreshTimeoutConstants();
- break;
- case PHASE_BOOT_COMPLETED:
- if (UserManager.isDeviceInDemoMode(getContext())) {
- startDemoMode();
- }
- break;
- }
- }
-
- @Override
- public void onSwitchUser(int userId) {
- if (!mDeviceInDemoMode) {
- return;
- }
- if (DEBUG) {
- Slog.d(TAG, "onSwitchUser: " + userId);
- }
- final UserInfo ui = mInjector.getUserManager().getUserInfo(userId);
- if (!ui.isDemo()) {
- Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode");
- return;
- }
- if (!mIsCarrierDemoMode && !mInjector.isWakeLockHeld()) {
- mInjector.acquireWakeLock();
- }
- mCurrentUserId = userId;
- mInjector.getActivityManagerInternal().updatePersistentConfigurationForUser(
- mInjector.getSystemUsersConfiguration(), userId);
-
- mInjector.turnOffAllFlashLights(mCameraIdsWithFlash);
- muteVolumeStreams();
- if (!mInjector.getWifiManager().isWifiEnabled()) {
- mInjector.getWifiManager().setWifiEnabled(true);
- }
-
- // Disable lock screen for demo users.
- mInjector.getLockPatternUtils().setLockScreenDisabled(true, userId);
-
- if (!mIsCarrierDemoMode) {
- // Show reset notification (except in carrier demo mode).
- mInjector.getNotificationManager().notifyAsUser(TAG, SystemMessage.NOTE_RETAIL_RESET,
- mInjector.createResetNotification(), UserHandle.of(userId));
-
- synchronized (mActivityLock) {
- mUserUntouched = true;
- }
- mInjector.logSessionCount(1);
- mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mPreloadAppsInstaller.installApps(userId);
- }
- });
- }
- }
-
- private RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() {
- private static final long USER_ACTIVITY_DEBOUNCE_TIME = 2000;
-
- @Override
- public void onUserActivity() {
- if (!mDeviceInDemoMode || mIsCarrierDemoMode) {
- return;
- }
- long timeOfActivity = SystemClock.uptimeMillis();
- synchronized (mActivityLock) {
- if (timeOfActivity < mLastUserActivityTime + USER_ACTIVITY_DEBOUNCE_TIME) {
- return;
- }
- mLastUserActivityTime = timeOfActivity;
- if (mUserUntouched && isDemoLauncherDisabled()) {
- Slog.d(TAG, "retail_demo first touch");
- mUserUntouched = false;
- mFirstUserActivityTime = timeOfActivity;
- }
- }
- mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
- mHandler.sendEmptyMessageDelayed(MSG_INACTIVITY_TIME_OUT, mUserInactivityTimeout);
- }
- };
-
- static class Injector {
- private Context mContext;
- private UserManager mUm;
- private PackageManager mPm;
- private NotificationManager mNm;
- private ActivityManagerService mAms;
- private ActivityManagerInternal mAmi;
- private AudioManager mAudioManager;
- private PowerManager mPowerManager;
- private CameraManager mCameraManager;
- private PowerManager.WakeLock mWakeLock;
- private WifiManager mWifiManager;
- private Configuration mSystemUserConfiguration;
- private PendingIntent mResetDemoPendingIntent;
- private PreloadAppsInstaller mPreloadAppsInstaller;
-
- Injector(Context context) {
- mContext = context;
- }
-
- Context getContext() {
- return mContext;
- }
-
- WifiManager getWifiManager() {
- if (mWifiManager == null) {
- mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- }
- return mWifiManager;
- }
-
- UserManager getUserManager() {
- if (mUm == null) {
- mUm = getContext().getSystemService(UserManager.class);
- }
- return mUm;
- }
-
- void switchUser(int userId) {
- if (mAms == null) {
- mAms = (ActivityManagerService) ActivityManager.getService();
- }
- mAms.switchUser(userId);
- }
-
- AudioManager getAudioManager() {
- if (mAudioManager == null) {
- mAudioManager = getContext().getSystemService(AudioManager.class);
- }
- return mAudioManager;
- }
-
- private PowerManager getPowerManager() {
- if (mPowerManager == null) {
- mPowerManager = (PowerManager) getContext().getSystemService(
- Context.POWER_SERVICE);
- }
- return mPowerManager;
- }
-
- NotificationManager getNotificationManager() {
- if (mNm == null) {
- mNm = NotificationManager.from(getContext());
- }
- return mNm;
- }
-
- ActivityManagerInternal getActivityManagerInternal() {
- if (mAmi == null) {
- mAmi = LocalServices.getService(ActivityManagerInternal.class);
- }
- return mAmi;
- }
-
- CameraManager getCameraManager() {
- if (mCameraManager == null) {
- mCameraManager = (CameraManager) getContext().getSystemService(
- Context.CAMERA_SERVICE);
- }
- return mCameraManager;
- }
-
- PackageManager getPackageManager() {
- if (mPm == null) {
- mPm = getContext().getPackageManager();
- }
- return mPm;
- }
-
- IPackageManager getIPackageManager() {
- return AppGlobals.getPackageManager();
- }
-
- ContentResolver getContentResolver() {
- return getContext().getContentResolver();
- }
-
- PreloadAppsInstaller getPreloadAppsInstaller() {
- if (mPreloadAppsInstaller == null) {
- mPreloadAppsInstaller = new PreloadAppsInstaller(getContext());
- }
- return mPreloadAppsInstaller;
- }
-
- void systemPropertiesSet(String key, String value) {
- SystemProperties.set(key, value);
- }
-
- void turnOffAllFlashLights(String[] cameraIdsWithFlash) {
- for (String cameraId : cameraIdsWithFlash) {
- try {
- getCameraManager().setTorchMode(cameraId, false);
- } catch (CameraAccessException e) {
- Slog.e(TAG, "Unable to access camera " + cameraId
- + " while turning off flash", e);
- }
- }
- }
-
- void initializeWakeLock() {
- if (mWakeLock == null) {
- mWakeLock = getPowerManager().newWakeLock(
- PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
- }
- }
-
- void destroyWakeLock() {
- mWakeLock = null;
- }
-
- boolean isWakeLockHeld() {
- return mWakeLock != null && mWakeLock.isHeld();
- }
-
- void acquireWakeLock() {
- mWakeLock.acquire();
- }
-
- void releaseWakeLock() {
- mWakeLock.release();
- }
-
- void logSessionDuration(int duration) {
- MetricsLogger.histogram(getContext(), DEMO_SESSION_DURATION, duration);
- }
-
- void logSessionCount(int count) {
- MetricsLogger.count(getContext(), DEMO_SESSION_COUNT, count);
- }
-
- Configuration getSystemUsersConfiguration() {
- if (mSystemUserConfiguration == null) {
- Settings.System.getConfiguration(getContentResolver(),
- mSystemUserConfiguration = new Configuration());
- }
- return mSystemUserConfiguration;
- }
-
- LockPatternUtils getLockPatternUtils() {
- return new LockPatternUtils(getContext());
- }
-
- Notification createResetNotification() {
- return new Notification.Builder(getContext(), SystemNotificationChannels.RETAIL_MODE)
- .setContentTitle(getContext().getString(R.string.reset_retail_demo_mode_title))
- .setContentText(getContext().getString(R.string.reset_retail_demo_mode_text))
- .setOngoing(true)
- .setSmallIcon(R.drawable.platlogo)
- .setShowWhen(false)
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setContentIntent(getResetDemoPendingIntent())
- .setColor(getContext().getColor(R.color.system_notification_accent_color))
- .build();
- }
-
- private PendingIntent getResetDemoPendingIntent() {
- if (mResetDemoPendingIntent == null) {
- Intent intent = new Intent(ACTION_RESET_DEMO);
- mResetDemoPendingIntent = PendingIntent.getBroadcast(getContext(), 0, intent, 0);
- }
- return mResetDemoPendingIntent;
- }
-
- File getDataPreloadsDirectory() {
- return Environment.getDataPreloadsDirectory();
- }
-
- File getDataPreloadsFileCacheDirectory() {
- return Environment.getDataPreloadsFileCacheDirectory();
- }
-
- void publishLocalService(RetailDemoModeService service,
- RetailDemoModeServiceInternal localService) {
- service.publishLocalService(RetailDemoModeServiceInternal.class, localService);
- }
- }
-}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java b/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
deleted file mode 100644
index 013eab8679a8..000000000000
--- a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2016 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.retaildemo;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.os.CountDownTimer;
-import android.view.WindowManager;
-import android.widget.TextView;
-
-import com.android.internal.R;
-
-public class UserInactivityCountdownDialog extends AlertDialog {
-
- private OnCountDownExpiredListener mOnCountDownExpiredListener;
- private CountDownTimer mCountDownTimer;
- private long mCountDownDuration;
- private long mRefreshInterval;
-
- UserInactivityCountdownDialog(Context context, long duration, long refreshInterval) {
- super(context);
- mCountDownDuration = duration;
- mRefreshInterval = refreshInterval;
-
- getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
- WindowManager.LayoutParams attrs = getWindow().getAttributes();
- attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- getWindow().setAttributes(attrs);
-
- setTitle(R.string.demo_user_inactivity_timeout_title);
- setMessage(getContext().getString(R.string.demo_user_inactivity_timeout_countdown,
- duration));
- }
-
- public void setOnCountDownExpiredListener(
- OnCountDownExpiredListener onCountDownExpiredListener) {
- mOnCountDownExpiredListener = onCountDownExpiredListener;
- }
-
- public void setPositiveButtonClickListener(OnClickListener onClickListener) {
- setButton(Dialog.BUTTON_POSITIVE,
- getContext().getString(R.string.demo_user_inactivity_timeout_right_button),
- onClickListener);
- }
-
- public void setNegativeButtonClickListener(OnClickListener onClickListener) {
- setButton(Dialog.BUTTON_NEGATIVE,
- getContext().getString(R.string.demo_user_inactivity_timeout_left_button),
- onClickListener);
- }
-
- @Override
- public void show() {
- super.show();
- final TextView messageView = findViewById(R.id.message);
- messageView.post(new Runnable() {
- @Override
- public void run() {
- mCountDownTimer = new CountDownTimer(mCountDownDuration, mRefreshInterval) {
-
- @Override
- public void onTick(long millisUntilFinished) {
- String msg = getContext().getString(
- R.string.demo_user_inactivity_timeout_countdown,
- millisUntilFinished / 1000);
- messageView.setText(msg);
- }
-
- @Override
- public void onFinish() {
- dismiss();
- if (mOnCountDownExpiredListener != null)
- mOnCountDownExpiredListener.onCountDownExpired();
- }
- }.start();
- }
- });
- }
-
- @Override
- public void onStop() {
- if (mCountDownTimer != null) {
- mCountDownTimer.cancel();
- }
- }
-
- interface OnCountDownExpiredListener {
- void onCountDownExpired();
- }
-}
diff --git a/services/tests/notification/Android.mk b/services/tests/notification/Android.mk
index 0ffe6e4db6b8..597a5849a1a0 100644
--- a/services/tests/notification/Android.mk
+++ b/services/tests/notification/Android.mk
@@ -18,7 +18,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
services.core \
services.devicepolicy \
services.net \
- services.retaildemo \
services.usage \
guava \
android-support-test \
diff --git a/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java
index ffbd8d493899..bd65f571d20b 100644
--- a/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/notification/src/com/android/server/notification/ManagedServicesTest.java
@@ -170,7 +170,7 @@ public class ManagedServicesTest extends NotificationTestCase {
null);
writeExpectedValuesToSettings(approvalLevel);
- assertTrue(service.readXml(parser));
+ service.migrateToXml();
verifyExpectedApprovedEntries(service);
}
@@ -182,7 +182,7 @@ public class ManagedServicesTest extends NotificationTestCase {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
mIpm, approvalLevel);
- assertFalse(loadXml(service));
+ loadXml(service);
verifyExpectedApprovedEntries(service);
}
@@ -239,7 +239,7 @@ public class ManagedServicesTest extends NotificationTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- assertFalse(service.readXml(parser));
+ service.readXml(parser);
verifyExpectedApprovedEntries(service);
assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0));
@@ -341,11 +341,8 @@ public class ManagedServicesTest extends NotificationTestCase {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
mIpm, approvalLevel);
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
- null);
writeExpectedValuesToSettings(approvalLevel);
- service.readXml(parser);
+ service.migrateToXml();
mExpectedPrimaryPackages.put(0, "another.package");
mExpectedPrimaryComponentNames.put(0, "another.package/B1");
@@ -360,11 +357,8 @@ public class ManagedServicesTest extends NotificationTestCase {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
mIpm, approvalLevel);
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
- null);
writeExpectedValuesToSettings(approvalLevel);
- service.readXml(parser);
+ service.migrateToXml();
mExpectedSecondaryComponentNames.put(10, "component/2");
mExpectedSecondaryPackages.put(10, "component");
@@ -516,9 +510,9 @@ public class ManagedServicesTest extends NotificationTestCase {
assertEquals(0, service.getAllowedComponents(10).size());
}
- private boolean loadXml(ManagedServices service) throws Exception {
+ private void loadXml(ManagedServices service) throws Exception {
final StringBuffer xml = new StringBuffer();
- xml.append("<" + service.getConfig().managedServiceTypeTag + ">\n");
+ xml.append("<" + service.getConfig().xmlTag + ">\n");
for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) {
xml.append(getXmlEntry(
mExpectedPrimary.get(service.mApprovalLevel).get(userId), userId, true));
@@ -527,13 +521,13 @@ public class ManagedServicesTest extends NotificationTestCase {
xml.append(getXmlEntry(
mExpectedSecondary.get(service.mApprovalLevel).get(userId), userId, false));
}
- xml.append("</" + service.getConfig().managedServiceTypeTag + ">");
+ xml.append("</" + service.getConfig().xmlTag + ">");
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.toString().getBytes())), null);
parser.nextTag();
- return service.readXml(parser);
+ service.readXml(parser);
}
private void addExpectedServices(final ManagedServices service, final List<String> packages,
@@ -674,7 +668,7 @@ public class ManagedServicesTest extends NotificationTestCase {
@Override
protected Config getConfig() {
final Config c = new Config();
- c.managedServiceTypeTag= "test";
+ c.xmlTag = "test";
c.secureSettingName = SETTING;
c.secondarySettingName = SECONDARY_SETTING;
c.bindPermission = "permission";
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java b/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java
index d2f608e63e53..85852f90c281 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java
@@ -19,6 +19,9 @@ package com.android.server.notification;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static com.android.server.notification.NotificationIntrusivenessExtractor.HANG_TIME_MS;
+
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
@@ -59,9 +62,29 @@ public class NotificationIntrusivenessExtractorTest extends NotificationTestCase
Notification n = builder.build();
StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
- 0, n, UserHandle.ALL, null, System.currentTimeMillis());
+ 0, n, UserHandle.ALL, null,
+ System.currentTimeMillis());
NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
assertNotNull(new NotificationIntrusivenessExtractor().process(r));
}
+
+ @Test
+ public void testOldNotificationsNotIntrusive() {
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+ final Notification.Builder builder = new Notification.Builder(getContext())
+ .setContentTitle("foo")
+ .setFullScreenIntent(PendingIntent.getActivity(
+ getContext(), 0, new Intent(""), 0), true)
+ .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+ Notification n = builder.build();
+ StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
+ 0, n, UserHandle.ALL, null,
+ System.currentTimeMillis() - HANG_TIME_MS);
+
+ NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+ assertNull(new NotificationIntrusivenessExtractor().process(r));
+ assertFalse(r.isRecentlyIntrusive());
+ }
}
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index d462c2ff1a6a..09af1e2fd7d4 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -20,9 +20,6 @@ import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
-import static com.android.server.notification.NotificationManagerService
- .MESSAGE_SEND_RANKING_UPDATE;
-
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -34,12 +31,10 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -60,35 +55,34 @@ import android.content.pm.ParceledListSlice;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Binder;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings.Secure;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
+import android.service.notification.ZenModeConfig;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArrayMap;
import android.util.AtomicFile;
-import android.util.Log;
-import android.util.Slog;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
+import com.android.server.notification.NotificationManagerService.NotificationAssistants;
+import com.android.server.notification.NotificationManagerService.NotificationListeners;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -115,7 +109,6 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
private TestableLooper mTestableLooper;
@Mock
private RankingHelper mRankingHelper;
- @Mock
AtomicFile mPolicyFile;
File mFile;
@Mock
@@ -129,8 +122,8 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
@Mock
- private NotificationManagerService.NotificationListeners mNotificationListeners;
- @Mock private NotificationManagerService.NotificationAssistants mNotificationAssistants;
+ private NotificationListeners mListeners;
+ @Mock private NotificationAssistants mAssistants;
@Mock private ConditionProviders mConditionProviders;
private ManagedServices.ManagedServiceInfo mListener;
@Mock private ICompanionDeviceManager mCompanionMgr;
@@ -182,18 +175,34 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+ // write to a test file; the system file isn't readable from tests
mFile = new File(mContext.getCacheDir(), "test.xml");
mFile.createNewFile();
- when(mPolicyFile.openRead()).thenReturn(new FileInputStream(mFile));
- when(mPolicyFile.startWrite()).thenReturn(new FileOutputStream(mFile));
-
- mListener = mNotificationListeners.new ManagedServiceInfo(
+ final String preupgradeXml = "<notification-policy></notification-policy>";
+ mPolicyFile = new AtomicFile(mFile);
+ FileOutputStream fos = mPolicyFile.startWrite();
+ fos.write(preupgradeXml.getBytes());
+ mPolicyFile.finishWrite(fos);
+ FileInputStream fStream = new FileInputStream(mFile);
+
+ // Setup managed services
+ mListener = mListeners.new ManagedServiceInfo(
null, new ComponentName(PKG, "test_class"), mUid, true, null, 0);
- when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+ when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+ ManagedServices.Config listenerConfig = new ManagedServices.Config();
+ listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS;
+ when(mListeners.getConfig()).thenReturn(listenerConfig);
+ ManagedServices.Config assistantConfig = new ManagedServices.Config();
+ assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS;
+ when(mAssistants.getConfig()).thenReturn(assistantConfig);
+ ManagedServices.Config dndConfig = new ManagedServices.Config();
+ dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
+ when(mConditionProviders.getConfig()).thenReturn(dndConfig);
+
try {
mNotificationManagerService.init(mTestableLooper.getLooper(),
mPackageManager, mPackageManagerClient, mockLightsManager,
- mNotificationListeners, mNotificationAssistants, mConditionProviders,
+ mListeners, mAssistants, mConditionProviders,
mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
mGroupHelper);
} catch (SecurityException e) {
@@ -827,13 +836,13 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
eq(channel2.getId()), anyBoolean()))
.thenReturn(channel2);
- reset(mNotificationListeners);
+ reset(mListeners);
mBinderService.createNotificationChannels(PKG,
new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
- verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
- verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(channel2),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
}
@@ -847,13 +856,13 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
- reset(mNotificationListeners);
+ reset(mListeners);
mBinderService.createNotificationChannelGroups(PKG,
new ParceledListSlice(Arrays.asList(group1, group2)));
- verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
+ verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
eq(Process.myUserHandle()), eq(group1),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
- verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
+ verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
eq(Process.myUserHandle()), eq(group2),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
}
@@ -869,9 +878,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
eq(mTestNotificationChannel.getId()), anyBoolean()))
.thenReturn(mTestNotificationChannel);
- reset(mNotificationListeners);
+ reset(mListeners);
mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
- verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -885,9 +894,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
eq(mTestNotificationChannel.getId()), anyBoolean()))
.thenReturn(mTestNotificationChannel);
- reset(mNotificationListeners);
+ reset(mListeners);
mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
- verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
}
@@ -901,9 +910,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mNotificationManagerService.setRankingHelper(mRankingHelper);
when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
.thenReturn(ncg);
- reset(mNotificationListeners);
+ reset(mListeners);
mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
- verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
+ verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
eq(Process.myUserHandle()), eq(ncg),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
}
@@ -920,7 +929,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mRankingHelper, times(1)).updateNotificationChannel(anyString(), anyInt(), any());
- verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -941,7 +950,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any());
- verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -955,7 +964,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mListener = mock(ManagedServices.ManagedServiceInfo.class);
mListener.component = new ComponentName(PKG, PKG);
when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
- when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+ when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
try {
mBinderService.updateNotificationChannelFromPrivilegedListener(
@@ -967,7 +976,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any());
- verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -1012,7 +1021,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
mListener = mock(ManagedServices.ManagedServiceInfo.class);
when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
- when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+ when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
try {
mBinderService.getNotificationChannelsFromPrivilegedListener(
@@ -1063,7 +1072,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
mListener = mock(ManagedServices.ManagedServiceInfo.class);
when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
- when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+ when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
try {
mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
@@ -1232,11 +1241,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
}
}
- verify(mNotificationListeners, times(1)).setPackageOrComponentEnabled(
+ verify(mListeners, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
- verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+ verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1251,11 +1260,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
}
}
- verify(mNotificationAssistants, times(1)).setPackageOrComponentEnabled(
+ verify(mAssistants, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
- verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+ verify(mListeners, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1272,9 +1281,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
c.getPackageName(), 0, true, true);
- verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+ verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
- verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+ verify(mListeners, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1284,11 +1293,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
ComponentName c = ComponentName.unflattenFromString("package/Component");
mBinderService.setNotificationListenerAccessGranted(c, true);
- verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+ verify(mListeners, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
- verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+ verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1299,11 +1308,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mBinderService.setNotificationAssistantAccessGranted(c, true);
- verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+ verify(mListeners, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
- verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+ verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1313,11 +1322,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
ComponentName c = ComponentName.unflattenFromString("package/Component");
mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
- verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
+ verify(mListeners, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
- verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
+ verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1425,16 +1434,41 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
}
@Test
- public void testModifyAutogroup_requestsSort() throws Exception {
+ public void testAddAutogroup_requestsSort() throws Exception {
RankingHandler rh = mock(RankingHandler.class);
mNotificationManagerService.setRankingHandler(rh);
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mNotificationManagerService.addNotification(r);
mNotificationManagerService.addAutogroupKeyLocked(r.getKey());
+
+ verify(rh, times(1)).requestSort();
+ }
+
+ @Test
+ public void testRemoveAutogroup_requestsSort() throws Exception {
+ RankingHandler rh = mock(RankingHandler.class);
+ mNotificationManagerService.setRankingHandler(rh);
+
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ r.setOverrideGroupKey("TEST");
+ mNotificationManagerService.addNotification(r);
mNotificationManagerService.removeAutogroupKeyLocked(r.getKey());
- verify(rh, times(2)).requestSort();
+ verify(rh, times(1)).requestSort();
+ }
+
+ @Test
+ public void testReaddAutogroup_noSort() throws Exception {
+ RankingHandler rh = mock(RankingHandler.class);
+ mNotificationManagerService.setRankingHandler(rh);
+
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ r.setOverrideGroupKey("TEST");
+ mNotificationManagerService.addNotification(r);
+ mNotificationManagerService.addAutogroupKeyLocked(r.getKey());
+
+ verify(rh, never()).requestSort();
}
@Test
@@ -1470,4 +1504,50 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mNotificationManagerService.handleRankingSort();
verify(handler, never()).scheduleSendRankingUpdate();
}
+
+ @Test
+ public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
+ final String preupgradeXml = "<notification-policy version=\"1\">"
+ + "<zen></zen>"
+ + "<ranking></ranking>"
+ + "<enabled_listeners>"
+ + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
+ + "</enabled_listeners>"
+ + "<enabled_assistants>"
+ + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
+ + "</enabled_assistants>"
+ + "<dnd_apps>"
+ + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
+ + "</dnd_apps>"
+ + "</notification-policy>";
+ mNotificationManagerService.readPolicyXml(
+ new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
+ verify(mListeners, times(1)).readXml(any());
+ verify(mConditionProviders, times(1)).readXml(any());
+ verify(mAssistants, times(1)).readXml(any());
+
+ // numbers are inflated for setup
+ verify(mListeners, times(1)).migrateToXml();
+ verify(mConditionProviders, times(1)).migrateToXml();
+ verify(mAssistants, times(1)).migrateToXml();
+ }
+
+ @Test
+ public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
+ final String preupgradeXml = "<notification-policy version=\"1\">"
+ + "<zen></zen>"
+ + "<ranking></ranking>"
+ + "</notification-policy>";
+ mNotificationManagerService.readPolicyXml(
+ new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
+ verify(mListeners, never()).readXml(any());
+ verify(mConditionProviders, never()).readXml(any());
+ verify(mAssistants, never()).readXml(any());
+
+ // numbers are inflated for setup
+ verify(mListeners, times(2)).migrateToXml();
+ verify(mConditionProviders, times(2)).migrateToXml();
+ verify(mAssistants, times(2)).migrateToXml();
+ }
+
}
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 0ff11c1f58f8..507b4830e455 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -19,7 +19,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
services.core \
services.devicepolicy \
services.net \
- services.retaildemo \
services.usage \
guava \
android-support-test \
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 16bc011f97b5..04b5bdebdca1 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.any;
@@ -78,7 +79,7 @@ public class ActivityTestsBase {
int stackId, int displayId, boolean onTop) {
if (service.mStackSupervisor instanceof TestActivityStackSupervisor) {
return ((TestActivityStackSupervisor) service.mStackSupervisor)
- .createTestStack(service, stackId, onTop);
+ .createTestStack(stackId, onTop);
}
return null;
@@ -96,8 +97,7 @@ public class ActivityTestsBase {
0 /* launchedFromPid */, 0, null, intent, null,
aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
- service.mStackSupervisor, null /* container */, null /* options */,
- null /* sourceRecord */);
+ service.mStackSupervisor, null /* options */, null /* sourceRecord */);
activity.mWindowContainerController = mock(AppWindowContainerController.class);
if (task != null) {
@@ -187,12 +187,24 @@ public class ActivityTestsBase {
boolean preserveWindows) {
}
- public <T extends ActivityStack> T createTestStack(ActivityManagerService service,
- int stackId, boolean onTop) {
- final TestActivityContainer container =
- new TestActivityContainer(service, stackId, mDisplay, onTop);
- mActivityContainers.put(stackId, container);
- return (T) container.getStack();
+ <T extends ActivityStack> T createTestStack(int stackId, boolean onTop) {
+ return (T) createStack(stackId, mDisplay, onTop);
+ }
+
+ @Override
+ ActivityStack createStack(int stackId, ActivityDisplay display, boolean onTop) {
+ final RecentTasks recents =
+ new RecentTasks(mService, mService.mStackSupervisor);
+ if (stackId == PINNED_STACK_ID) {
+ return new PinnedActivityStack(display, stackId, this, recents, onTop) {
+ @Override
+ Rect getDefaultPictureInPictureBounds(float aspectRatio) {
+ return new Rect(50, 50, 100, 100);
+ }
+ };
+ } else {
+ return new TestActivityStack(display, stackId, this, recents, onTop);
+ }
}
@Override
@@ -204,49 +216,7 @@ public class ActivityTestsBase {
return stack;
}
- return createTestStack(mService, stackId, createOnTop);
- }
-
- private class TestActivityContainer extends ActivityContainer {
- private final ActivityManagerService mService;
-
- private boolean mOnTop;
- private int mStackId;
- private ActivityStack mStack;
-
- TestActivityContainer(ActivityManagerService service, int stackId,
- ActivityDisplay activityDisplay, boolean onTop) {
- super(stackId, activityDisplay, onTop);
- mService = service;
- }
-
- @Override
- protected void createStack(int stackId, boolean onTop) {
- // normally stack creation is done here. However we need to do it on demand since
- // we cannot set {@link mService} by the time the super constructor calling this
- // method is invoked.
- mOnTop = onTop;
- mStackId = stackId;
- }
-
- public ActivityStack getStack() {
- if (mStack == null) {
- final RecentTasks recents =
- new RecentTasks(mService, mService.mStackSupervisor);
- if (mStackId == ActivityManager.StackId.PINNED_STACK_ID) {
- mStack = new PinnedActivityStack(this, recents, mOnTop) {
- @Override
- Rect getDefaultPictureInPictureBounds(float aspectRatio) {
- return new Rect(50, 50, 100, 100);
- }
- };
- } else {
- mStack = new TestActivityStack(this, recents, mOnTop);
- }
- }
-
- return mStack;
- }
+ return createTestStack(stackId, createOnTop);
}
}
@@ -277,9 +247,9 @@ public class ActivityTestsBase {
extends ActivityStack<T> implements ActivityStackReporter {
private int mOnActivityRemovedFromStackCount = 0;
private T mContainerController;
- TestActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer,
- RecentTasks recentTasks, boolean onTop) {
- super(activityContainer, recentTasks, onTop);
+ TestActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId,
+ ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) {
+ super(display, stackId, supervisor, recentTasks, onTop);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
deleted file mode 100644
index cf27a503efd4..000000000000
--- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2016 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.retaildemo;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.IPackageInstallObserver2;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.FileUtils;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.mock.MockContentResolver;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.util.ArrayList;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class PreloadAppsInstallerTest {
- private static final int TEST_DEMO_USER = 111;
-
- private Context mContext;
- private @Mock IPackageManager mIpm;
- private MockContentResolver mContentResolver;
- private File mPreloadsAppsDirectory;
- private String[] mPreloadedApps =
- new String[] {"test1.apk.preload", "test2.apk.preload", "test3.apk.preload"};
- private ArrayList<String> mPreloadedAppPaths = new ArrayList<>();
-
- private PreloadAppsInstaller mInstaller;
-
- @BeforeClass
- @AfterClass
- public static void clearSettingsProvider() {
- FakeSettingsProvider.clearSettingsProvider();
- }
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
- mContentResolver = new MockContentResolver(mContext);
- mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
- when(mContext.getContentResolver()).thenReturn(mContentResolver);
- initializePreloadedApps();
- Settings.Secure.putStringForUser(mContentResolver,
- Settings.Secure.DEMO_USER_SETUP_COMPLETE, "0", TEST_DEMO_USER);
-
- mInstaller = new PreloadAppsInstaller(mContext, mIpm, mPreloadsAppsDirectory);
- }
-
- private void initializePreloadedApps() throws Exception {
- mPreloadsAppsDirectory = new File(InstrumentationRegistry.getContext().getFilesDir(),
- "test_preload_apps_dir");
- mPreloadsAppsDirectory.mkdir();
- for (String name : mPreloadedApps) {
- final File f = new File(mPreloadsAppsDirectory, name);
- f.createNewFile();
- mPreloadedAppPaths.add(f.getPath());
- }
- }
-
- @After
- public void tearDown() {
- if (mPreloadsAppsDirectory != null) {
- FileUtils.deleteContentsAndDir(mPreloadsAppsDirectory);
- }
- }
-
- @Test
- public void testInstallApps() throws Exception {
- mInstaller.installApps(TEST_DEMO_USER);
- for (String path : mPreloadedAppPaths) {
- ArgumentCaptor<IPackageInstallObserver2> observer =
- ArgumentCaptor.forClass(IPackageInstallObserver2.class);
- verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(),
- anyString(), eq(TEST_DEMO_USER));
- observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED,
- null, null);
- // Verify that we try to install the package in system user.
- verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
- }
- assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
- "1",
- Settings.Secure.getStringForUser(mContentResolver,
- Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
- }
-
- @Test
- public void testInstallApps_noPreloads() throws Exception {
- // Delete all files in preloaded apps directory - no preloaded apps
- FileUtils.deleteContents(mPreloadsAppsDirectory);
- mInstaller.installApps(TEST_DEMO_USER);
- assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
- "1",
- Settings.Secure.getStringForUser(mContentResolver,
- Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
- }
-
- @Test
- public void testInstallApps_installationFails() throws Exception {
- mInstaller.installApps(TEST_DEMO_USER);
- for (int i = 0; i < mPreloadedAppPaths.size(); ++i) {
- ArgumentCaptor<IPackageInstallObserver2> observer =
- ArgumentCaptor.forClass(IPackageInstallObserver2.class);
- final String path = mPreloadedAppPaths.get(i);
- verify(mIpm).installPackageAsUser(eq(path), observer.capture(), anyInt(),
- anyString(), eq(TEST_DEMO_USER));
- if (i == 0) {
- observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_FAILED_DEXOPT,
- null, null);
- continue;
- }
- observer.getValue().onPackageInstalled(path, PackageManager.INSTALL_SUCCEEDED,
- null, null);
- // Verify that we try to install the package in system user.
- verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
- }
- assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
- "1",
- Settings.Secure.getStringForUser(mContentResolver,
- Settings.Secure.DEMO_USER_SETUP_COMPLETE, TEST_DEMO_USER));
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
deleted file mode 100644
index a93f64396d57..000000000000
--- a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2016 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.retaildemo;
-
-import static com.android.server.retaildemo.RetailDemoModeService.SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.Manifest;
-import android.app.ActivityManagerInternal;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.RetailDemoModeServiceInternal;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.CallLog;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.mock.MockContentProvider;
-import android.test.mock.MockContentResolver;
-import android.util.ArrayMap;
-
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.SystemService;
-import com.android.server.retaildemo.RetailDemoModeService.Injector;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.compat.ArgumentMatcher;
-
-import java.io.File;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class RetailDemoModeServiceTest {
- private static final int TEST_DEMO_USER = 111;
- private static final long SETUP_COMPLETE_TIMEOUT_MS = 2000; // 2 sec
- private static final String TEST_CAMERA_PKG = "test.cameraapp";
- private static final String TEST_PRELOADS_DIR_NAME = "test_preloads";
-
- private Context mContext;
- private @Mock UserManager mUm;
- private @Mock PackageManager mPm;
- private @Mock IPackageManager mIpm;
- private @Mock NotificationManager mNm;
- private @Mock ActivityManagerInternal mAmi;
- private @Mock AudioManager mAudioManager;
- private @Mock WifiManager mWifiManager;
- private @Mock LockPatternUtils mLockPatternUtils;
- private @Mock JobScheduler mJobScheduler;
- private MockPreloadAppsInstaller mPreloadAppsInstaller;
- private MockContentResolver mContentResolver;
- private MockContactsProvider mContactsProvider;
- private Configuration mConfiguration;
- private File mTestPreloadsDir;
- private CountDownLatch mLatch;
-
- private RetailDemoModeService mService;
- private TestInjector mInjector;
-
- @BeforeClass
- @AfterClass
- public static void clearSettingsProvider() {
- FakeSettingsProvider.clearSettingsProvider();
- }
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
- when(mContext.getSystemServiceName(eq(JobScheduler.class))).thenReturn(
- Context.JOB_SCHEDULER_SERVICE);
- when(mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).thenReturn(mJobScheduler);
- when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm);
- mContentResolver = new MockContentResolver(mContext);
- mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
- mContactsProvider = new MockContactsProvider(mContext);
- mContentResolver.addProvider(CallLog.AUTHORITY, mContactsProvider);
- when(mContext.getContentResolver()).thenReturn(mContentResolver);
- mPreloadAppsInstaller = new MockPreloadAppsInstaller(mContext);
- mConfiguration = new Configuration();
- mTestPreloadsDir = new File(InstrumentationRegistry.getContext().getFilesDir(),
- TEST_PRELOADS_DIR_NAME);
-
- Settings.Global.putString(mContentResolver, Settings.Global.RETAIL_DEMO_MODE_CONSTANTS, "");
- Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 1);
- Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 1);
-
- // Initialize RetailDemoModeService
- mInjector = new TestInjector();
- mService = new RetailDemoModeService(mInjector);
- mService.onStart();
- }
-
- @After
- public void tearDown() {
- if (mTestPreloadsDir != null) {
- FileUtils.deleteContentsAndDir(mTestPreloadsDir);
- }
- }
-
- @Test
- public void testDemoUserSetup() throws Exception {
- mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
-
- mLatch = new CountDownLatch(1);
- final UserInfo userInfo = new UserInfo();
- userInfo.id = TEST_DEMO_USER;
- when(mUm.createUser(anyString(), anyInt())).thenReturn(userInfo);
-
- setCameraPackage(TEST_CAMERA_PKG);
- mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
- assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set",
- "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED));
-
- final ArgumentCaptor<IntentFilter> intentFilter =
- ArgumentCaptor.forClass(IntentFilter.class);
- verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
- assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF,
- intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF));
-
- // Wait for the setup to complete.
- mLatch.await(SETUP_COMPLETE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- ArgumentCaptor<Integer> flags = ArgumentCaptor.forClass(Integer.class);
- verify(mUm).createUser(anyString(), flags.capture());
- assertTrue("FLAG_DEMO not set during user creation",
- (flags.getValue() & UserInfo.FLAG_DEMO) != 0);
- assertTrue("FLAG_EPHEMERAL not set during user creation",
- (flags.getValue() & UserInfo.FLAG_EPHEMERAL) != 0);
- // Verify if necessary restrictions are being set.
- final UserHandle user = UserHandle.of(TEST_DEMO_USER);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, false, user);
- verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true, UserHandle.SYSTEM);
- // Verify if necessary settings are updated.
- assertEquals("SKIP_FIRST_USE_HINTS setting is not set for demo user",
- Settings.Secure.getIntForUser(mContentResolver,
- Settings.Secure.SKIP_FIRST_USE_HINTS, TEST_DEMO_USER),
- 1);
- assertEquals("PACKAGE_VERIFIER_ENABLE settings should be set to 0 for demo user",
- Settings.Global.getInt(mContentResolver,
- Settings.Global.PACKAGE_VERIFIER_ENABLE),
- 0);
- // Verify if camera is granted location permission.
- verify(mPm).grantRuntimePermission(TEST_CAMERA_PKG,
- Manifest.permission.ACCESS_FINE_LOCATION, user);
- // Verify call logs are cleared.
- assertTrue("Call logs should be deleted", mContactsProvider.isCallLogDeleted());
- }
-
- @Test
- public void testSettingsObserver_disableDemoMode() throws Exception {
- final RetailDemoModeService.SettingsObserver observer =
- mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
- final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
- when(mUm.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT, UserHandle.SYSTEM))
- .thenReturn(false);
- Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1);
- // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially.
- observer.onChange(false, deviceDemoModeUri);
- final ArgumentCaptor<BroadcastReceiver> receiver =
- ArgumentCaptor.forClass(BroadcastReceiver.class);
- verify(mContext).registerReceiver(receiver.capture(), any(IntentFilter.class));
-
- Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
- new File(mTestPreloadsDir, "dir1").mkdirs();
- new File(mTestPreloadsDir, "file1").createNewFile();
- Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_DEMO_MODE, 0);
- observer.onChange(false, deviceDemoModeUri);
- verify(mContext).unregisterReceiver(receiver.getValue());
- verify(mUm).setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, false, UserHandle.SYSTEM);
- assertEquals("Package verifier enable value has not been reset", 1,
- Settings.Global.getInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_ENABLE));
- Thread.sleep(20); // Wait for the deletion to complete.
- // verify that the preloaded directory is emptied.
- assertEquals("Preloads directory is not emptied",
- 0, mTestPreloadsDir.list().length);
- // Verify that the expiration job was scheduled
- verify(mJobScheduler).schedule(any(JobInfo.class));
- }
-
- @Test
- public void testSettingsObserver_enableDemoMode() throws Exception {
- final RetailDemoModeService.SettingsObserver observer =
- mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
- final Uri deviceDemoModeUri = Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE);
- // Settings.Global.DEVICE_DEMO_MODE has been set to 1 initially.
- observer.onChange(false, deviceDemoModeUri);
- assertEquals(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED + " property not set",
- "1", mInjector.systemPropertiesGet(SYSTEM_PROPERTY_RETAIL_DEMO_ENABLED));
-
- final ArgumentCaptor<IntentFilter> intentFilter =
- ArgumentCaptor.forClass(IntentFilter.class);
- verify(mContext).registerReceiver(any(BroadcastReceiver.class), intentFilter.capture());
- assertTrue("Not registered for " + Intent.ACTION_SCREEN_OFF,
- intentFilter.getValue().hasAction(Intent.ACTION_SCREEN_OFF));
- }
-
- @Test
- public void testSwitchToDemoUser() {
- // To make the RetailDemoModeService update it's internal state.
- mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
- final RetailDemoModeService.SettingsObserver observer =
- mService.new SettingsObserver(new Handler(Looper.getMainLooper()));
- observer.onChange(false, Settings.Global.getUriFor(Settings.Global.DEVICE_DEMO_MODE));
-
- final UserInfo userInfo = new UserInfo(TEST_DEMO_USER, "demo_user",
- UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL);
- when(mUm.getUserInfo(TEST_DEMO_USER)).thenReturn(userInfo);
- when(mWifiManager.isWifiEnabled()).thenReturn(false);
- final int minVolume = -111;
- for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) {
- when(mAudioManager.getStreamMinVolume(stream)).thenReturn(minVolume);
- }
-
- mService.onSwitchUser(TEST_DEMO_USER);
- verify(mAmi).updatePersistentConfigurationForUser(mConfiguration, TEST_DEMO_USER);
- for (int stream : RetailDemoModeService.VOLUME_STREAMS_TO_MUTE) {
- verify(mAudioManager).setStreamVolume(stream, minVolume, 0);
- }
- verify(mLockPatternUtils).setLockScreenDisabled(true, TEST_DEMO_USER);
- verify(mWifiManager).setWifiEnabled(true);
- }
-
- private void setCameraPackage(String pkgName) {
- final ResolveInfo ri = new ResolveInfo();
- final ActivityInfo ai = new ActivityInfo();
- ai.packageName = pkgName;
- ri.activityInfo = ai;
- when(mPm.resolveActivityAsUser(
- argThat(new IntentMatcher(MediaStore.ACTION_IMAGE_CAPTURE)),
- anyInt(),
- eq(TEST_DEMO_USER))).thenReturn(ri);
- }
-
- private class IntentMatcher extends ArgumentMatcher<Intent> {
- private final Intent mIntent;
-
- IntentMatcher(String action) {
- mIntent = new Intent(action);
- }
-
- @Override
- public boolean matchesObject(Object argument) {
- if (argument instanceof Intent) {
- return ((Intent) argument).filterEquals(mIntent);
- }
- return false;
- }
-
- @Override
- public String toString() {
- return "Expected: " + mIntent;
- }
- }
-
- private class MockContactsProvider extends MockContentProvider {
- private boolean mCallLogDeleted;
-
- MockContactsProvider(Context context) {
- super(context);
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- if (CallLog.Calls.CONTENT_URI.equals(uri)) {
- mCallLogDeleted = true;
- }
- return 0;
- }
-
- public boolean isCallLogDeleted() {
- return mCallLogDeleted;
- }
- }
-
- private class MockPreloadAppsInstaller extends PreloadAppsInstaller {
- MockPreloadAppsInstaller(Context context) {
- super(context);
- }
-
- @Override
- public void installApps(int userId) {
- }
- }
-
- private class TestInjector extends Injector {
- private ArrayMap<String, String> mSystemProperties = new ArrayMap<>();
-
- TestInjector() {
- super(mContext);
- }
-
- @Override
- Context getContext() {
- return mContext;
- }
-
- @Override
- UserManager getUserManager() {
- return mUm;
- }
-
- @Override
- WifiManager getWifiManager() {
- return mWifiManager;
- }
-
- @Override
- void switchUser(int userId) {
- if (mLatch != null) {
- mLatch.countDown();
- }
- }
-
- @Override
- AudioManager getAudioManager() {
- return mAudioManager;
- }
-
- @Override
- NotificationManager getNotificationManager() {
- return mNm;
- }
-
- @Override
- ActivityManagerInternal getActivityManagerInternal() {
- return mAmi;
- }
-
- @Override
- PackageManager getPackageManager() {
- return mPm;
- }
-
- @Override
- IPackageManager getIPackageManager() {
- return mIpm;
- }
-
- @Override
- ContentResolver getContentResolver() {
- return mContentResolver;
- }
-
- @Override
- PreloadAppsInstaller getPreloadAppsInstaller() {
- return mPreloadAppsInstaller;
- }
-
- @Override
- void systemPropertiesSet(String key, String value) {
- mSystemProperties.put(key, value);
- }
-
- @Override
- void turnOffAllFlashLights(String[] cameraIdsWithFlash) {
- }
-
- @Override
- void initializeWakeLock() {
- }
-
- @Override
- void destroyWakeLock() {
- }
-
- @Override
- boolean isWakeLockHeld() {
- return false;
- }
-
- @Override
- void acquireWakeLock() {
- }
-
- @Override
- void releaseWakeLock() {
- }
-
- @Override
- void logSessionDuration(int duration) {
- }
-
- @Override
- void logSessionCount(int count) {
- }
-
- @Override
- Configuration getSystemUsersConfiguration() {
- return mConfiguration;
- }
-
- @Override
- LockPatternUtils getLockPatternUtils() {
- return mLockPatternUtils;
- }
-
- @Override
- Notification createResetNotification() {
- return null;
- }
-
- @Override
- File getDataPreloadsDirectory() {
- return mTestPreloadsDir;
- }
-
- @Override
- File getDataPreloadsFileCacheDirectory() {
- return new File(mTestPreloadsDir, "file_cache");
- }
-
- @Override
- void publishLocalService(RetailDemoModeService service,
- RetailDemoModeServiceInternal localService) {
- }
-
- String systemPropertiesGet(String key) {
- return mSystemProperties.get(key);
- }
- }
-}
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index 0060901578cd..cb6a83d2644b 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -16,12 +16,14 @@
package com.android.internal.colorextraction;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.Mockito.any;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Color;
@@ -29,7 +31,6 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.colorextraction.types.ExtractionType;
import com.android.internal.colorextraction.types.Tonal;
@@ -78,10 +79,10 @@ public class ColorExtractorTest {
ExtractionType type =
(inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
outGradientColorsExtraDark) -> {
- outGradientColorsNormal.set(colorsExpectedNormal);
- outGradientColorsDark.set(colorsExpectedDark);
- outGradientColorsExtraDark.set(colorsExpectedExtraDark);
- };
+ outGradientColorsNormal.set(colorsExpectedNormal);
+ outGradientColorsDark.set(colorsExpectedDark);
+ outGradientColorsExtraDark.set(colorsExpectedExtraDark);
+ };
ColorExtractor extractor = new ColorExtractor(mContext, type);
GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM,
@@ -92,4 +93,22 @@ public class ColorExtractorTest {
colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_EXTRA_DARK);
assertEquals("Extracted colors not being used!", colors, colorsExpectedExtraDark);
}
+
+ @Test
+ public void addOnColorsChangedListener_invokesListener() {
+ ColorExtractor.OnColorsChangedListener mockedListeners =
+ mock(ColorExtractor.OnColorsChangedListener.class);
+ ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext));
+ extractor.addOnColorsChangedListener(mockedListeners);
+
+ extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
+ WallpaperManager.FLAG_LOCK);
+ verify(mockedListeners, times(1)).onColorsChanged(any(),
+ eq(WallpaperManager.FLAG_LOCK));
+
+ extractor.removeOnColorsChangedListener(mockedListeners);
+ extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
+ WallpaperManager.FLAG_LOCK);
+ verifyNoMoreInteractions(mockedListeners);
+ }
}
diff --git a/tests/UiBench/Android.mk b/tests/UiBench/Android.mk
index 71067aef52c7..e6af4b024700 100644
--- a/tests/UiBench/Android.mk
+++ b/tests/UiBench/Android.mk
@@ -15,21 +15,24 @@ LOCAL_RESOURCE_DIR := \
frameworks/support/design/res \
frameworks/support/v7/appcompat/res \
frameworks/support/v7/cardview/res \
- frameworks/support/v7/recyclerview/res
+ frameworks/support/v7/recyclerview/res \
+ frameworks/support/v17/leanback/res
LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages android.support.design \
--extra-packages android.support.v7.appcompat \
--extra-packages android.support.v7.cardview \
- --extra-packages android.support.v7.recyclerview
+ --extra-packages android.support.v7.recyclerview \
+ --extra-packages android.support.v17.leanback
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-design \
android-support-v4 \
android-support-v7-appcompat \
android-support-v7-cardview \
- android-support-v7-recyclerview
+ android-support-v7-recyclerview \
+ android-support-v17-leanback
LOCAL_PACKAGE_NAME := UiBench
diff --git a/tests/UiBench/AndroidManifest.xml b/tests/UiBench/AndroidManifest.xml
index c20be5141df5..2521dc9f82ae 100644
--- a/tests/UiBench/AndroidManifest.xml
+++ b/tests/UiBench/AndroidManifest.xml
@@ -257,5 +257,15 @@
<category android:name="com.android.test.uibench.TEST" />
</intent-filter>
</activity>
+
+ <activity
+ android:name=".leanback.BrowseActivity"
+ android:theme="@style/Theme.Leanback.Browse"
+ android:label="Leanback/Browse Fragment" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.uibench.TEST" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/tests/UiBench/build.gradle b/tests/UiBench/build.gradle
index 03ef7f106de5..fa2cfcd438fd 100644
--- a/tests/UiBench/build.gradle
+++ b/tests/UiBench/build.gradle
@@ -36,4 +36,5 @@ dependencies {
compile 'com.android.support:cardview-v7:23.0.1'
compile 'com.android.support:recyclerview-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
+ compile 'com.android.support:leanback-v17:23.0.1'
}
diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/BitmapLoader.java b/tests/UiBench/src/com/android/test/uibench/leanback/BitmapLoader.java
new file mode 100644
index 000000000000..8af9d3bca647
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/leanback/BitmapLoader.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 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.test.uibench.leanback;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.os.AsyncTask;
+import android.support.v4.util.LruCache;
+import android.util.DisplayMetrics;
+import android.widget.ImageView;
+
+/**
+ * This class simulates a typical Bitmap memory cache with up to 1.5 times of screen pixels.
+ * The sample bitmap is generated in worker threads in AsyncTask.THREAD_POOL_EXECUTOR.
+ * The class does not involve decoding, disk cache i/o, network i/o, as the test is mostly focusing
+ * on the graphics side.
+ * There will be two general use cases for cards in leanback test:
+ * 1. As a typical app, each card has its own id and load its own Bitmap, the test result will
+ * include impact of texture upload.
+ * 2. All cards share same id/Bitmap and there wont be texture upload.
+ */
+public class BitmapLoader {
+
+ /**
+ * Caches bitmaps with bytes adds up to 1.5 x screen
+ * DO NOT CHANGE this defines baseline of test result.
+ */
+ static final float CACHE_SIZE_TO_SCREEN = 1.5f;
+ /**
+ * 4 bytes per pixel for RGBA_8888
+ */
+ static final int BYTES_PER_PIXEL = 4;
+
+ static LruCache<Long, Bitmap> sLruCache;
+ static Paint sTextPaint = new Paint();
+
+ static {
+ sTextPaint.setColor(Color.BLACK);
+ }
+
+ /**
+ * get or initialize LruCache, the max is set to full screen pixels.
+ */
+ static LruCache<Long, Bitmap> getLruCache(Context context) {
+ if (sLruCache == null) {
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ int width = metrics.widthPixels;
+ int height = metrics.heightPixels;
+ int maxBytes = (int) (width * height * BYTES_PER_PIXEL * CACHE_SIZE_TO_SCREEN);
+ sLruCache = new LruCache<Long, Bitmap>(maxBytes) {
+ @Override
+ protected int sizeOf(Long key, Bitmap value) {
+ return value.getByteCount();
+ }
+ };
+ }
+ return sLruCache;
+ }
+
+ static class BitmapAsyncTask extends AsyncTask<Void, Void, Bitmap> {
+
+ ImageView mImageView;
+ long mId;
+ int mWidth;
+ int mHeight;
+
+ BitmapAsyncTask(ImageView view, long id, int width, int height) {
+ mImageView = view;
+ mId = id;
+ mImageView.setTag(this);
+ mWidth = width;
+ mHeight = height;
+ }
+
+ @Override
+ protected Bitmap doInBackground(Void... voids) {
+ // generate a sample bitmap: white background and text showing id
+ Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ canvas.drawARGB(0xff, 0xff, 0xff, 0xff);
+ canvas.drawText(Long.toString(mId), 0f, mHeight / 2, sTextPaint);
+ canvas.setBitmap(null);
+ bitmap.prepareToDraw();
+ return bitmap;
+ }
+
+ @Override
+ protected void onCancelled() {
+ if (mImageView.getTag() == this) {
+ mImageView.setTag(null);
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ if (mImageView.getTag() == this) {
+ mImageView.setTag(null);
+ sLruCache.put(mId, bitmap);
+ mImageView.setImageBitmap(bitmap);
+ }
+ }
+ }
+
+ public static void loadBitmap(ImageView view, long id, int width, int height) {
+ Context context = view.getContext();
+ Bitmap bitmap = getLruCache(context).get(id);
+ if (bitmap != null) {
+ view.setImageBitmap(bitmap);
+ return;
+ }
+ new BitmapAsyncTask(view, id, width, height)
+ .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ public static void cancel(ImageView view) {
+ BitmapAsyncTask task = (BitmapAsyncTask) view.getTag();
+ if (task != null && task.mImageView == view) {
+ task.mImageView.setTag(null);
+ task.cancel(false);
+ }
+ }
+
+ public static void clear() {
+ if (sLruCache != null) {
+ sLruCache.evictAll();
+ }
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/BrowseActivity.java b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseActivity.java
new file mode 100644
index 000000000000..d29f0eaf6fdc
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseActivity.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.test.uibench.leanback;
+
+import android.support.v4.app.FragmentActivity;
+import android.app.Activity;
+import android.os.Bundle;
+
+public class BrowseActivity extends FragmentActivity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState == null) {
+ getSupportFragmentManager().beginTransaction()
+ .add(android.R.id.content, new BrowseFragment())
+ .commit();
+ }
+ }
+
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/BrowseFragment.java b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseFragment.java
new file mode 100644
index 000000000000..11ea36132dcc
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/leanback/BrowseFragment.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 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.test.uibench.leanback;
+
+import android.os.Bundle;
+
+public class BrowseFragment extends android.support.v17.leanback.app.BrowseSupportFragment {
+
+ public BrowseFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ BitmapLoader.clear();
+ TestHelper.initBackground(getActivity());
+ boolean runEntranceTransition = TestHelper.runEntranceTransition(getActivity());
+ if (runEntranceTransition) {
+ prepareEntranceTransition();
+ }
+ setAdapter(TestHelper.initRowsAdapterBuilder(getActivity()).build());
+ if (runEntranceTransition) {
+ startEntranceTransition();
+ }
+ }
+
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/CardPresenter.java b/tests/UiBench/src/com/android/test/uibench/leanback/CardPresenter.java
new file mode 100644
index 000000000000..5194555aca01
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/leanback/CardPresenter.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 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.test.uibench.leanback;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v4.content.res.ResourcesCompat;
+import android.view.ContextThemeWrapper;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+
+public class CardPresenter extends Presenter {
+
+ private int mImageWidth = 0;
+ private int mImageHeight = 0;
+
+ public CardPresenter(int width, int height) {
+ mImageWidth = width;
+ mImageHeight = height;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ Context context = parent.getContext();
+ ImageCardView v = new ImageCardView(context);
+ v.setFocusable(true);
+ v.setFocusableInTouchMode(true);
+ v.setMainImageAdjustViewBounds(true);
+ v.setMainImageDimensions(mImageWidth, mImageHeight);
+ return new ViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder viewHolder, Object item) {
+ PhotoItem photoItem = (PhotoItem) item;
+ ImageCardView cardView = (ImageCardView) viewHolder.view;
+ cardView.setTitleText(photoItem.getTitle());
+ BitmapLoader.loadBitmap(cardView.getMainImageView(), photoItem.getId(),
+ mImageWidth, mImageHeight);
+ }
+
+ @Override
+ public void onUnbindViewHolder(ViewHolder viewHolder) {
+ ImageCardView cardView = (ImageCardView) viewHolder.view;
+ BitmapLoader.cancel(cardView.getMainImageView());
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/PhotoItem.java b/tests/UiBench/src/com/android/test/uibench/leanback/PhotoItem.java
new file mode 100644
index 000000000000..acb9a5d05a7f
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/leanback/PhotoItem.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 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.test.uibench.leanback;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class PhotoItem implements Parcelable {
+
+ private String mTitle;
+ private long mId;
+
+ public PhotoItem(String title, long id) {
+ mTitle = title;
+ mId = id;
+ }
+
+ public long getId() {
+ return mId;
+ }
+
+ public String getTitle() {
+ return mTitle;
+ }
+
+ @Override
+ public String toString() {
+ return mTitle;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mTitle);
+ dest.writeLong(mId);
+ }
+
+ public static final Creator<PhotoItem> CREATOR
+ = new Creator<PhotoItem>() {
+ @Override
+ public PhotoItem createFromParcel(Parcel in) {
+ return new PhotoItem(in);
+ }
+
+ @Override
+ public PhotoItem[] newArray(int size) {
+ return new PhotoItem[size];
+ }
+ };
+
+ private PhotoItem(Parcel in) {
+ mTitle = in.readString();
+ mId = in.readLong();
+ }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/leanback/TestHelper.java b/tests/UiBench/src/com/android/test/uibench/leanback/TestHelper.java
new file mode 100644
index 000000000000..2bf388501ba0
--- /dev/null
+++ b/tests/UiBench/src/com/android/test/uibench/leanback/TestHelper.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2017 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.test.uibench.leanback;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.support.v17.leanback.app.BackgroundManager;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.ObjectAdapter;
+import android.support.v17.leanback.widget.Presenter;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+
+public class TestHelper {
+
+ public static final String EXTRA_BACKGROUND = "extra_bg";
+ public static final String EXTRA_ROWS = "extra_rows";
+ public static final String EXTRA_CARDS_PER_ROW = "extra_cards_per_row";
+ public static final String EXTRA_CARD_HEIGHT_DP = "extra_card_height";
+ public static final String EXTRA_CARD_WIDTH_DP = "extra_card_width";
+ public static final String EXTRA_CARD_SHADOW = "extra_card_shadow";
+ public static final String EXTRA_CARD_ROUND_RECT = "extra_card_round_rect";
+ public static final String EXTRA_ENTRANCE_TRANSITION = "extra_entrance_transition";
+ public static final String EXTRA_BITMAP_UPLOAD = "extra_bitmap_upload";
+
+ /**
+ * Dont change the default values, they gave baseline for measuring the performance
+ */
+ static final int DEFAULT_CARD_HEIGHT_DP = 180;
+ static final int DEFAULT_CARD_WIDTH_DP = 125;
+ static final int DEFAULT_CARDS_PER_ROW = 20;
+ static final int DEFAULT_ROWS = 10;
+ static final boolean DEFAULT_ENTRANCE_TRANSITION = false;
+ static final boolean DEFAULT_BACKGROUND = true;
+ static final boolean DEFAULT_CARD_SHADOW = true;
+ static final boolean DEFAULT_CARD_ROUND_RECT = true;
+ static final boolean DEFAULT_BITMAP_UPLOAD = true;
+
+ static long sCardIdSeed = 0;
+ static long sRowIdSeed = 0;
+
+ public static class ListRowPresenterBuilder {
+
+ boolean mShadow = DEFAULT_CARD_SHADOW;
+ boolean mRoundedCorner = DEFAULT_CARD_ROUND_RECT;
+
+ ListRowPresenterBuilder(Context context) {
+ }
+
+ public ListRowPresenterBuilder configShadow(boolean shadow) {
+ mShadow = shadow;
+ return this;
+ }
+
+ public ListRowPresenterBuilder configRoundedCorner(boolean roundedCorner) {
+ mRoundedCorner = roundedCorner;
+ return this;
+ }
+
+ public ListRowPresenter build() {
+ ListRowPresenter listRowPresenter = new ListRowPresenter();
+ listRowPresenter.setShadowEnabled(mShadow);
+ listRowPresenter.enableChildRoundedCorners(mRoundedCorner);
+ return listRowPresenter;
+ }
+ }
+
+ public static class CardPresenterBuilder {
+ Context mContext;
+ int mWidthDP = DEFAULT_CARD_WIDTH_DP;
+ int mHeightDP = DEFAULT_CARD_HEIGHT_DP;
+
+ CardPresenterBuilder(Context context) {
+ mContext = context;
+ }
+
+ public CardPresenterBuilder configWidthDP(int widthDP) {
+ mWidthDP = widthDP;
+ return this;
+ }
+
+ public CardPresenterBuilder configHeightDP(int hightDP) {
+ mHeightDP = hightDP;
+ return this;
+ }
+
+ public Presenter build() {
+ DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
+ return new CardPresenter(
+ (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mWidthDP, dm),
+ (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHeightDP, dm));
+ }
+ }
+
+ public static class RowsAdapterBuilder {
+
+ Context mContext;
+ int mCardsPerRow = DEFAULT_CARDS_PER_ROW;
+ int mRows = DEFAULT_ROWS;
+ CardPresenterBuilder mCardPresenterBuilder;
+ ListRowPresenterBuilder mListRowPresenterBuilder;
+ Presenter mCardPresenter;
+ boolean mBitmapUpload = DEFAULT_BITMAP_UPLOAD;
+
+ static final String[] sSampleStrings = new String[] {
+ "Hello world", "This is a test", "Android TV", "UI Jank Test",
+ "Scroll Up", "Scroll Down", "Load Bitmaps"
+ };
+
+ /**
+ * Create a RowsAdapterBuilder with default settings
+ */
+ public RowsAdapterBuilder(Context context) {
+ mContext = context;
+ mCardPresenterBuilder = new CardPresenterBuilder(context);
+ mListRowPresenterBuilder = new ListRowPresenterBuilder(context);
+ }
+
+ public ListRowPresenterBuilder getListRowPresenterBuilder() {
+ return mListRowPresenterBuilder;
+ }
+
+ public CardPresenterBuilder getCardPresenterBuilder() {
+ return mCardPresenterBuilder;
+ }
+
+ public RowsAdapterBuilder configRows(int rows) {
+ mRows = rows;
+ return this;
+ }
+
+ public RowsAdapterBuilder configCardsPerRow(int cardsPerRow) {
+ mCardsPerRow = cardsPerRow;
+ return this;
+ }
+
+ public RowsAdapterBuilder configBitmapUpLoad(boolean bitmapUpload) {
+ mBitmapUpload = bitmapUpload;
+ return this;
+ }
+
+ public ListRow buildListRow() {
+ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(mCardPresenter);
+ ListRow listRow = new ListRow(new HeaderItem(sRowIdSeed++, "Row"), listRowAdapter);
+ int indexSample = 0;
+ for (int i = 0; i < mCardsPerRow; i++) {
+ // when doing bitmap upload, use different id so each card has different bitmap
+ // otherwise all cards share the same bitmap
+ listRowAdapter.add(new PhotoItem(sSampleStrings[indexSample],
+ (mBitmapUpload ? sCardIdSeed++ : 0)));
+ indexSample++;
+ if (indexSample >= sSampleStrings.length) {
+ indexSample = 0;
+ }
+ }
+ return listRow;
+ }
+
+ public ObjectAdapter build() {
+ try {
+ mCardPresenter = mCardPresenterBuilder.build();
+ ArrayObjectAdapter adapter = new ArrayObjectAdapter(
+ mListRowPresenterBuilder.build());
+ for (int i = 0; i < mRows; i++) {
+ adapter.add(buildListRow());
+ }
+ return adapter;
+ } finally {
+ mCardPresenter = null;
+ }
+ }
+ }
+
+ public static boolean runEntranceTransition(Activity activity) {
+ return activity.getIntent().getBooleanExtra(EXTRA_ENTRANCE_TRANSITION,
+ DEFAULT_ENTRANCE_TRANSITION);
+ }
+
+ public static RowsAdapterBuilder initRowsAdapterBuilder(Activity activity) {
+ RowsAdapterBuilder builder = new RowsAdapterBuilder(activity);
+ boolean shadow = activity.getIntent().getBooleanExtra(EXTRA_CARD_SHADOW,
+ DEFAULT_CARD_SHADOW);
+ boolean roundRect = activity.getIntent().getBooleanExtra(EXTRA_CARD_ROUND_RECT,
+ DEFAULT_CARD_ROUND_RECT);
+ int widthDp = activity.getIntent().getIntExtra(EXTRA_CARD_WIDTH_DP,
+ DEFAULT_CARD_WIDTH_DP);
+ int heightDp = activity.getIntent().getIntExtra(EXTRA_CARD_HEIGHT_DP,
+ DEFAULT_CARD_HEIGHT_DP);
+ int rows = activity.getIntent().getIntExtra(EXTRA_ROWS, DEFAULT_ROWS);
+ int cardsPerRow = activity.getIntent().getIntExtra(EXTRA_CARDS_PER_ROW,
+ DEFAULT_CARDS_PER_ROW);
+ boolean bitmapUpload = activity.getIntent().getBooleanExtra(EXTRA_BITMAP_UPLOAD,
+ DEFAULT_BITMAP_UPLOAD);
+ builder.configRows(rows)
+ .configCardsPerRow(cardsPerRow)
+ .configBitmapUpLoad(bitmapUpload);
+ builder.getListRowPresenterBuilder()
+ .configRoundedCorner(roundRect)
+ .configShadow(shadow);
+ builder.getCardPresenterBuilder()
+ .configWidthDP(widthDp)
+ .configHeightDP(heightDp);
+ return builder;
+ }
+
+ public static void initBackground(Activity activity) {
+ if (activity.getIntent().getBooleanExtra(EXTRA_BACKGROUND, DEFAULT_BACKGROUND)) {
+ BackgroundManager manager = BackgroundManager.getInstance(activity);
+ manager.attach(activity.getWindow());
+ DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
+ int width = metrics.widthPixels;
+ int height = metrics.heightPixels;
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ canvas.drawARGB(255, 128, 128, 128);
+ canvas.setBitmap(null);
+ manager.setBitmap(bitmap);
+ }
+ }
+}