summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt5
-rw-r--r--api/test-current.txt6
-rw-r--r--cmds/incidentd/src/incidentd_util.cpp6
-rw-r--r--config/hiddenapi-light-greylist.txt2
-rw-r--r--core/java/android/app/ActivityManager.java34
-rw-r--r--core/java/android/app/ActivityThread.java145
-rw-r--r--core/java/android/app/IActivityManager.aidl2
-rw-r--r--core/java/android/app/Notification.java40
-rw-r--r--core/java/android/content/IntentFilter.java5
-rw-r--r--core/java/android/content/pm/PackageParser.java31
-rw-r--r--core/java/android/content/res/Configuration.java10
-rw-r--r--core/java/android/hardware/display/DisplayManager.java1
-rw-r--r--core/java/android/os/Build.java2
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/view/NotificationHeaderView.java31
-rw-r--r--core/java/android/view/View.java35
-rw-r--r--core/java/android/view/textclassifier/SystemTextClassifier.java14
-rw-r--r--core/java/android/view/textclassifier/TextClassificationConstants.java (renamed from core/java/android/view/textclassifier/TextClassifierConstants.java)94
-rw-r--r--core/java/android/view/textclassifier/TextClassificationManager.java23
-rw-r--r--core/java/android/view/textclassifier/TextClassifier.java8
-rw-r--r--core/java/android/view/textclassifier/TextClassifierImpl.java37
-rw-r--r--core/java/android/webkit/URLUtil.java2
-rw-r--r--core/java/android/widget/Editor.java11
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java31
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java2
-rw-r--r--core/proto/android/content/configuration.proto6
-rw-r--r--core/proto/android/os/incident.proto14
-rw-r--r--core/proto/android/server/activitymanagerservice.proto26
-rw-r--r--core/proto/android/server/alarmmanagerservice.proto2
-rw-r--r--core/proto/android/server/windowmanagerservice.proto2
-rw-r--r--core/proto/android/server/windowmanagertrace.proto2
-rw-r--r--core/res/res/drawable/ic_alert_window_layer.xml24
-rw-r--r--core/res/res/drawable/ic_camera.xml27
-rw-r--r--core/res/res/drawable/ic_mic.xml24
-rw-r--r--core/res/res/layout/notification_template_header.xml39
-rw-r--r--core/res/res/values-land/dimens.xml3
-rw-r--r--core/res/res/values/attrs_manifest.xml10
-rw-r--r--core/res/res/values/dimens.xml6
-rw-r--r--core/res/res/values/symbols.xml10
-rw-r--r--core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java105
-rw-r--r--core/tests/coretests/src/android/view/textclassifier/TextClassifierConstantsTest.java46
-rw-r--r--media/java/android/media/Ringtone.java39
-rw-r--r--packages/SettingsLib/res/values/strings.xml82
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java79
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java124
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java90
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_row.xml4
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java166
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Recents.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java68
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java195
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java102
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java136
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java39
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java2
-rw-r--r--packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml3
-rw-r--r--packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml3
-rw-r--r--packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml3
-rw-r--r--proto/src/metrics_constants.proto5
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java96
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java335
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java166
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java4
-rw-r--r--services/core/java/com/android/server/am/VrController.java2
-rw-r--r--services/core/java/com/android/server/media/MediaUpdateService.java29
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java19
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java4
90 files changed, 2340 insertions, 737 deletions
diff --git a/api/current.txt b/api/current.txt
index 39187b806987..c4ec27feb50f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3883,6 +3883,7 @@ package android.app {
method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException;
method public deprecated java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException;
method public deprecated java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+ method public boolean isBackgroundRestricted();
method public deprecated boolean isInLockTaskMode();
method public boolean isLowRamDevice();
method public static boolean isRunningInTestHarness();
@@ -25211,10 +25212,14 @@ package android.media {
method public android.media.AudioAttributes getAudioAttributes();
method public deprecated int getStreamType();
method public java.lang.String getTitle(android.content.Context);
+ method public float getVolume();
+ method public boolean isLooping();
method public boolean isPlaying();
method public void play();
method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
+ method public void setLooping(boolean);
method public deprecated void setStreamType(int);
+ method public void setVolume(float);
method public void stop();
}
diff --git a/api/test-current.txt b/api/test-current.txt
index d5b43115c125..21d12c357164 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -12,6 +12,7 @@ package android.app {
public class ActivityManager {
method public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
method public int getPackageImportance(java.lang.String);
+ method public long getTotalRam();
method public int getUidImportance(int);
method public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
method public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException;
@@ -351,6 +352,7 @@ package android.hardware.display {
public final class DisplayManager {
method public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents();
+ method public android.graphics.Point getStableDisplaySize();
method public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration);
}
@@ -446,6 +448,10 @@ package android.net {
package android.os {
+ public static class Build.VERSION {
+ field public static final int RESOURCES_SDK_INT;
+ }
+
public class IncidentManager {
method public void reportIncident(android.os.IncidentReportArgs);
method public void reportIncident(java.lang.String, byte[]);
diff --git a/cmds/incidentd/src/incidentd_util.cpp b/cmds/incidentd/src/incidentd_util.cpp
index fc7cec9dbb40..c095f2bcf144 100644
--- a/cmds/incidentd/src/incidentd_util.cpp
+++ b/cmds/incidentd/src/incidentd_util.cpp
@@ -94,10 +94,10 @@ const char** varargs(const char* first, va_list rest) {
// allocate extra 1 for NULL terminator
const char** ret = (const char**)malloc(sizeof(const char*) * (numOfArgs + 1));
ret[0] = first;
- for (int i = 0; i < numOfArgs; i++) {
+ for (int i = 1; i < numOfArgs; i++) {
const char* arg = va_arg(rest, const char*);
- ret[i + 1] = arg;
+ ret[i] = arg;
}
- ret[numOfArgs + 1] = NULL;
+ ret[numOfArgs] = NULL;
return ret;
}
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 8d70a553f1b3..cc57f6c1bee5 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -976,8 +976,6 @@ Landroid/media/RemoteDisplay;->notifyDisplayConnected(Landroid/view/Surface;IIII
Landroid/media/RemoteDisplay;->notifyDisplayDisconnected()V
Landroid/media/RemoteDisplay;->notifyDisplayError(I)V
Landroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;I)Landroid/media/Ringtone;
-Landroid/media/Ringtone;->setLooping(Z)V
-Landroid/media/Ringtone;->setVolume(F)V
Landroid/media/session/MediaSessionLegacyHelper;->getHelper(Landroid/content/Context;)Landroid/media/session/MediaSessionLegacyHelper;
Landroid/media/SubtitleController;->mHandler:Landroid/os/Handler;
Landroid/media/ThumbnailUtils;->createImageThumbnail(Ljava/lang/String;I)Landroid/graphics/Bitmap;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 03faeeeb91a1..de4d1785745d 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -71,6 +71,7 @@ import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.os.TransferPipe;
import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.MemInfoReader;
import com.android.server.LocalServices;
import org.xmlpull.v1.XmlSerializer;
@@ -964,6 +965,17 @@ public class ActivityManager {
}
/**
+ * Return the total number of bytes of RAM this device has.
+ * @hide
+ */
+ @TestApi
+ public long getTotalRam() {
+ MemInfoReader memreader = new MemInfoReader();
+ memreader.readMemInfo();
+ return memreader.getTotalSize();
+ }
+
+ /**
* Return the maximum number of recents entries that we will maintain and show.
* @hide
*/
@@ -3335,6 +3347,28 @@ public class ActivityManager {
}
/**
+ * Query whether the user has enabled background restrictions for this app.
+ *
+ * <p> The user may chose to do this, if they see that an app is consuming an unreasonable
+ * amount of battery while in the background. </p>
+ *
+ * <p> If true, any work that the app tries to do will be aggressively restricted while it is in
+ * the background. At a minimum, jobs and alarms will not execute and foreground services
+ * cannot be started unless an app activity is in the foreground. </p>
+ *
+ * <p><b> Note that these restrictions stay in effect even when the device is charging.</b></p>
+ *
+ * @return true if user has enforced background restrictions for this app, false otherwise.
+ */
+ public boolean isBackgroundRestricted() {
+ try {
+ return getService().isBackgroundRestricted(mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Sets the memory trim mode for a process and schedules a memory trim operation.
*
* <p><b>Note: this method is only intended for testing framework.</b></p>
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 457f945bff80..379944e2e230 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -143,7 +143,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.org.conscrypt.OpenSSLSocketImpl;
import com.android.org.conscrypt.TrustedCertificateStore;
-import com.android.server.am.proto.MemInfoProto;
+import com.android.server.am.proto.MemInfoDumpProto;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.CloseGuard;
@@ -1251,55 +1251,62 @@ public final class ActivityThread extends ClientTransactionHandler {
long parcelCount = Parcel.getGlobalAllocCount();
SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
- final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
- proto.write(MemInfoProto.ProcessMemory.PID, Process.myPid());
- proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME,
+ final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
+ proto.write(MemInfoDumpProto.ProcessMemory.PID, Process.myPid());
+ proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME,
(mBoundApplication != null) ? mBoundApplication.processName : "unknown");
dumpMemInfoTable(proto, memInfo, dumpDalvik, dumpSummaryOnly,
nativeMax, nativeAllocated, nativeFree,
dalvikMax, dalvikAllocated, dalvikFree);
proto.end(mToken);
- final long oToken = proto.start(MemInfoProto.AppData.OBJECTS);
- proto.write(MemInfoProto.AppData.ObjectStats.VIEW_INSTANCE_COUNT, viewInstanceCount);
- proto.write(MemInfoProto.AppData.ObjectStats.VIEW_ROOT_INSTANCE_COUNT,
+ final long oToken = proto.start(MemInfoDumpProto.AppData.OBJECTS);
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_INSTANCE_COUNT,
+ viewInstanceCount);
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_ROOT_INSTANCE_COUNT,
viewRootInstanceCount);
- proto.write(MemInfoProto.AppData.ObjectStats.APP_CONTEXT_INSTANCE_COUNT,
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.APP_CONTEXT_INSTANCE_COUNT,
appContextInstanceCount);
- proto.write(MemInfoProto.AppData.ObjectStats.ACTIVITY_INSTANCE_COUNT,
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.ACTIVITY_INSTANCE_COUNT,
activityInstanceCount);
- proto.write(MemInfoProto.AppData.ObjectStats.GLOBAL_ASSET_COUNT, globalAssetCount);
- proto.write(MemInfoProto.AppData.ObjectStats.GLOBAL_ASSET_MANAGER_COUNT,
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_COUNT,
+ globalAssetCount);
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_MANAGER_COUNT,
globalAssetManagerCount);
- proto.write(MemInfoProto.AppData.ObjectStats.LOCAL_BINDER_OBJECT_COUNT,
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.LOCAL_BINDER_OBJECT_COUNT,
binderLocalObjectCount);
- proto.write(MemInfoProto.AppData.ObjectStats.PROXY_BINDER_OBJECT_COUNT,
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.PROXY_BINDER_OBJECT_COUNT,
binderProxyObjectCount);
- proto.write(MemInfoProto.AppData.ObjectStats.PARCEL_MEMORY_KB, parcelSize / 1024);
- proto.write(MemInfoProto.AppData.ObjectStats.PARCEL_COUNT, parcelCount);
- proto.write(MemInfoProto.AppData.ObjectStats.BINDER_OBJECT_DEATH_COUNT,
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_MEMORY_KB,
+ parcelSize / 1024);
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_COUNT, parcelCount);
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.BINDER_OBJECT_DEATH_COUNT,
binderDeathObjectCount);
- proto.write(MemInfoProto.AppData.ObjectStats.OPEN_SSL_SOCKET_COUNT, openSslSocketCount);
- proto.write(MemInfoProto.AppData.ObjectStats.WEBVIEW_INSTANCE_COUNT,
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.OPEN_SSL_SOCKET_COUNT,
+ openSslSocketCount);
+ proto.write(MemInfoDumpProto.AppData.ObjectStats.WEBVIEW_INSTANCE_COUNT,
webviewInstanceCount);
proto.end(oToken);
// SQLite mem info
- final long sToken = proto.start(MemInfoProto.AppData.SQL);
- proto.write(MemInfoProto.AppData.SqlStats.MEMORY_USED_KB, stats.memoryUsed / 1024);
- proto.write(MemInfoProto.AppData.SqlStats.PAGECACHE_OVERFLOW_KB,
+ final long sToken = proto.start(MemInfoDumpProto.AppData.SQL);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.MEMORY_USED_KB,
+ stats.memoryUsed / 1024);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.PAGECACHE_OVERFLOW_KB,
stats.pageCacheOverflow / 1024);
- proto.write(MemInfoProto.AppData.SqlStats.MALLOC_SIZE_KB, stats.largestMemAlloc / 1024);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.MALLOC_SIZE_KB,
+ stats.largestMemAlloc / 1024);
int n = stats.dbStats.size();
for (int i = 0; i < n; i++) {
DbStats dbStats = stats.dbStats.get(i);
- final long dToken = proto.start(MemInfoProto.AppData.SqlStats.DATABASES);
- proto.write(MemInfoProto.AppData.SqlStats.Database.NAME, dbStats.dbName);
- proto.write(MemInfoProto.AppData.SqlStats.Database.PAGE_SIZE, dbStats.pageSize);
- proto.write(MemInfoProto.AppData.SqlStats.Database.DB_SIZE, dbStats.dbSize);
- proto.write(MemInfoProto.AppData.SqlStats.Database.LOOKASIDE_B, dbStats.lookaside);
- proto.write(MemInfoProto.AppData.SqlStats.Database.CACHE, dbStats.cache);
+ final long dToken = proto.start(MemInfoDumpProto.AppData.SqlStats.DATABASES);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.Database.NAME, dbStats.dbName);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.Database.PAGE_SIZE, dbStats.pageSize);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.Database.DB_SIZE, dbStats.dbSize);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.Database.LOOKASIDE_B,
+ dbStats.lookaside);
+ proto.write(MemInfoDumpProto.AppData.SqlStats.Database.CACHE, dbStats.cache);
proto.end(dToken);
}
proto.end(sToken);
@@ -1307,7 +1314,7 @@ public final class ActivityThread extends ClientTransactionHandler {
// Asset details.
String assetAlloc = AssetManager.getAssetAllocations();
if (assetAlloc != null) {
- proto.write(MemInfoProto.AppData.ASSET_ALLOCATIONS, assetAlloc);
+ proto.write(MemInfoDumpProto.AppData.ASSET_ALLOCATIONS, assetAlloc);
}
// Unreachable native memory
@@ -1315,7 +1322,7 @@ public final class ActivityThread extends ClientTransactionHandler {
int flags = mBoundApplication == null ? 0 : mBoundApplication.appInfo.flags;
boolean showContents = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0
|| android.os.Build.IS_DEBUGGABLE;
- proto.write(MemInfoProto.AppData.UNREACHABLE_MEMORY,
+ proto.write(MemInfoDumpProto.AppData.UNREACHABLE_MEMORY,
Debug.getUnreachableMemory(100, showContents));
}
}
@@ -2505,17 +2512,17 @@ public final class ActivityThread extends ClientTransactionHandler {
boolean hasSwappedOutPss, int dirtySwap, int dirtySwapPss) {
final long token = proto.start(fieldId);
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.NAME, name);
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.TOTAL_PSS_KB, pss);
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.CLEAN_PSS_KB, cleanPss);
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.SHARED_DIRTY_KB, sharedDirty);
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty);
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.SHARED_CLEAN_KB, sharedClean);
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.PRIVATE_CLEAN_KB, privateClean);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.NAME, name);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.TOTAL_PSS_KB, pss);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.CLEAN_PSS_KB, cleanPss);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_DIRTY_KB, sharedDirty);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_CLEAN_KB, sharedClean);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_CLEAN_KB, privateClean);
if (hasSwappedOutPss) {
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss);
} else {
- proto.write(MemInfoProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_KB, dirtySwap);
+ proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_KB, dirtySwap);
}
proto.end(token);
@@ -2530,26 +2537,26 @@ public final class ActivityThread extends ClientTransactionHandler {
long dalvikMax, long dalvikAllocated, long dalvikFree) {
if (!dumpSummaryOnly) {
- final long nhToken = proto.start(MemInfoProto.ProcessMemory.NATIVE_HEAP);
- dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "Native Heap",
+ final long nhToken = proto.start(MemInfoDumpProto.ProcessMemory.NATIVE_HEAP);
+ dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Native Heap",
memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
memInfo.nativePrivateClean, memInfo.hasSwappedOutPss,
memInfo.nativeSwappedOut, memInfo.nativeSwappedOutPss);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, nativeAllocated);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, nativeAllocated);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree);
proto.end(nhToken);
- final long dvToken = proto.start(MemInfoProto.ProcessMemory.DALVIK_HEAP);
- dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "Dalvik Heap",
+ final long dvToken = proto.start(MemInfoDumpProto.ProcessMemory.DALVIK_HEAP);
+ dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Dalvik Heap",
memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss,
memInfo.dalvikSwappedOut, memInfo.dalvikSwappedOutPss);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, dalvikMax);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, dalvikFree);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, dalvikMax);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, dalvikFree);
proto.end(dvToken);
int otherPss = memInfo.otherPss;
@@ -2573,7 +2580,7 @@ public final class ActivityThread extends ClientTransactionHandler {
if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
|| mySharedClean != 0 || myPrivateClean != 0
|| (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
- dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.OTHER_HEAPS,
+ dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.OTHER_HEAPS,
Debug.MemoryInfo.getOtherLabel(i),
myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
mySharedClean, myPrivateClean,
@@ -2590,21 +2597,23 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
- dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.UNKNOWN_HEAP, "Unknown",
+ dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.UNKNOWN_HEAP, "Unknown",
otherPss, otherSwappablePss,
otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
memInfo.hasSwappedOutPss, otherSwappedOut, otherSwappedOutPss);
- final long tToken = proto.start(MemInfoProto.ProcessMemory.TOTAL_HEAP);
- dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "TOTAL",
+ final long tToken = proto.start(MemInfoDumpProto.ProcessMemory.TOTAL_HEAP);
+ dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "TOTAL",
memInfo.getTotalPss(), memInfo.getTotalSwappablePss(),
memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
memInfo.hasSwappedOutPss, memInfo.getTotalSwappedOut(),
memInfo.getTotalSwappedOutPss());
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax + dalvikMax);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB,
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB,
+ nativeMax + dalvikMax);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB,
nativeAllocated + dalvikAllocated);
- proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree + dalvikFree);
+ proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB,
+ nativeFree + dalvikFree);
proto.end(tToken);
if (dumpDalvik) {
@@ -2622,7 +2631,7 @@ public final class ActivityThread extends ClientTransactionHandler {
if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
|| mySharedClean != 0 || myPrivateClean != 0
|| (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
- dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.DALVIK_DETAILS,
+ dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.DALVIK_DETAILS,
Debug.MemoryInfo.getOtherLabel(i),
myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
mySharedClean, myPrivateClean,
@@ -2632,24 +2641,26 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
- final long asToken = proto.start(MemInfoProto.ProcessMemory.APP_SUMMARY);
- proto.write(MemInfoProto.ProcessMemory.AppSummary.JAVA_HEAP_PSS_KB,
+ final long asToken = proto.start(MemInfoDumpProto.ProcessMemory.APP_SUMMARY);
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.JAVA_HEAP_PSS_KB,
memInfo.getSummaryJavaHeap());
- proto.write(MemInfoProto.ProcessMemory.AppSummary.NATIVE_HEAP_PSS_KB,
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.NATIVE_HEAP_PSS_KB,
memInfo.getSummaryNativeHeap());
- proto.write(MemInfoProto.ProcessMemory.AppSummary.CODE_PSS_KB, memInfo.getSummaryCode());
- proto.write(MemInfoProto.ProcessMemory.AppSummary.STACK_PSS_KB, memInfo.getSummaryStack());
- proto.write(MemInfoProto.ProcessMemory.AppSummary.GRAPHICS_PSS_KB,
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.CODE_PSS_KB,
+ memInfo.getSummaryCode());
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.STACK_PSS_KB,
+ memInfo.getSummaryStack());
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.GRAPHICS_PSS_KB,
memInfo.getSummaryGraphics());
- proto.write(MemInfoProto.ProcessMemory.AppSummary.PRIVATE_OTHER_PSS_KB,
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.PRIVATE_OTHER_PSS_KB,
memInfo.getSummaryPrivateOther());
- proto.write(MemInfoProto.ProcessMemory.AppSummary.SYSTEM_PSS_KB,
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.SYSTEM_PSS_KB,
memInfo.getSummarySystem());
if (memInfo.hasSwappedOutPss) {
- proto.write(MemInfoProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
memInfo.getSummaryTotalSwapPss());
} else {
- proto.write(MemInfoProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
+ proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
memInfo.getSummaryTotalSwap());
}
proto.end(asToken);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index ac301b3cc595..eaa23c6a9b61 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -614,7 +614,7 @@ interface IActivityManager {
int sendIntentSender(in IIntentSender target, in IBinder whitelistToken, int code,
in Intent intent, in String resolvedType, in IIntentReceiver finishedReceiver,
in String requiredPermission, in Bundle options);
-
+ boolean isBackgroundRestricted(in String packageName);
// Start of N MR1 transactions
void setVrThread(int tid);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 233e09d90f9b..13a6be557dae 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -360,6 +360,23 @@ public class Notification implements Parcelable
@Deprecated
public RemoteViews headsUpContentView;
+ private boolean mUsesStandardHeader;
+
+ private static final ArraySet<Integer> STANDARD_LAYOUTS = new ArraySet<>();
+ static {
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_base);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_base);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_picture);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_text);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_inbox);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_messaging);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_media);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_media);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_ambient_header);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_header);
+ STANDARD_LAYOUTS.add(R.layout.notification_template_material_ambient);
+ }
+
/**
* A large bitmap to be shown in the notification content area.
*
@@ -2534,6 +2551,8 @@ public class Notification implements Parcelable
}
parcel.writeInt(mGroupAlertBehavior);
+
+ // mUsesStandardHeader is not written because it should be recomputed in listeners
}
/**
@@ -4092,6 +4111,25 @@ public class Notification implements Parcelable
}
}
+ /**
+ * @hide
+ */
+ public boolean usesStandardHeader() {
+ if (mN.mUsesStandardHeader) {
+ return true;
+ }
+ if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) {
+ if (mN.contentView == null && mN.bigContentView == null) {
+ return true;
+ }
+ }
+ boolean contentViewUsesHeader = mN.contentView == null
+ || STANDARD_LAYOUTS.contains(mN.contentView.getLayoutId());
+ boolean bigContentViewUsesHeader = mN.bigContentView == null
+ || STANDARD_LAYOUTS.contains(mN.bigContentView.getLayoutId());
+ return contentViewUsesHeader && bigContentViewUsesHeader;
+ }
+
private void resetStandardTemplate(RemoteViews contentView) {
resetNotificationHeader(contentView);
resetContentMargins(contentView);
@@ -4123,6 +4161,7 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.time, View.GONE);
contentView.setImageViewIcon(R.id.profile_badge, null);
contentView.setViewVisibility(R.id.profile_badge, View.GONE);
+ mN.mUsesStandardHeader = false;
}
private void resetContentMargins(RemoteViews contentView) {
@@ -4444,6 +4483,7 @@ public class Notification implements Parcelable
bindProfileBadge(contentView);
}
bindExpandButton(contentView);
+ mN.mUsesStandardHeader = true;
}
private void bindExpandButton(RemoteViews contentView) {
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index a957aed8b806..cec3badd2e6c 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -1872,9 +1872,10 @@ public class IntentFilter implements Parcelable {
du.println(sb.toString());
}
}
- if (mPriority != 0 || mHasPartialTypes) {
+ if (mPriority != 0 || mOrder != 0 || mHasPartialTypes) {
sb.setLength(0);
sb.append(prefix); sb.append("mPriority="); sb.append(mPriority);
+ sb.append(", mOrder="); sb.append(mOrder);
sb.append(", mHasPartialTypes="); sb.append(mHasPartialTypes);
du.println(sb.toString());
}
@@ -1951,6 +1952,7 @@ public class IntentFilter implements Parcelable {
dest.writeInt(mHasPartialTypes ? 1 : 0);
dest.writeInt(getAutoVerify() ? 1 : 0);
dest.writeInt(mInstantAppVisibility);
+ dest.writeInt(mOrder);
}
/**
@@ -2020,6 +2022,7 @@ public class IntentFilter implements Parcelable {
mHasPartialTypes = source.readInt() > 0;
setAutoVerify(source.readInt() > 0);
setVisibilityToInstantApp(source.readInt());
+ mOrder = source.readInt();
}
private final boolean findMimeType(String type) {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 2420b639d678..5f10da1faeab 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3190,7 +3190,7 @@ public class PackageParser {
&& (perm.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) == 0
&& (perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) !=
PermissionInfo.PROTECTION_SIGNATURE) {
- outError[0] = "<permission> protectionLevel specifies a non-instnat flag but is "
+ outError[0] = "<permission> protectionLevel specifies a non-instant flag but is "
+ "not based on signature type";
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return false;
@@ -3641,7 +3641,9 @@ public class PackageParser {
// getting added to the wrong package.
final CachedComponentArgs cachedArgs = new CachedComponentArgs();
int type;
-
+ boolean hasActivityOrder = false;
+ boolean hasReceiverOrder = false;
+ boolean hasServiceOrder = false;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -3657,6 +3659,7 @@ public class PackageParser {
return false;
}
+ hasActivityOrder |= (a.order != 0);
owner.activities.add(a);
} else if (tagName.equals("receiver")) {
@@ -3667,6 +3670,7 @@ public class PackageParser {
return false;
}
+ hasReceiverOrder |= (a.order != 0);
owner.receivers.add(a);
} else if (tagName.equals("service")) {
@@ -3676,6 +3680,7 @@ public class PackageParser {
return false;
}
+ hasServiceOrder |= (s.order != 0);
owner.services.add(s);
} else if (tagName.equals("provider")) {
@@ -3694,6 +3699,7 @@ public class PackageParser {
return false;
}
+ hasActivityOrder |= (a.order != 0);
owner.activities.add(a);
} else if (parser.getName().equals("meta-data")) {
@@ -3827,6 +3833,15 @@ public class PackageParser {
}
}
+ if (hasActivityOrder) {
+ Collections.sort(owner.activities, (a1, a2) -> Integer.compare(a2.order, a1.order));
+ }
+ if (hasReceiverOrder) {
+ Collections.sort(owner.receivers, (r1, r2) -> Integer.compare(r2.order, r1.order));
+ }
+ if (hasServiceOrder) {
+ Collections.sort(owner.services, (s1, s2) -> Integer.compare(s2.order, s1.order));
+ }
// Must be ran after the entire {@link ApplicationInfo} has been fully processed and after
// every activity info has had a chance to set it from its attributes.
setMaxAspectRatio(owner);
@@ -4368,6 +4383,7 @@ public class PackageParser {
+ mArchiveSourcePath + " "
+ parser.getPositionDescription());
} else {
+ a.order = Math.max(intent.getOrder(), a.order);
a.intents.add(intent);
}
// adjust activity flags when we implicitly expose it via a browsable filter
@@ -4745,6 +4761,7 @@ public class PackageParser {
+ mArchiveSourcePath + " "
+ parser.getPositionDescription());
} else {
+ a.order = Math.max(intent.getOrder(), a.order);
a.intents.add(intent);
}
// adjust activity flags when we implicitly expose it via a browsable filter
@@ -4952,6 +4969,7 @@ public class PackageParser {
intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
}
+ outInfo.order = Math.max(intent.getOrder(), outInfo.order);
outInfo.intents.add(intent);
} else if (parser.getName().equals("meta-data")) {
@@ -5241,6 +5259,7 @@ public class PackageParser {
intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
}
+ s.order = Math.max(intent.getOrder(), s.order);
s.intents.add(intent);
} else if (parser.getName().equals("meta-data")) {
if ((s.metaData=parseMetaData(res, parser, s.metaData,
@@ -5466,6 +5485,10 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0);
outInfo.setPriority(priority);
+ int order = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_order, 0);
+ outInfo.setOrder(order);
+
TypedValue v = sa.peekValue(
com.android.internal.R.styleable.AndroidManifestIntentFilter_label);
if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
@@ -7053,6 +7076,8 @@ public class PackageParser {
public Bundle metaData;
public Package owner;
+ /** The order of this component in relation to its peers */
+ public int order;
ComponentName componentName;
String componentShortName;
@@ -7571,6 +7596,7 @@ public class PackageParser {
for (ActivityIntentInfo aii : intents) {
aii.activity = this;
+ order = Math.max(aii.getOrder(), order);
}
if (info.permission != null) {
@@ -7660,6 +7686,7 @@ public class PackageParser {
for (ServiceIntentInfo aii : intents) {
aii.service = this;
+ order = Math.max(aii.getOrder(), order);
}
if (info.permission != null) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 2baf539317e9..19b5c45f3a81 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -16,10 +16,11 @@
package android.content.res;
+import static android.content.ConfigurationProto.COLOR_MODE;
import static android.content.ConfigurationProto.DENSITY_DPI;
import static android.content.ConfigurationProto.FONT_SCALE;
import static android.content.ConfigurationProto.HARD_KEYBOARD_HIDDEN;
-import static android.content.ConfigurationProto.HDR_COLOR_MODE;
+import static android.content.ConfigurationProto.KEYBOARD;
import static android.content.ConfigurationProto.KEYBOARD_HIDDEN;
import static android.content.ConfigurationProto.LOCALES;
import static android.content.ConfigurationProto.MCC;
@@ -33,7 +34,6 @@ import static android.content.ConfigurationProto.SCREEN_WIDTH_DP;
import static android.content.ConfigurationProto.SMALLEST_SCREEN_WIDTH_DP;
import static android.content.ConfigurationProto.TOUCHSCREEN;
import static android.content.ConfigurationProto.UI_MODE;
-import static android.content.ConfigurationProto.WIDE_COLOR_GAMUT;
import static android.content.ConfigurationProto.WINDOW_CONFIGURATION;
import static android.content.ResourcesConfigurationProto.CONFIGURATION;
import static android.content.ResourcesConfigurationProto.SCREEN_HEIGHT_PX;
@@ -1095,11 +1095,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
protoOutputStream.write(MNC, mnc);
mLocaleList.writeToProto(protoOutputStream, LOCALES);
protoOutputStream.write(SCREEN_LAYOUT, screenLayout);
- protoOutputStream.write(HDR_COLOR_MODE,
- (colorMode & Configuration.COLOR_MODE_HDR_MASK) >> COLOR_MODE_HDR_SHIFT);
- protoOutputStream.write(WIDE_COLOR_GAMUT,
- colorMode & Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_MASK);
+ protoOutputStream.write(COLOR_MODE, colorMode);
protoOutputStream.write(TOUCHSCREEN, touchscreen);
+ protoOutputStream.write(KEYBOARD, keyboard);
protoOutputStream.write(KEYBOARD_HIDDEN, keyboardHidden);
protoOutputStream.write(HARD_KEYBOARD_HIDDEN, hardKeyboardHidden);
protoOutputStream.write(NAVIGATION, navigation);
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6b2059e1c84c..36d5615e6ac2 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -615,6 +615,7 @@ public final class DisplayManager {
* @hide
*/
@SystemApi
+ @TestApi
public Point getStableDisplaySize() {
return mGlobal.getStableDisplaySize();
}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 48f56847e88d..6d8831bccdba 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -19,6 +19,7 @@ package android.os;
import android.Manifest;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Application;
import android.content.Context;
import android.text.TextUtils;
@@ -287,6 +288,7 @@ public class Build {
* we are operating under, we bump the assumed resource platform version by 1.
* @hide
*/
+ @TestApi
public static final int RESOURCES_SDK_INT = SDK_INT + ACTIVE_CODENAMES.length;
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 02994079d6ec..569a0db768aa 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10516,8 +10516,11 @@ public final class Settings {
* entity_list_default use ":" as delimiter for values. Ex:
*
* <pre>
- * smart_selection_dark_launch (boolean)
- * smart_selection_enabled_for_edit_text (boolean)
+ * model_dark_launch_enabled (boolean)
+ * smart_selection_enabled (boolean)
+ * smart_text_share_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * smart_select_animation_enabled (boolean)
* suggest_selection_max_range_length (int)
* classify_text_max_range_length (int)
* generate_links_max_text_length (int)
@@ -10530,7 +10533,7 @@ public final class Settings {
* <p>
* Type: string
* @hide
- * see also android.view.textclassifier.TextClassifierConstants
+ * see also android.view.textclassifier.TextClassificationConstants
*/
public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants";
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index fbba8abff304..137e820805e2 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -17,6 +17,7 @@
package android.view;
import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.app.Notification;
import android.content.Context;
import android.content.res.Resources;
@@ -25,6 +26,7 @@ import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.util.ArraySet;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.RemoteViews;
@@ -53,6 +55,10 @@ public class NotificationHeaderView extends ViewGroup {
private ImageView mExpandButton;
private CachingIconView mIcon;
private View mProfileBadge;
+ private View mOverlayIcon;
+ private View mCameraIcon;
+ private View mMicIcon;
+ private View mAppOps;
private int mIconColor;
private int mOriginalNotificationColor;
private boolean mExpanded;
@@ -108,6 +114,10 @@ public class NotificationHeaderView extends ViewGroup {
mExpandButton = findViewById(com.android.internal.R.id.expand_button);
mIcon = findViewById(com.android.internal.R.id.icon);
mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
+ mCameraIcon = findViewById(com.android.internal.R.id.camera);
+ mMicIcon = findViewById(com.android.internal.R.id.mic);
+ mOverlayIcon = findViewById(com.android.internal.R.id.overlay);
+ mAppOps = findViewById(com.android.internal.R.id.app_ops);
}
@Override
@@ -198,6 +208,11 @@ public class NotificationHeaderView extends ViewGroup {
layoutRight = end - paddingEnd;
end = layoutLeft = layoutRight - child.getMeasuredWidth();
}
+ if (child == mAppOps) {
+ int paddingEnd = mContentEndMargin;
+ layoutRight = end - paddingEnd;
+ end = layoutLeft = layoutRight - child.getMeasuredWidth();
+ }
if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
int ltrLeft = layoutLeft;
layoutLeft = getWidth() - layoutRight;
@@ -289,6 +304,22 @@ public class NotificationHeaderView extends ViewGroup {
updateExpandButton();
}
+ /**
+ * Shows or hides 'app op in use' icons based on app usage.
+ */
+ public void showAppOpsIcons(ArraySet<Integer> appOps) {
+ if (mOverlayIcon == null || mCameraIcon == null || mMicIcon == null) {
+ return;
+ }
+
+ mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
+ ? View.VISIBLE : View.GONE);
+ mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
+ ? View.VISIBLE : View.GONE);
+ mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
+ ? View.VISIBLE : View.GONE);
+ }
+
private void updateExpandButton() {
int drawableId;
int contentDescriptionId;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f61b6528bd0e..e28522292ac3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2953,6 +2953,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* 1 PFLAG3_NO_REVEAL_ON_FOCUS
* 1 PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT
* 1 PFLAG3_SCREEN_READER_FOCUSABLE
+ * 1 PFLAG3_AGGREGATED_VISIBLE
+ * 1 PFLAG3_AUTOFILLID_EXPLICITLY_SET
+ * 1 available
* |-------|-------|-------|-------|
*/
@@ -3243,6 +3246,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private static final int PFLAG3_AGGREGATED_VISIBLE = 0x20000000;
+ /**
+ * Used to indicate that {@link #mAutofillId} was explicitly set through
+ * {@link #setAutofillId(AutofillId)}.
+ */
+ private static final int PFLAG3_AUTOFILLID_EXPLICITLY_SET = 0x40000000;
+
/* End of masks for mPrivateFlags3 */
/**
@@ -8205,16 +8214,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @throws IllegalArgumentException if the id is an autofill id associated with a virtual view.
*/
public void setAutofillId(@Nullable AutofillId id) {
+ // TODO(b/37566627): add unit / CTS test for all possible combinations below
if (android.view.autofill.Helper.sVerbose) {
Log.v(VIEW_LOG_TAG, "setAutofill(): from " + mAutofillId + " to " + id);
}
if (isAttachedToWindow()) {
throw new IllegalStateException("Cannot set autofill id when view is attached");
}
- if (id.isVirtual()) {
+ if (id != null && id.isVirtual()) {
throw new IllegalStateException("Cannot set autofill id assigned to virtual views");
}
+ if (id == null && (mPrivateFlags3 & PFLAG3_AUTOFILLID_EXPLICITLY_SET) == 0) {
+ // Ignore reset because it was never explicitly set before.
+ return;
+ }
mAutofillId = id;
+ if (id != null) {
+ mAutofillViewId = id.getViewId();
+ mPrivateFlags3 |= PFLAG3_AUTOFILLID_EXPLICITLY_SET;
+ } else {
+ mAutofillViewId = NO_ID;
+ mPrivateFlags3 &= ~PFLAG3_AUTOFILLID_EXPLICITLY_SET;
+ }
}
/**
@@ -18524,7 +18545,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Hence prevent the same autofill view id from being restored multiple times.
((BaseSavedState) state).mSavedData &= ~BaseSavedState.AUTOFILL_ID;
- mAutofillViewId = baseState.mAutofillViewId;
+ if ((mPrivateFlags3 & PFLAG3_AUTOFILLID_EXPLICITLY_SET) != 0) {
+ // Ignore when view already set it through setAutofillId();
+ if (android.view.autofill.Helper.sDebug) {
+ Log.d(VIEW_LOG_TAG, "onRestoreInstanceState(): not setting autofillId to "
+ + baseState.mAutofillViewId + " because view explicitly set it to "
+ + mAutofillId);
+ }
+ } else {
+ mAutofillViewId = baseState.mAutofillViewId;
+ mAutofillId = null; // will be set on demand by getAutofillId()
+ }
}
}
}
diff --git a/core/java/android/view/textclassifier/SystemTextClassifier.java b/core/java/android/view/textclassifier/SystemTextClassifier.java
index 1789edf1e876..2b335fb09c61 100644
--- a/core/java/android/view/textclassifier/SystemTextClassifier.java
+++ b/core/java/android/view/textclassifier/SystemTextClassifier.java
@@ -29,6 +29,8 @@ import android.service.textclassifier.ITextClassifierService;
import android.service.textclassifier.ITextLinksCallback;
import android.service.textclassifier.ITextSelectionCallback;
+import com.android.internal.util.Preconditions;
+
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -40,13 +42,16 @@ final class SystemTextClassifier implements TextClassifier {
private static final String LOG_TAG = "SystemTextClassifier";
private final ITextClassifierService mManagerService;
+ private final TextClassificationConstants mSettings;
private final TextClassifier mFallback;
private final String mPackageName;
- SystemTextClassifier(Context context) throws ServiceManager.ServiceNotFoundException {
+ SystemTextClassifier(Context context, TextClassificationConstants settings)
+ throws ServiceManager.ServiceNotFoundException {
mManagerService = ITextClassifierService.Stub.asInterface(
ServiceManager.getServiceOrThrow(Context.TEXT_CLASSIFICATION_SERVICE));
- mFallback = new TextClassifierImpl(context);
+ mSettings = Preconditions.checkNotNull(settings);
+ mFallback = new TextClassifierImpl(context, settings);
mPackageName = context.getPackageName();
}
@@ -108,6 +113,11 @@ final class SystemTextClassifier implements TextClassifier {
public TextLinks generateLinks(
@NonNull CharSequence text, @Nullable TextLinks.Options options) {
Utils.validate(text, false /* allowInMainThread */);
+
+ if (!mSettings.isSmartLinkifyEnabled()) {
+ return TextClassifier.NO_OP.generateLinks(text, options);
+ }
+
try {
if (options == null) {
options = new TextLinks.Options().setCallingPackageName(mPackageName);
diff --git a/core/java/android/view/textclassifier/TextClassifierConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index 397473be9d4b..32a7f376c4b1 100644
--- a/core/java/android/view/textclassifier/TextClassifierConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -30,11 +30,15 @@ import java.util.StringJoiner;
* This is encoded as a key=value list, separated by commas. Ex:
*
* <pre>
- * smart_selection_dark_launch (boolean)
- * smart_selection_enabled_for_edit_text (boolean)
+ * model_dark_launch_enabled (boolean)
+ * smart_selection_enabled (boolean)
+ * smart_text_share_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * smart_select_animation_enabled (boolean)
* suggest_selection_max_range_length (int)
* classify_text_max_range_length (int)
* generate_links_max_text_length (int)
+ * generate_links_log_sample_rate (int)
* entity_list_default (String[])
* entity_list_not_editable (String[])
* entity_list_editable (String[])
@@ -46,20 +50,24 @@ import java.util.StringJoiner;
*
* Example of setting the values for testing.
* adb shell settings put global text_classifier_constants \
- * smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true,\
+ * model_dark_launch_enabled=true,smart_selection_enabled=true,\
* entity_list_default=phone:address
* @hide
*/
-public final class TextClassifierConstants {
+public final class TextClassificationConstants {
- private static final String LOG_TAG = "TextClassifierConstants";
+ private static final String LOG_TAG = "TextClassificationConstants";
- private static final String SMART_SELECTION_DARK_LAUNCH =
- "smart_selection_dark_launch";
- private static final String SMART_SELECTION_ENABLED_FOR_EDIT_TEXT =
- "smart_selection_enabled_for_edit_text";
+ private static final String MODEL_DARK_LAUNCH_ENABLED =
+ "model_dark_launch_enabled";
+ private static final String SMART_SELECTION_ENABLED =
+ "smart_selection_enabled";
+ private static final String SMART_TEXT_SHARE_ENABLED =
+ "smart_text_share_enabled";
private static final String SMART_LINKIFY_ENABLED =
"smart_linkify_enabled";
+ private static final String SMART_SELECT_ANIMATION_ENABLED =
+ "smart_select_animation_enabled";
private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
"suggest_selection_max_range_length";
private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH =
@@ -75,9 +83,11 @@ public final class TextClassifierConstants {
private static final String ENTITY_LIST_EDITABLE =
"entity_list_editable";
- private static final boolean SMART_SELECTION_DARK_LAUNCH_DEFAULT = false;
- private static final boolean SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT = true;
+ private static final boolean MODEL_DARK_LAUNCH_ENABLED_DEFAULT = false;
+ private static final boolean SMART_SELECTION_ENABLED_DEFAULT = true;
+ private static final boolean SMART_TEXT_SHARE_ENABLED_DEFAULT = true;
private static final boolean SMART_LINKIFY_ENABLED_DEFAULT = true;
+ private static final boolean SMART_SELECT_ANIMATION_ENABLED_DEFAULT = true;
private static final int SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
@@ -92,12 +102,11 @@ public final class TextClassifierConstants {
.add(TextClassifier.TYPE_DATE_TIME)
.add(TextClassifier.TYPE_FLIGHT_NUMBER).toString();
- /** Default settings. */
- static final TextClassifierConstants DEFAULT = new TextClassifierConstants();
-
- private final boolean mDarkLaunch;
- private final boolean mSuggestSelectionEnabledForEditableText;
+ private final boolean mModelDarkLaunchEnabled;
+ private final boolean mSmartSelectionEnabled;
+ private final boolean mSmartTextShareEnabled;
private final boolean mSmartLinkifyEnabled;
+ private final boolean mSmartSelectionAnimationEnabled;
private final int mSuggestSelectionMaxRangeLength;
private final int mClassifyTextMaxRangeLength;
private final int mGenerateLinksMaxTextLength;
@@ -106,20 +115,7 @@ public final class TextClassifierConstants {
private final List<String> mEntityListNotEditable;
private final List<String> mEntityListEditable;
- private TextClassifierConstants() {
- mDarkLaunch = SMART_SELECTION_DARK_LAUNCH_DEFAULT;
- mSuggestSelectionEnabledForEditableText = SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT;
- mSmartLinkifyEnabled = SMART_LINKIFY_ENABLED_DEFAULT;
- mSuggestSelectionMaxRangeLength = SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT;
- mClassifyTextMaxRangeLength = CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT;
- mGenerateLinksMaxTextLength = GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT;
- mGenerateLinksLogSampleRate = GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT;
- mEntityListDefault = parseEntityList(ENTITY_LIST_DEFAULT_VALUE);
- mEntityListNotEditable = mEntityListDefault;
- mEntityListEditable = mEntityListDefault;
- }
-
- private TextClassifierConstants(@Nullable String settings) {
+ private TextClassificationConstants(@Nullable String settings) {
final KeyValueListParser parser = new KeyValueListParser(',');
try {
parser.setString(settings);
@@ -127,15 +123,21 @@ public final class TextClassifierConstants {
// Failed to parse the settings string, log this and move on with defaults.
Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
}
- mDarkLaunch = parser.getBoolean(
- SMART_SELECTION_DARK_LAUNCH,
- SMART_SELECTION_DARK_LAUNCH_DEFAULT);
- mSuggestSelectionEnabledForEditableText = parser.getBoolean(
- SMART_SELECTION_ENABLED_FOR_EDIT_TEXT,
- SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT);
+ mModelDarkLaunchEnabled = parser.getBoolean(
+ MODEL_DARK_LAUNCH_ENABLED,
+ MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
+ mSmartSelectionEnabled = parser.getBoolean(
+ SMART_SELECTION_ENABLED,
+ SMART_SELECTION_ENABLED_DEFAULT);
+ mSmartTextShareEnabled = parser.getBoolean(
+ SMART_TEXT_SHARE_ENABLED,
+ SMART_TEXT_SHARE_ENABLED_DEFAULT);
mSmartLinkifyEnabled = parser.getBoolean(
SMART_LINKIFY_ENABLED,
SMART_LINKIFY_ENABLED_DEFAULT);
+ mSmartSelectionAnimationEnabled = parser.getBoolean(
+ SMART_SELECT_ANIMATION_ENABLED,
+ SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
mSuggestSelectionMaxRangeLength = parser.getInt(
SUGGEST_SELECTION_MAX_RANGE_LENGTH,
SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
@@ -160,22 +162,30 @@ public final class TextClassifierConstants {
}
/** Load from a settings string. */
- public static TextClassifierConstants loadFromString(String settings) {
- return new TextClassifierConstants(settings);
+ public static TextClassificationConstants loadFromString(String settings) {
+ return new TextClassificationConstants(settings);
}
- public boolean isDarkLaunch() {
- return mDarkLaunch;
+ public boolean isModelDarkLaunchEnabled() {
+ return mModelDarkLaunchEnabled;
}
- public boolean isSuggestSelectionEnabledForEditableText() {
- return mSuggestSelectionEnabledForEditableText;
+ public boolean isSmartSelectionEnabled() {
+ return mSmartSelectionEnabled;
+ }
+
+ public boolean isSmartTextShareEnabled() {
+ return mSmartTextShareEnabled;
}
public boolean isSmartLinkifyEnabled() {
return mSmartLinkifyEnabled;
}
+ public boolean isSmartSelectionAnimationEnabled() {
+ return mSmartSelectionAnimationEnabled;
+ }
+
public int getSuggestSelectionMaxRangeLength() {
return mSuggestSelectionMaxRangeLength;
}
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 300aef2d172e..fea932cf2a50 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.annotation.SystemService;
import android.content.Context;
import android.os.ServiceManager;
+import android.provider.Settings;
import android.service.textclassifier.TextClassifierService;
import com.android.internal.util.Preconditions;
@@ -38,12 +39,15 @@ public final class TextClassificationManager {
private final Object mLock = new Object();
private final Context mContext;
+ private final TextClassificationConstants mSettings;
private TextClassifier mTextClassifier;
private TextClassifier mSystemTextClassifier;
/** @hide */
public TextClassificationManager(Context context) {
mContext = Preconditions.checkNotNull(context);
+ mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
+ context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
}
/**
@@ -56,14 +60,14 @@ public final class TextClassificationManager {
if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
try {
Log.d(LOG_TAG, "Initialized SystemTextClassifier");
- mSystemTextClassifier = new SystemTextClassifier(mContext);
+ mSystemTextClassifier = new SystemTextClassifier(mContext, mSettings);
} catch (ServiceManager.ServiceNotFoundException e) {
Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
}
}
if (mSystemTextClassifier == null) {
Log.d(LOG_TAG, "Using an in-process TextClassifier as the system default");
- mSystemTextClassifier = new TextClassifierImpl(mContext);
+ mSystemTextClassifier = new TextClassifierImpl(mContext, mSettings);
}
}
return mSystemTextClassifier;
@@ -78,7 +82,7 @@ public final class TextClassificationManager {
if (isSystemTextClassifierEnabled()) {
mTextClassifier = getSystemDefaultTextClassifier();
} else {
- mTextClassifier = new TextClassifierImpl(mContext);
+ mTextClassifier = new TextClassifierImpl(mContext, mSettings);
}
}
return mTextClassifier;
@@ -100,4 +104,17 @@ public final class TextClassificationManager {
return SYSTEM_TEXT_CLASSIFIER_ENABLED
&& TextClassifierService.getServiceComponentName(mContext) != null;
}
+
+ /** @hide */
+ public static TextClassificationConstants getSettings(Context context) {
+ Preconditions.checkNotNull(context);
+ final TextClassificationManager tcm =
+ context.getSystemService(TextClassificationManager.class);
+ if (tcm != null) {
+ return tcm.mSettings;
+ } else {
+ return TextClassificationConstants.loadFromString(Settings.Global.getString(
+ context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+ }
+ }
}
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index d52a30bcc018..0321bb6d62fa 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -329,14 +329,6 @@ public interface TextClassifier {
}
/**
- * Returns this TextClassifier's settings.
- * @hide
- */
- default TextClassifierConstants getSettings() {
- return TextClassifierConstants.DEFAULT;
- }
-
- /**
* Configuration object for specifying what entities to identify.
*
* Configs are initially based on a predefined preset, and can be modified from there.
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 5b7095b2f44f..41f1c69a47ed 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -34,7 +34,6 @@ import android.os.UserManager;
import android.provider.Browser;
import android.provider.CalendarContract;
import android.provider.ContactsContract;
-import android.provider.Settings;
import android.view.textclassifier.logging.DefaultLogger;
import android.view.textclassifier.logging.GenerateLinksLogger;
import android.view.textclassifier.logging.Logger;
@@ -99,13 +98,13 @@ public final class TextClassifierImpl implements TextClassifier {
@GuardedBy("mLoggerLock") // Do not access outside this lock.
private Logger mLogger; // Should never be null if mLoggerConfig.get() is not null.
- private TextClassifierConstants mSettings;
+ private final TextClassificationConstants mSettings;
- public TextClassifierImpl(Context context) {
+ public TextClassifierImpl(Context context, TextClassificationConstants settings) {
mContext = Preconditions.checkNotNull(context);
mFallback = TextClassifier.NO_OP;
- mGenerateLinksLogger = new GenerateLinksLogger(
- getSettings().getGenerateLinksLogSampleRate());
+ mSettings = Preconditions.checkNotNull(settings);
+ mGenerateLinksLogger = new GenerateLinksLogger(mSettings.getGenerateLinksLogSampleRate());
}
/** @inheritDoc */
@@ -117,7 +116,7 @@ public final class TextClassifierImpl implements TextClassifier {
try {
final int rangeLength = selectionEndIndex - selectionStartIndex;
if (text.length() > 0
- && rangeLength <= getSettings().getSuggestSelectionMaxRangeLength()) {
+ && rangeLength <= mSettings.getSuggestSelectionMaxRangeLength()) {
final LocaleList locales = (options == null) ? null : options.getDefaultLocales();
final String localesString = concatenateLocales(locales);
final Calendar refTime = Calendar.getInstance();
@@ -126,7 +125,7 @@ public final class TextClassifierImpl implements TextClassifier {
final String string = text.toString();
final int start;
final int end;
- if (getSettings().isDarkLaunch() && !darkLaunchAllowed) {
+ if (mSettings.isModelDarkLaunchEnabled() && !darkLaunchAllowed) {
start = selectionStartIndex;
end = selectionEndIndex;
} else {
@@ -179,7 +178,7 @@ public final class TextClassifierImpl implements TextClassifier {
Utils.validate(text, startIndex, endIndex, false /* allowInMainThread */);
try {
final int rangeLength = endIndex - startIndex;
- if (text.length() > 0 && rangeLength <= getSettings().getClassifyTextMaxRangeLength()) {
+ if (text.length() > 0 && rangeLength <= mSettings.getClassifyTextMaxRangeLength()) {
final String string = text.toString();
final LocaleList locales = (options == null) ? null : options.getDefaultLocales();
final String localesString = concatenateLocales(locales);
@@ -214,7 +213,7 @@ public final class TextClassifierImpl implements TextClassifier {
final String textString = text.toString();
final TextLinks.Builder builder = new TextLinks.Builder(textString);
- if (!getSettings().isSmartLinkifyEnabled()) {
+ if (!mSettings.isSmartLinkifyEnabled()) {
return builder.build();
}
@@ -226,7 +225,7 @@ public final class TextClassifierImpl implements TextClassifier {
options != null && options.getEntityConfig() != null
? options.getEntityConfig().resolveEntityListModifications(
getEntitiesForHints(options.getEntityConfig().getHints()))
- : getSettings().getEntityListDefault();
+ : mSettings.getEntityListDefault();
final TextClassifierImplNative nativeImpl =
getNative(defaultLocales);
final TextClassifierImplNative.AnnotatedSpan[] annotations =
@@ -268,7 +267,7 @@ public final class TextClassifierImpl implements TextClassifier {
/** @inheritDoc */
@Override
public int getMaxGenerateLinksTextLength() {
- return getSettings().getGenerateLinksMaxTextLength();
+ return mSettings.getGenerateLinksMaxTextLength();
}
private Collection<String> getEntitiesForHints(Collection<String> hints) {
@@ -278,11 +277,11 @@ public final class TextClassifierImpl implements TextClassifier {
// Use the default if there is no hint, or conflicting ones.
final boolean useDefault = editable == notEditable;
if (useDefault) {
- return getSettings().getEntityListDefault();
+ return mSettings.getEntityListDefault();
} else if (editable) {
- return getSettings().getEntityListEditable();
+ return mSettings.getEntityListEditable();
} else { // notEditable
- return getSettings().getEntityListNotEditable();
+ return mSettings.getEntityListNotEditable();
}
}
@@ -298,16 +297,6 @@ public final class TextClassifierImpl implements TextClassifier {
}
}
- /** @hide */
- @Override
- public TextClassifierConstants getSettings() {
- if (mSettings == null) {
- mSettings = TextClassifierConstants.loadFromString(Settings.Global.getString(
- mContext.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
- }
- return mSettings;
- }
-
private TextClassifierImplNative getNative(LocaleList localeList)
throws FileNotFoundException {
synchronized (mLock) {
diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java
index 84c000a379df..ed122a650e66 100644
--- a/core/java/android/webkit/URLUtil.java
+++ b/core/java/android/webkit/URLUtil.java
@@ -39,7 +39,7 @@ public final class URLUtil {
// "file:///android_res/drawable/bar.png". Use "drawable" to refer to
// "drawable-hdpi" directory as well.
static final String RESOURCE_BASE = "file:///android_res/";
- static final String FILE_BASE = "file://";
+ static final String FILE_BASE = "file:";
static final String PROXY_BASE = "file:///cookieless_proxy/";
static final String CONTENT_BASE = "content:";
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 2e7b2fd65d33..02f35ca0d4d7 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -107,6 +107,7 @@ import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextLinks;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView.Drawables;
@@ -4024,7 +4025,7 @@ public class Editor {
private void updateAssistMenuItems(Menu menu) {
clearAssistMenuItems(menu);
- if (!mTextView.isDeviceProvisioned()) {
+ if (!shouldEnableAssistMenuItems()) {
return;
}
final TextClassification textClassification =
@@ -4097,7 +4098,7 @@ public class Editor {
final TextClassification textClassification =
getSelectionActionModeHelper().getTextClassification();
- if (!mTextView.isDeviceProvisioned() || textClassification == null) {
+ if (!shouldEnableAssistMenuItems() || textClassification == null) {
// No textClassification result to handle the click. Eat the click.
return true;
}
@@ -4118,6 +4119,12 @@ public class Editor {
return true;
}
+ private boolean shouldEnableAssistMenuItems() {
+ return mTextView.isDeviceProvisioned()
+ && TextClassificationManager.getSettings(mTextView.getContext())
+ .isSmartTextShareEnabled();
+ }
+
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
getSelectionActionModeHelper().onSelectionAction(item.getItemId());
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 6ab09d6cbe74..12ab0ee7d56a 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -34,6 +34,8 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.ActionMode;
import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationConstants;
+import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextClassifier;
import android.view.textclassifier.TextLinks;
import android.view.textclassifier.TextSelection;
@@ -65,12 +67,10 @@ public final class SelectionActionModeHelper {
private static final String LOG_TAG = "SelectActionModeHelper";
- // TODO: Make this a configurable flag.
- private static final boolean SMART_SELECT_ANIMATION_ENABLED = true;
-
private final Editor mEditor;
private final TextView mTextView;
private final TextClassificationHelper mTextClassificationHelper;
+ private final TextClassificationConstants mTextClassificationSettings;
private TextClassification mTextClassification;
private AsyncTask mTextClassificationAsyncTask;
@@ -84,6 +84,7 @@ public final class SelectionActionModeHelper {
SelectionActionModeHelper(@NonNull Editor editor) {
mEditor = Preconditions.checkNotNull(editor);
mTextView = mEditor.getTextView();
+ mTextClassificationSettings = TextClassificationManager.getSettings(mTextView.getContext());
mTextClassificationHelper = new TextClassificationHelper(
mTextView.getContext(),
mTextView.getTextClassifier(),
@@ -91,7 +92,7 @@ public final class SelectionActionModeHelper {
0, 1, mTextView.getTextLocales());
mSelectionTracker = new SelectionTracker(mTextView);
- if (SMART_SELECT_ANIMATION_ENABLED) {
+ if (mTextClassificationSettings.isSmartSelectionAnimationEnabled()) {
mSmartSelectSprite = new SmartSelectSprite(mTextView.getContext(),
editor.getTextView().mHighlightColor, mTextView::invalidate);
} else {
@@ -104,9 +105,7 @@ public final class SelectionActionModeHelper {
*/
public void startSelectionActionModeAsync(boolean adjustSelection) {
// Check if the smart selection should run for editable text.
- adjustSelection &= !mTextView.isTextEditable()
- || mTextView.getTextClassifier().getSettings()
- .isSuggestSelectionEnabledForEditableText();
+ adjustSelection &= mTextClassificationSettings.isSmartSelectionEnabled();
mSelectionTracker.onOriginalSelection(
getText(mTextView),
@@ -249,7 +248,7 @@ public final class SelectionActionModeHelper {
|| mTextView.isTextEditable()
|| actionMode == Editor.TextActionMode.TEXT_LINK)) {
// Do not change the selection if TextClassifier should be dark launched.
- if (!mTextView.getTextClassifier().getSettings().isDarkLaunch()) {
+ if (!mTextClassificationSettings.isModelDarkLaunchEnabled()) {
Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
mTextView.invalidate();
}
@@ -450,7 +449,6 @@ public final class SelectionActionModeHelper {
selectionEnd = mTextView.getSelectionEnd();
}
mTextClassificationHelper.init(
- mTextView.getContext(),
mTextView.getTextClassifier(),
getText(mTextView),
selectionStart, selectionEnd,
@@ -882,7 +880,8 @@ public final class SelectionActionModeHelper {
private static final int TRIM_DELTA = 120; // characters
- private Context mContext;
+ private final Context mContext;
+ private final boolean mDarkLaunchEnabled;
private TextClassifier mTextClassifier;
/** The original TextView text. **/
@@ -917,13 +916,15 @@ public final class SelectionActionModeHelper {
TextClassificationHelper(Context context, TextClassifier textClassifier,
CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
- init(context, textClassifier, text, selectionStart, selectionEnd, locales);
+ init(textClassifier, text, selectionStart, selectionEnd, locales);
+ mContext = Preconditions.checkNotNull(context);
+ mDarkLaunchEnabled = TextClassificationManager.getSettings(mContext)
+ .isModelDarkLaunchEnabled();
}
@UiThread
- public void init(Context context, TextClassifier textClassifier,
- CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
- mContext = Preconditions.checkNotNull(context);
+ public void init(TextClassifier textClassifier, CharSequence text,
+ int selectionStart, int selectionEnd, LocaleList locales) {
mTextClassifier = Preconditions.checkNotNull(textClassifier);
mText = Preconditions.checkNotNull(text).toString();
mLastClassificationText = null; // invalidate.
@@ -956,7 +957,7 @@ public final class SelectionActionModeHelper {
mSelectionOptions.getDefaultLocales());
}
// Do not classify new selection boundaries if TextClassifier should be dark launched.
- if (!mTextClassifier.getSettings().isDarkLaunch()) {
+ if (!mDarkLaunchEnabled) {
mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
mSelectionEnd = Math.min(
mText.length(), selection.getSelectionEndIndex() + mTrimStart);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index fdb97560c848..242f4229f0ae 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -13348,7 +13348,7 @@ public class BatteryStatsImpl extends BatteryStats {
private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true;
private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
- private static final boolean DEFAULT_READ_BINARY_CPU_TIME = false;
+ private static final boolean DEFAULT_READ_BINARY_CPU_TIME = true;
private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000;
private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 10_000;
diff --git a/core/proto/android/content/configuration.proto b/core/proto/android/content/configuration.proto
index 834ecdee6a9f..74b47d2424b2 100644
--- a/core/proto/android/content/configuration.proto
+++ b/core/proto/android/content/configuration.proto
@@ -35,9 +35,9 @@ message ConfigurationProto {
optional uint32 mnc = 3;
repeated LocaleProto locales = 4;
optional uint32 screen_layout = 5;
- optional uint32 hdr_color_mode = 6;
- optional uint32 wide_color_gamut = 7;
- optional uint32 touchscreen = 8;
+ optional uint32 color_mode = 6;
+ optional uint32 touchscreen = 7;
+ optional uint32 keyboard = 8;
optional uint32 keyboard_hidden = 9;
optional uint32 hard_keyboard_hidden = 10;
optional uint32 navigation = 11;
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index be155977a1ea..7326829b584b 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -214,37 +214,37 @@ message IncidentProto {
(section).args = "procstats --proto"
];
- optional com.android.server.am.proto.ActivityStackSupervisorProto activities = 3012 [
+ optional com.android.server.am.proto.ActivityManagerServiceDumpActivitiesProto activities = 3012 [
(section).type = SECTION_DUMPSYS,
(section).args = "activity --proto activities"
];
- optional com.android.server.am.proto.BroadcastProto broadcasts = 3013 [
+ optional com.android.server.am.proto.ActivityManagerServiceDumpBroadcastsProto broadcasts = 3013 [
(section).type = SECTION_DUMPSYS,
(section).args = "activity --proto broadcasts"
];
- optional com.android.server.am.proto.ActiveServicesProto amservices = 3014 [
+ optional com.android.server.am.proto.ActivityManagerServiceDumpServicesProto amservices = 3014 [
(section).type = SECTION_DUMPSYS,
(section).args = "activity --proto service"
];
- optional com.android.server.am.proto.ProcessesProto amprocesses = 3015 [
+ optional com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto amprocesses = 3015 [
(section).type = SECTION_DUMPSYS,
(section).args = "activity --proto processes"
];
- optional com.android.server.AlarmManagerServiceProto alarm = 3016 [
+ optional com.android.server.AlarmManagerServiceDumpProto alarm = 3016 [
(section).type = SECTION_DUMPSYS,
(section).args = "alarm --proto"
];
- optional com.android.server.wm.proto.WindowManagerServiceProto window = 3017 [
+ optional com.android.server.wm.proto.WindowManagerServiceDumpProto window = 3017 [
(section).type = SECTION_DUMPSYS,
(section).args = "window --proto"
];
- optional com.android.server.am.proto.MemInfoProto meminfo = 3018 [
+ optional com.android.server.am.proto.MemInfoDumpProto meminfo = 3018 [
(section).type = SECTION_DUMPSYS,
(section).args = "meminfo -a --proto"
];
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 5042ede77d2d..3b9150f44abc 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -40,16 +40,22 @@ option java_multiple_files = true;
message ActivityManagerServiceProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
- optional ActivityStackSupervisorProto activities = 1;
+ optional ActivityManagerServiceDumpActivitiesProto activities = 1;
- optional BroadcastProto broadcasts = 2;
+ optional ActivityManagerServiceDumpBroadcastsProto broadcasts = 2;
- optional ActiveServicesProto services = 3;
+ optional ActivityManagerServiceDumpServicesProto services = 3;
- optional ProcessesProto processes = 4;
+ optional ActivityManagerServiceDumpProcessesProto processes = 4;
}
// "dumpsys activity --proto activities"
+message ActivityManagerServiceDumpActivitiesProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional ActivityStackSupervisorProto activity_stack_supervisor = 1;
+}
+
message ActivityStackSupervisorProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -121,7 +127,7 @@ message KeyguardControllerProto {
}
// "dumpsys activity --proto broadcasts"
-message BroadcastProto {
+message ActivityManagerServiceDumpBroadcastsProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
repeated ReceiverListProto receiver_list = 1;
@@ -202,7 +208,7 @@ message BroadcastQueueProto {
repeated BroadcastSummary historical_broadcasts_summary = 6;
}
-message MemInfoProto {
+message MemInfoDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional int64 uptime_duration_ms = 1;
@@ -406,6 +412,12 @@ message StickyBroadcastProto {
}
// "dumpsys activity --proto service"
+message ActivityManagerServiceDumpServicesProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional ActiveServicesProto active_services = 1;
+}
+
message ActiveServicesProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -585,7 +597,7 @@ message IntentBindRecordProto {
}
// TODO: "dumpsys activity --proto processes"
-message ProcessesProto {
+message ActivityManagerServiceDumpProcessesProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
repeated ProcessRecordProto procs = 1;
diff --git a/core/proto/android/server/alarmmanagerservice.proto b/core/proto/android/server/alarmmanagerservice.proto
index b288c1149731..53e3ba965120 100644
--- a/core/proto/android/server/alarmmanagerservice.proto
+++ b/core/proto/android/server/alarmmanagerservice.proto
@@ -28,7 +28,7 @@ package com.android.server;
option java_multiple_files = true;
// next ID: 43
-message AlarmManagerServiceProto {
+message AlarmManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional int64 current_time = 1;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index c11058a22107..7745ee45619e 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -32,7 +32,7 @@ package com.android.server.wm.proto;
option java_multiple_files = true;
-message WindowManagerServiceProto {
+message WindowManagerServiceDumpProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional WindowManagerPolicyProto policy = 1;
diff --git a/core/proto/android/server/windowmanagertrace.proto b/core/proto/android/server/windowmanagertrace.proto
index d96953ee9ded..96a90bfe63da 100644
--- a/core/proto/android/server/windowmanagertrace.proto
+++ b/core/proto/android/server/windowmanagertrace.proto
@@ -48,5 +48,5 @@ message WindowManagerTraceProto {
/* where the trace originated */
optional string where = 2;
- optional WindowManagerServiceProto window_manager_service = 3;
+ optional WindowManagerServiceDumpProto window_manager_service = 3;
}
diff --git a/core/res/res/drawable/ic_alert_window_layer.xml b/core/res/res/drawable/ic_alert_window_layer.xml
new file mode 100644
index 000000000000..15931b807918
--- /dev/null
+++ b/core/res/res/drawable/ic_alert_window_layer.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="16dp"
+ android:height="16dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M11.99,18.54l-7.37,-5.73L3,14.07l9,7 9,-7 -1.63,-1.27 -7.38,5.74zM12,16l7.36,-5.73L21,9l-9,-7 -9,7 1.63,1.27L12,16z"/>
+</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_camera.xml b/core/res/res/drawable/ic_camera.xml
new file mode 100644
index 000000000000..2921a689ef8a
--- /dev/null
+++ b/core/res/res/drawable/ic_camera.xml
@@ -0,0 +1,27 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="16dp"
+ android:height="16dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"
+ android:fillColor="#FFFFFF"/>
+</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_mic.xml b/core/res/res/drawable/ic_mic.xml
new file mode 100644
index 000000000000..3212330278aa
--- /dev/null
+++ b/core/res/res/drawable/ic_mic.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="16dp"
+ android:height="16dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"
+ android:fillColor="#FFFFFF"/>
+</vector> \ No newline at end of file
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 20bdf3fe8fa3..c03cf51d6bca 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -14,7 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-
+<!-- extends ViewGroup -->
<NotificationHeaderView
xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="@style/Theme.Material.Notification"
@@ -126,5 +126,42 @@
android:visibility="gone"
android:contentDescription="@string/notification_work_profile_content_description"
/>
+
+ <LinearLayout
+ android:id="@+id/app_ops"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="horizontal" >
+ <ImageButton
+ android:id="@+id/camera"
+ android:layout_width="?attr/notificationHeaderIconSize"
+ android:layout_height="?attr/notificationHeaderIconSize"
+ android:src="@drawable/ic_camera"
+ android:tint="@color/notification_secondary_text_color_light"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:layout_marginStart="6dp"
+ android:visibility="gone"
+ />
+ <ImageButton
+ android:id="@+id/mic"
+ android:layout_width="?attr/notificationHeaderIconSize"
+ android:layout_height="?attr/notificationHeaderIconSize"
+ android:src="@drawable/ic_mic"
+ android:tint="@color/notification_secondary_text_color_light"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:layout_marginStart="4dp"
+ android:visibility="gone"
+ />
+ <ImageButton
+ android:id="@+id/overlay"
+ android:layout_width="?attr/notificationHeaderIconSize"
+ android:layout_height="?attr/notificationHeaderIconSize"
+ android:src="@drawable/ic_alert_window_layer"
+ android:tint="@color/notification_secondary_text_color_light"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:layout_marginStart="4dp"
+ android:visibility="gone"
+ />
+ </LinearLayout>
</NotificationHeaderView>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index 4f0c0fbc4835..265eaaf39713 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -27,6 +27,9 @@
<dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
<dimen name="preference_widget_width">72dp</dimen>
+ <!-- Height of the status bar -->
+ <dimen name="status_bar_height">@dimen/status_bar_height_landscape</dimen>
+
<!-- Default height of an action bar. -->
<dimen name="action_bar_default_height">40dip</dimen>
<!-- Vertical padding around action bar icons. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index cfb5784666b9..c4fa190b228d 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2348,6 +2348,16 @@
<attr name="logo" />
<attr name="priority" />
<attr name="autoVerify" />
+ <!-- Within an application, multiple intent filters may match a particular
+ intent. This allows the app author to specify the order filters should
+ be considered. We don't want to use priority because that is global
+ across applications.
+ <p>Only use if you really need to forcibly set the order in which
+ filters are evaluated. It is preferred to target an activity with a
+ directed intent instead.
+ <p>The value is a single integer, with higher numbers considered to
+ be better. If not specified, the default order is 0. -->
+ <attr name="order" />
</declare-styleable>
<!-- Attributes that can be supplied in an AndroidManifest.xml
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 291826025cc1..7ff96fa7def2 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -32,7 +32,11 @@
<dimen name="toast_y_offset">24dp</dimen>
<!-- Height of the status bar -->
- <dimen name="status_bar_height">24dp</dimen>
+ <dimen name="status_bar_height">@dimen/status_bar_height_portrait</dimen>
+ <!-- Height of the status bar in portrait -->
+ <dimen name="status_bar_height_portrait">24dp</dimen>
+ <!-- Height of the status bar in landscape -->
+ <dimen name="status_bar_height_landscape">@dimen/status_bar_height_portrait</dimen>
<!-- Height of area above QQS where battery/time go -->
<dimen name="quick_qs_offset_height">48dp</dimen>
<!-- Total height of QQS (quick_qs_offset_height + 128) -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1babd707c781..3b96861e45fc 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -218,6 +218,10 @@
<java-symbol type="id" name="selection_end_handle" />
<java-symbol type="id" name="insertion_handle" />
<java-symbol type="id" name="accessibilityActionClickOnClickableSpan" />
+ <java-symbol type="id" name="camera" />
+ <java-symbol type="id" name="mic" />
+ <java-symbol type="id" name="overlay" />
+ <java-symbol type="id" name="app_ops" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -1389,6 +1393,9 @@
<java-symbol type="drawable" name="stat_notify_mmcc_indication_icn" />
<java-symbol type="drawable" name="autofilled_highlight"/>
+ <java-symbol type="drawable" name="ic_camera" />
+ <java-symbol type="drawable" name="ic_mic" />
+ <java-symbol type="drawable" name="ic_alert_window_layer" />
<java-symbol type="drawable" name="ic_account_circle" />
<java-symbol type="color" name="user_icon_1" />
@@ -3238,6 +3245,9 @@
<java-symbol type="string" name="keyguard_accessibility_sim_puk_unlock" />
<java-symbol type="string" name="keyguard_accessibility_password_unlock" />
+ <java-symbol type="dimen" name="status_bar_height_portrait" />
+ <java-symbol type="dimen" name="status_bar_height_landscape" />
+
<java-symbol type="string" name="global_action_logout" />
<java-symbol type="string" name="config_mainBuiltInDisplayCutout" />
<java-symbol type="drawable" name="messaging_user" />
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
new file mode 100644
index 000000000000..7f16359ad269
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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 android.view.textclassifier;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TextClassificationConstantsTest {
+
+ @Test
+ public void testLoadFromString() {
+ final String s = "model_dark_launch_enabled=true,"
+ + "smart_selection_enabled=true,"
+ + "smart_text_share_enabled=true,"
+ + "smart_linkify_enabled=true,"
+ + "smart_select_animation_enabled=true,"
+ + "suggest_selection_max_range_length=10,"
+ + "classify_text_max_range_length=11,"
+ + "generate_links_max_text_length=12,"
+ + "generate_links_log_sample_rate=13";
+ final TextClassificationConstants constants =
+ TextClassificationConstants.loadFromString(s);
+ assertTrue("model_dark_launch_enabled", constants.isModelDarkLaunchEnabled());
+ assertTrue("smart_selection_enabled", constants.isSmartSelectionEnabled());
+ assertTrue("smart_text_share_enabled", constants.isSmartTextShareEnabled());
+ assertTrue("smart_linkify_enabled", constants.isSmartLinkifyEnabled());
+ assertTrue("smart_select_animation_enabled", constants.isSmartSelectionAnimationEnabled());
+ assertEquals("suggest_selection_max_range_length",
+ 10, constants.getSuggestSelectionMaxRangeLength());
+ assertEquals("classify_text_max_range_length",
+ 11, constants.getClassifyTextMaxRangeLength());
+ assertEquals("generate_links_max_text_length",
+ 12, constants.getGenerateLinksMaxTextLength());
+ assertEquals("generate_links_log_sample_rate",
+ 13, constants.getGenerateLinksLogSampleRate());
+ }
+
+ @Test
+ public void testLoadFromString_differentValues() {
+ final String s = "model_dark_launch_enabled=false,"
+ + "smart_selection_enabled=false,"
+ + "smart_text_share_enabled=false,"
+ + "smart_linkify_enabled=false,"
+ + "smart_select_animation_enabled=false,"
+ + "suggest_selection_max_range_length=8,"
+ + "classify_text_max_range_length=7,"
+ + "generate_links_max_text_length=6,"
+ + "generate_links_log_sample_rate=5";
+ final TextClassificationConstants constants =
+ TextClassificationConstants.loadFromString(s);
+ assertFalse("model_dark_launch_enabled", constants.isModelDarkLaunchEnabled());
+ assertFalse("smart_selection_enabled", constants.isSmartSelectionEnabled());
+ assertFalse("smart_text_share_enabled", constants.isSmartTextShareEnabled());
+ assertFalse("smart_linkify_enabled", constants.isSmartLinkifyEnabled());
+ assertFalse("smart_select_animation_enabled",
+ constants.isSmartSelectionAnimationEnabled());
+ assertEquals("suggest_selection_max_range_length",
+ 8, constants.getSuggestSelectionMaxRangeLength());
+ assertEquals("classify_text_max_range_length",
+ 7, constants.getClassifyTextMaxRangeLength());
+ assertEquals("generate_links_max_text_length",
+ 6, constants.getGenerateLinksMaxTextLength());
+ assertEquals("generate_links_log_sample_rate",
+ 5, constants.getGenerateLinksLogSampleRate());
+ }
+
+ @Test
+ public void testEntityListParsing() {
+ final TextClassificationConstants constants = TextClassificationConstants.loadFromString(
+ "entity_list_default=phone,"
+ + "entity_list_not_editable=address:flight,"
+ + "entity_list_editable=date:datetime");
+ assertEquals(1, constants.getEntityListDefault().size());
+ assertEquals("phone", constants.getEntityListDefault().get(0));
+ assertEquals(2, constants.getEntityListNotEditable().size());
+ assertEquals("address", constants.getEntityListNotEditable().get(0));
+ assertEquals("flight", constants.getEntityListNotEditable().get(1));
+ assertEquals(2, constants.getEntityListEditable().size());
+ assertEquals("date", constants.getEntityListEditable().get(0));
+ assertEquals("datetime", constants.getEntityListEditable().get(1));
+ }
+}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierConstantsTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierConstantsTest.java
deleted file mode 100644
index 984eede55684..000000000000
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierConstantsTest.java
+++ /dev/null
@@ -1,46 +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 android.view.textclassifier;
-
-import static org.junit.Assert.assertEquals;
-
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TextClassifierConstantsTest {
-
- @Test
- public void testEntityListParsing() {
- final TextClassifierConstants constants = TextClassifierConstants.loadFromString(
- "entity_list_default=phone,"
- + "entity_list_not_editable=address:flight,"
- + "entity_list_editable=date:datetime");
- assertEquals(1, constants.getEntityListDefault().size());
- assertEquals("phone", constants.getEntityListDefault().get(0));
- assertEquals(2, constants.getEntityListNotEditable().size());
- assertEquals("address", constants.getEntityListNotEditable().get(0));
- assertEquals("flight", constants.getEntityListNotEditable().get(1));
- assertEquals(2, constants.getEntityListEditable().size());
- assertEquals("date", constants.getEntityListEditable().get(0));
- assertEquals("datetime", constants.getEntityListEditable().get(1));
- }
-}
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 209ec42dfb0b..c0468dc920ec 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -40,7 +40,7 @@ import java.util.ArrayList;
* <p>
* For ways of retrieving {@link Ringtone} objects or to show a ringtone
* picker, see {@link RingtoneManager}.
- *
+ *
* @see RingtoneManager
*/
public class Ringtone {
@@ -97,7 +97,7 @@ public class Ringtone {
/**
* Sets the stream type where this ringtone will be played.
- *
+ *
* @param streamType The stream, see {@link AudioManager}.
* @deprecated use {@link #setAudioAttributes(AudioAttributes)}
*/
@@ -111,7 +111,7 @@ public class Ringtone {
/**
* Gets the stream type where this ringtone will be played.
- *
+ *
* @return The stream type, see {@link AudioManager}.
* @deprecated use of stream types is deprecated, see
* {@link #setAudioAttributes(AudioAttributes)}
@@ -146,9 +146,8 @@ public class Ringtone {
}
/**
- * @hide
* Sets the player to be looping or non-looping.
- * @param looping whether to loop or not
+ * @param looping whether to loop or not.
*/
public void setLooping(boolean looping) {
synchronized (mPlaybackSettingsLock) {
@@ -158,7 +157,16 @@ public class Ringtone {
}
/**
- * @hide
+ * Returns whether the looping mode was enabled on this player.
+ * @return true if this player loops when playing.
+ */
+ public boolean isLooping() {
+ synchronized (mPlaybackSettingsLock) {
+ return mIsLooping;
+ }
+ }
+
+ /**
* Sets the volume on this player.
* @param volume a raw scalar in range 0.0 to 1.0, where 0.0 mutes this player, and 1.0
* corresponds to no attenuation being applied.
@@ -173,6 +181,16 @@ public class Ringtone {
}
/**
+ * Returns the volume scalar set on this player.
+ * @return a value between 0.0f and 1.0f.
+ */
+ public float getVolume() {
+ synchronized (mPlaybackSettingsLock) {
+ return mVolume;
+ }
+ }
+
+ /**
* Must be called synchronized on mPlaybackSettingsLock
*/
private void applyPlaybackProperties_sync() {
@@ -194,8 +212,8 @@ public class Ringtone {
/**
* Returns a human-presentable title for ringtone. Looks in media
* content provider. If not in either, uses the filename
- *
- * @param context A context used for querying.
+ *
+ * @param context A context used for querying.
*/
public String getTitle(Context context) {
if (mTitle != null) return mTitle;
@@ -265,12 +283,11 @@ public class Ringtone {
if (title == null) {
title = context.getString(com.android.internal.R.string.ringtone_unknown);
-
if (title == null) {
title = "";
}
}
-
+
return title;
}
@@ -395,7 +412,7 @@ public class Ringtone {
/**
* Whether this ringtone is currently playing.
- *
+ *
* @return True if playing, false otherwise.
*/
public boolean isPlaying() {
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 58d5db32a7e3..a75b147a4901 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -876,47 +876,53 @@
<!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
<string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
- <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
- <string name="power_remaining_duration_only">About <xliff:g id="time">%1$s</xliff:g> left</string>
- <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
- <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">%1$s</xliff:g> left based on your usage</string>
- <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
- <string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until fully charged</string>
-
- <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
- <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string>
-
- <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount -->
- <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string>
- <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount with the percentage -->
- <string name="power_remaining_less_than_duration"><xliff:g id="level">%1$s</xliff:g> - Less than <xliff:g id="threshold">%2$s</xliff:g> remaining</string>
-
- <!-- Used to let users know that they have more than some amount of battery life remaining with percentage. ex: 75% - more than 1 day remaining [CHAR LIMIT = 80] -->
- <string name="power_remaining_more_than_subtext"><xliff:g id="level">%1$s</xliff:g>more than <xliff:g id="time_remaining">%2$s</xliff:g> remaining</string>
- <!-- Used to let users know that they have more than some amount of battery life remaining. ex: more than 1 day remaining [CHAR LIMIT = 40] -->
- <string name="power_remaining_only_more_than_subtext">more than <xliff:g id="time_remaining">%1$s</xliff:g> remaining</string>
-
- <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
- <string name="power_remaining_duration_only_shutdown_imminent" product="default">phone may shutdown soon</string>
- <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
- <string name="power_remaining_duration_only_shutdown_imminent" product="tablet">tablet may shutdown soon</string>
- <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
- <string name="power_remaining_duration_only_shutdown_imminent" product="device">device may shutdown soon</string>
-
- <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
- <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g> - about <xliff:g id="time">%2$s</xliff:g> left</string>
- <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
- <string name="power_discharging_duration_enhanced"><xliff:g id="level">%1$s</xliff:g> - about <xliff:g id="time">%2$s</xliff:g> left based on your usage</string>
-
- <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
- <string name="power_remaining_duration_shutdown_imminent" product="default"><xliff:g id="level">%1$s</xliff:g> - phone may shutdown soon</string>
- <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
- <string name="power_remaining_duration_shutdown_imminent" product="tablet"><xliff:g id="level">%1$s</xliff:g> - tablet may shutdown soon</string>
- <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
- <string name="power_remaining_duration_shutdown_imminent" product="device"><xliff:g id="level">%1$s</xliff:g> - device may shutdown soon</string>
+ <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
+ <string name="power_remaining_duration_only">About <xliff:g id="time">%1$s</xliff:g> left</string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
+ <string name="power_discharging_duration">About <xliff:g id="time">%1$s</xliff:g> left (<xliff:g id="level">%2$s</xliff:g>)</string>
+ <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
+ <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">%1$s</xliff:g> left based on your usage</string>
+ <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
+ <string name="power_discharging_duration_enhanced">About <xliff:g id="time">%1$s</xliff:g> left based on your usage (<xliff:g id="level">%2$s</xliff:g>)</string>
+ <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
+ <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string>
+
+ <!-- [CHAR_LIMIT=100] Label for enhanced estimated time that phone will run out of battery -->
+ <string name="power_discharge_by_enhanced">Will last until about about <xliff:g id="time">%1$s</xliff:g> based on your usage (<xliff:g id="level">%2$s</xliff:g>)</string>
+ <!-- [CHAR_LIMIT=100] Label for enhanced estimated time that phone will run out of battery with no percentage -->
+ <string name="power_discharge_by_only_enhanced">Will last until about about <xliff:g id="time">%1$s</xliff:g> based on your usage</string>
+ <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
+ <string name="power_discharge_by">Will last until about about <xliff:g id="time">%1$s</xliff:g> (<xliff:g id="level">%2$s</xliff:g>)</string>
+ <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
+ <string name="power_discharge_by_only">Will last until about about <xliff:g id="time">%1$s</xliff:g></string>
+
+ <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount -->
+ <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string>
+ <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount with the percentage -->
+ <string name="power_remaining_less_than_duration">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string>
+
+ <!-- Used to let users know that they have more than some amount of battery life remaining with percentage. ex: 75% - more than 1 day remaining [CHAR LIMIT = 80] -->
+ <string name="power_remaining_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string>
+ <!-- Used to let users know that they have more than some amount of battery life remaining. ex: more than 1 day remaining [CHAR LIMIT = 40] -->
+ <string name="power_remaining_only_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining</string>
+
+ <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
+ <string name="power_remaining_duration_only_shutdown_imminent" product="default">Phone may shutdown soon</string>
+ <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
+ <string name="power_remaining_duration_only_shutdown_imminent" product="tablet">Tablet may shutdown soon</string>
+ <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
+ <string name="power_remaining_duration_only_shutdown_imminent" product="device">Device may shutdown soon</string>
+ <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
+ <string name="power_remaining_duration_shutdown_imminent" product="default">Phone may shutdown soon (<xliff:g id="level">%1$s</xliff:g>)</string>
+ <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
+ <string name="power_remaining_duration_shutdown_imminent" product="tablet">Tablet may shutdown soon (<xliff:g id="level">%1$s</xliff:g>)</string>
+ <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
+ <string name="power_remaining_duration_shutdown_imminent" product="device">Device may shutdown soon (<xliff:g id="level">%1$s</xliff:g>)</string>
<!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
<string name="power_charging"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="state">%2$s</xliff:g></string>
+ <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
+ <string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until fully charged</string>
<!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
<string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until fully charged</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
index 346ca66bcb13..8b3da3944088 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
@@ -17,22 +17,30 @@
package com.android.settingslib.utils;
import android.content.Context;
+import android.icu.text.DateFormat;
import android.icu.text.MeasureFormat;
import android.icu.text.MeasureFormat.FormatWidth;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.support.annotation.Nullable;
import android.text.TextUtils;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.R;
-import com.android.settingslib.utils.StringUtil;
+import java.time.Clock;
+import java.time.Instant;
+import java.util.Calendar;
+import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
/** Utility class for keeping power related strings consistent**/
public class PowerUtil {
+
private static final long SEVEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(7);
private static final long FIFTEEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(15);
private static final long ONE_DAY_MILLIS = TimeUnit.DAYS.toMillis(1);
+ private static final long TWO_DAYS_MILLIS = TimeUnit.DAYS.toMillis(2);
+ private static final long ONE_HOUR_MILLIS = TimeUnit.HOURS.toMillis(1);
/**
* This method produces the text used in various places throughout the system to describe the
@@ -57,11 +65,15 @@ public class PowerUtil {
FIFTEEN_MINUTES_MILLIS,
false /* withSeconds */);
return getUnderFifteenString(context, timeString, percentageString);
+ } else if (drainTimeMs >= TWO_DAYS_MILLIS) {
+ // just say more than two day if over 48 hours
+ return getMoreThanTwoDaysString(context, percentageString);
} else if (drainTimeMs >= ONE_DAY_MILLIS) {
- // just say more than one day if over 24 hours
- return getMoreThanOneDayString(context, percentageString);
+ // show remaining days & hours if more than a day
+ return getMoreThanOneDayString(context, drainTimeMs,
+ percentageString, basedOnUsage);
} else {
- // show a regular time remaining string
+ // show the time of day we think you'll run out
return getRegularTimeRemainingString(context, drainTimeMs,
percentageString, basedOnUsage);
}
@@ -83,44 +95,69 @@ public class PowerUtil {
? context.getString(R.string.power_remaining_less_than_duration_only, timeString)
: context.getString(
R.string.power_remaining_less_than_duration,
- percentageString,
- timeString);
+ timeString,
+ percentageString);
+
+ }
+ private static String getMoreThanOneDayString(Context context, long drainTimeMs,
+ String percentageString, boolean basedOnUsage) {
+ final long roundedTimeMs = roundToNearestThreshold(drainTimeMs, ONE_HOUR_MILLIS);
+ CharSequence timeString = StringUtil.formatElapsedTime(context,
+ roundedTimeMs,
+ false /* withSeconds */);
+
+ if (TextUtils.isEmpty(percentageString)) {
+ int id = basedOnUsage
+ ? R.string.power_remaining_duration_only_enhanced
+ : R.string.power_remaining_duration_only;
+ return context.getString(id, timeString);
+ } else {
+ int id = basedOnUsage
+ ? R.string.power_discharging_duration_enhanced
+ : R.string.power_discharging_duration;
+ return context.getString(id, timeString, percentageString);
+ }
}
- private static String getMoreThanOneDayString(Context context, String percentageString) {
+ private static String getMoreThanTwoDaysString(Context context, String percentageString) {
final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);
final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);
- final Measure daysMeasure = new Measure(1, MeasureUnit.DAY);
+ final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);
return TextUtils.isEmpty(percentageString)
? context.getString(R.string.power_remaining_only_more_than_subtext,
frmt.formatMeasures(daysMeasure))
: context.getString(
R.string.power_remaining_more_than_subtext,
- percentageString,
- frmt.formatMeasures(daysMeasure));
+ frmt.formatMeasures(daysMeasure),
+ percentageString);
}
private static String getRegularTimeRemainingString(Context context, long drainTimeMs,
String percentageString, boolean basedOnUsage) {
- // round to the nearest 15 min to not appear oversly precise
- final long roundedTimeMs = roundToNearestThreshold(drainTimeMs,
- FIFTEEN_MINUTES_MILLIS);
- CharSequence timeString = StringUtil.formatElapsedTime(context,
- roundedTimeMs,
- false /* withSeconds */);
+ // Get the time of day we think device will die rounded to the nearest 15 min.
+ final long roundedTimeOfDayMs =
+ roundToNearestThreshold(
+ System.currentTimeMillis() + drainTimeMs,
+ FIFTEEN_MINUTES_MILLIS);
+
+ // convert the time to a properly formatted string.
+ DateFormat fmt = DateFormat.getTimeInstance(DateFormat.SHORT);
+ Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs));
+ CharSequence timeString = fmt.format(date);
+
if (TextUtils.isEmpty(percentageString)) {
int id = basedOnUsage
- ? R.string.power_remaining_duration_only_enhanced
- : R.string.power_remaining_duration_only;
+ ? R.string.power_discharge_by_only_enhanced
+ : R.string.power_discharge_by_only;
return context.getString(id, timeString);
} else {
int id = basedOnUsage
- ? R.string.power_discharging_duration_enhanced
- : R.string.power_discharging_duration;
- return context.getString(id, percentageString, timeString);
+ ? R.string.power_discharge_by_enhanced
+ : R.string.power_discharge_by;
+ return context.getString(id, timeString, percentageString);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
index 45fdd7860836..68be2b4041b1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
@@ -33,74 +33,74 @@ import java.util.Locale;
/** Utility class for generally useful string methods **/
public class StringUtil {
- public static final int SECONDS_PER_MINUTE = 60;
- public static final int SECONDS_PER_HOUR = 60 * 60;
- public static final int SECONDS_PER_DAY = 24 * 60 * 60;
+ public static final int SECONDS_PER_MINUTE = 60;
+ public static final int SECONDS_PER_HOUR = 60 * 60;
+ public static final int SECONDS_PER_DAY = 24 * 60 * 60;
- /**
- * Returns elapsed time for the given millis, in the following format:
- * 2d 5h 40m 29s
- * @param context the application context
- * @param millis the elapsed time in milli seconds
- * @param withSeconds include seconds?
- * @return the formatted elapsed time
- */
- public static CharSequence formatElapsedTime(Context context, double millis,
- boolean withSeconds) {
- SpannableStringBuilder sb = new SpannableStringBuilder();
- int seconds = (int) Math.floor(millis / 1000);
- if (!withSeconds) {
- // Round up.
- seconds += 30;
- }
+ /**
+ * Returns elapsed time for the given millis, in the following format:
+ * 2d 5h 40m 29s
+ * @param context the application context
+ * @param millis the elapsed time in milli seconds
+ * @param withSeconds include seconds?
+ * @return the formatted elapsed time
+ */
+ public static CharSequence formatElapsedTime(Context context, double millis,
+ boolean withSeconds) {
+ SpannableStringBuilder sb = new SpannableStringBuilder();
+ int seconds = (int) Math.floor(millis / 1000);
+ if (!withSeconds) {
+ // Round up.
+ seconds += 30;
+ }
- int days = 0, hours = 0, minutes = 0;
- if (seconds >= SECONDS_PER_DAY) {
- days = seconds / SECONDS_PER_DAY;
- seconds -= days * SECONDS_PER_DAY;
- }
- if (seconds >= SECONDS_PER_HOUR) {
- hours = seconds / SECONDS_PER_HOUR;
- seconds -= hours * SECONDS_PER_HOUR;
- }
- if (seconds >= SECONDS_PER_MINUTE) {
- minutes = seconds / SECONDS_PER_MINUTE;
- seconds -= minutes * SECONDS_PER_MINUTE;
- }
+ int days = 0, hours = 0, minutes = 0;
+ if (seconds >= SECONDS_PER_DAY) {
+ days = seconds / SECONDS_PER_DAY;
+ seconds -= days * SECONDS_PER_DAY;
+ }
+ if (seconds >= SECONDS_PER_HOUR) {
+ hours = seconds / SECONDS_PER_HOUR;
+ seconds -= hours * SECONDS_PER_HOUR;
+ }
+ if (seconds >= SECONDS_PER_MINUTE) {
+ minutes = seconds / SECONDS_PER_MINUTE;
+ seconds -= minutes * SECONDS_PER_MINUTE;
+ }
- final ArrayList<Measure> measureList = new ArrayList(4);
- if (days > 0) {
- measureList.add(new Measure(days, MeasureUnit.DAY));
- }
- if (hours > 0) {
- measureList.add(new Measure(hours, MeasureUnit.HOUR));
- }
- if (minutes > 0) {
- measureList.add(new Measure(minutes, MeasureUnit.MINUTE));
- }
- if (withSeconds && seconds > 0) {
- measureList.add(new Measure(seconds, MeasureUnit.SECOND));
- }
- if (measureList.size() == 0) {
- // Everything addable was zero, so nothing was added. We add a zero.
- measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));
- }
- final Measure[] measureArray = measureList.toArray(new Measure[measureList.size()]);
+ final ArrayList<Measure> measureList = new ArrayList(4);
+ if (days > 0) {
+ measureList.add(new Measure(days, MeasureUnit.DAY));
+ }
+ if (hours > 0) {
+ measureList.add(new Measure(hours, MeasureUnit.HOUR));
+ }
+ if (minutes > 0) {
+ measureList.add(new Measure(minutes, MeasureUnit.MINUTE));
+ }
+ if (withSeconds && seconds > 0) {
+ measureList.add(new Measure(seconds, MeasureUnit.SECOND));
+ }
+ if (measureList.size() == 0) {
+ // Everything addable was zero, so nothing was added. We add a zero.
+ measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));
+ }
+ final Measure[] measureArray = measureList.toArray(new Measure[measureList.size()]);
- final Locale locale = context.getResources().getConfiguration().locale;
- final MeasureFormat measureFormat = MeasureFormat.getInstance(
- locale, FormatWidth.NARROW);
- sb.append(measureFormat.formatMeasures(measureArray));
+ final Locale locale = context.getResources().getConfiguration().locale;
+ final MeasureFormat measureFormat = MeasureFormat.getInstance(
+ locale, FormatWidth.NARROW);
+ sb.append(measureFormat.formatMeasures(measureArray));
- if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {
- // Add ttsSpan if it only have minute value, because it will be read as "meters"
- final TtsSpan ttsSpan = new TtsSpan.MeasureBuilder().setNumber(minutes)
- .setUnit("minute").build();
- sb.setSpan(ttsSpan, 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
+ if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {
+ // Add ttsSpan if it only have minute value, because it will be read as "meters"
+ final TtsSpan ttsSpan = new TtsSpan.MeasureBuilder().setNumber(minutes)
+ .setUnit("minute").build();
+ sb.setSpan(ttsSpan, 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
- return sb;
- }
+ return sb;
+ }
/**
* Returns relative time for the given millis in the past, in a short format such as "2 days
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
index 9285148f7ae2..c42ff083ff11 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
@@ -24,13 +24,18 @@ import android.content.Context;
import com.android.settingslib.R;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import java.time.Clock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import java.time.Duration;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowSettings.ShadowSystem;
+import org.robolectric.shadows.ShadowSystemClock;
@RunWith(SettingsLibRobolectricTestRunner.class)
public class PowerUtilTest {
@@ -39,8 +44,12 @@ public class PowerUtilTest {
public static final long SEVENTEEN_MIN_MILLIS = Duration.ofMinutes(17).toMillis();
public static final long FIVE_MINUTES_MILLIS = Duration.ofMinutes(5).toMillis();
public static final long TEN_MINUTES_MILLIS = Duration.ofMinutes(10).toMillis();
- public static final long TWO_DAYS_MILLIS = Duration.ofDays(2).toMillis();
- public static final String ONE_DAY_FORMATTED = "1 day";
+ public static final long THREE_DAYS_MILLIS = Duration.ofDays(3).toMillis();
+ public static final long THIRTY_HOURS_MILLIS = Duration.ofHours(30).toMillis();
+ public static final String TWO_DAYS_FORMATTED = "2 days";
+ public static final String THIRTY_HOURS_FORMATTED = "1d 6h";
+ public static final String NORMAL_CASE_EXPECTED_PREFIX = "Will last until about";
+ public static final String ENHANCED_SUFFIX = "based on your usage";
private Context mContext;
@@ -51,6 +60,7 @@ public class PowerUtilTest {
}
@Test
+ @Config(shadows = {ShadowSystemClock.class})
public void testGetBatteryRemainingStringFormatted_moreThanFifteenMinutes_withPercentage() {
String info = PowerUtil.getBatteryRemainingStringFormatted(mContext,
SEVENTEEN_MIN_MILLIS,
@@ -62,15 +72,13 @@ public class PowerUtilTest {
false /* basedOnUsage */);
// We only add special mention for the long string
- assertThat(info).isEqualTo(mContext.getString(
- R.string.power_discharging_duration_enhanced,
- TEST_BATTERY_LEVEL_10,
- FIFTEEN_MIN_FORMATTED));
+ assertThat(info).contains(NORMAL_CASE_EXPECTED_PREFIX);
+ assertThat(info).contains(ENHANCED_SUFFIX);
+ assertThat(info).contains("%");
// shortened string should not have extra text
- assertThat(info2).isEqualTo(mContext.getString(
- R.string.power_discharging_duration,
- TEST_BATTERY_LEVEL_10,
- FIFTEEN_MIN_FORMATTED));
+ assertThat(info2).contains(NORMAL_CASE_EXPECTED_PREFIX);
+ assertThat(info2).doesNotContain(ENHANCED_SUFFIX);
+ assertThat(info2).contains("%");
}
@Test
@@ -84,14 +92,14 @@ public class PowerUtilTest {
null /* percentageString */,
false /* basedOnUsage */);
- // We only add special mention for the long string
- assertThat(info).isEqualTo(mContext.getString(
- R.string.power_remaining_duration_only_enhanced,
- FIFTEEN_MIN_FORMATTED));
+ // We only have % when it is provided
+ assertThat(info).contains(NORMAL_CASE_EXPECTED_PREFIX);
+ assertThat(info).contains(ENHANCED_SUFFIX);
+ assertThat(info).doesNotContain("%");
// shortened string should not have extra text
- assertThat(info2).isEqualTo(mContext.getString(
- R.string.power_remaining_duration_only,
- FIFTEEN_MIN_FORMATTED));
+ assertThat(info2).contains(NORMAL_CASE_EXPECTED_PREFIX);
+ assertThat(info2).doesNotContain(ENHANCED_SUFFIX);
+ assertThat(info2).doesNotContain("%");
}
@@ -107,12 +115,9 @@ public class PowerUtilTest {
true /* basedOnUsage */);
// additional battery percentage in this string
- assertThat(info).isEqualTo(mContext.getString(
- R.string.power_remaining_duration_shutdown_imminent,
- TEST_BATTERY_LEVEL_10));
+ assertThat(info).isEqualTo("Phone may shutdown soon (10%)");
// shortened string should not have percentage
- assertThat(info2).isEqualTo(mContext.getString(
- R.string.power_remaining_duration_only_shutdown_imminent));
+ assertThat(info2).isEqualTo("Phone may shutdown soon");
}
@Test
@@ -127,35 +132,42 @@ public class PowerUtilTest {
true /* basedOnUsage */);
// shortened string should not have percentage
- assertThat(info).isEqualTo(mContext.getString(
- R.string.power_remaining_less_than_duration_only,
- FIFTEEN_MIN_FORMATTED));
+ assertThat(info).isEqualTo("Less than 15m remaining");
// Add percentage to string when provided
- assertThat(info2).isEqualTo(mContext.getString(
- R.string.power_remaining_less_than_duration,
- TEST_BATTERY_LEVEL_10,
- FIFTEEN_MIN_FORMATTED));
+ assertThat(info2).isEqualTo("Less than 15m remaining (10%)");
}
@Test
- public void testGetBatteryRemainingStringFormatted_moreThanOneDay_usesCorrectString() {
+ public void testGetBatteryRemainingStringFormatted_betweenOneAndTwoDays_usesCorrectString() {
String info = PowerUtil.getBatteryRemainingStringFormatted(mContext,
- TWO_DAYS_MILLIS,
+ THIRTY_HOURS_MILLIS,
null /* percentageString */,
true /* basedOnUsage */);
String info2 = PowerUtil.getBatteryRemainingStringFormatted(mContext,
- TWO_DAYS_MILLIS,
+ THIRTY_HOURS_MILLIS,
+ TEST_BATTERY_LEVEL_10 /* percentageString */,
+ false /* basedOnUsage */);
+
+ // We only add special mention for the long string
+ assertThat(info).isEqualTo("About 1d 6h left based on your usage");
+ // shortened string should not have extra text
+ assertThat(info2).isEqualTo("About 1d 6h left (10%)");
+ }
+
+ @Test
+ public void testGetBatteryRemainingStringFormatted_moreThanTwoDays_usesCorrectString() {
+ String info = PowerUtil.getBatteryRemainingStringFormatted(mContext,
+ THREE_DAYS_MILLIS,
+ null /* percentageString */,
+ true /* basedOnUsage */);
+ String info2 = PowerUtil.getBatteryRemainingStringFormatted(mContext,
+ THREE_DAYS_MILLIS,
TEST_BATTERY_LEVEL_10 /* percentageString */,
true /* basedOnUsage */);
// shortened string should not have percentage
- assertThat(info).isEqualTo(mContext.getString(
- R.string.power_remaining_only_more_than_subtext,
- ONE_DAY_FORMATTED));
+ assertThat(info).isEqualTo("More than 2 days remaining");
// Add percentage to string when provided
- assertThat(info2).isEqualTo(mContext.getString(
- R.string.power_remaining_more_than_subtext,
- TEST_BATTERY_LEVEL_10,
- ONE_DAY_FORMATTED));
+ assertThat(info2).isEqualTo("More than 2 days remaining (10%)");
}
}
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 4614999e3c4f..2e7ab7fe8904 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
+<!-- extends FrameLayout -->
<com.android.systemui.statusbar.ExpandableNotificationRow
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
@@ -54,6 +55,7 @@
android:paddingStart="8dp"
/>
+ <!-- TODO: remove -->
<ImageButton
android:id="@+id/helper"
android:layout_width="48dp"
@@ -64,7 +66,7 @@
android:tint="#FF0000"
android:background="@drawable/ripple_drawable"
android:visibility="visible"
- />
+ />
<ViewStub
android:layout="@layout/notification_children_container"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 0103cad4a6c4..2f28c814c76b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -17,6 +17,7 @@
package com.android.systemui.shared.system;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
@@ -403,6 +404,25 @@ public class ActivityManagerWrapper {
}
/**
+ * @return whether screen pinning is active.
+ */
+ public boolean isScreenPinningActive() {
+ try {
+ return ActivityManager.getService().getLockTaskModeState() == LOCK_TASK_MODE_PINNED;
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * @return whether screen pinning is enabled.
+ */
+ public boolean isScreenPinningEnabled() {
+ final ContentResolver cr = AppGlobals.getInitialApplication().getContentResolver();
+ return Settings.System.getInt(cr, Settings.System.LOCK_TO_APP_ENABLED, 0) != 0;
+ }
+
+ /**
* @return whether there is currently a locked task (ie. in screen pinning).
*/
public boolean isLockToAppActive() {
@@ -415,9 +435,9 @@ public class ActivityManagerWrapper {
/**
* @return whether screen pinning is enabled.
+ * @deprecated See {@link #isScreenPinningEnabled}
*/
public boolean isLockToAppEnabled() {
- final ContentResolver cr = AppGlobals.getInitialApplication().getContentResolver();
- return Settings.System.getInt(cr, Settings.System.LOCK_TO_APP_ENABLED, 0) != 0;
+ return isScreenPinningEnabled();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 7403ddc441f6..cad155c43867 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -44,6 +44,7 @@ import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.power.PowerNotificationWarnings;
import com.android.systemui.power.PowerUI;
+import com.android.systemui.statusbar.AppOpsListener;
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
import com.android.systemui.statusbar.phone.LightBarController;
@@ -314,6 +315,8 @@ public class Dependency extends SystemUI {
mProviders.put(EnhancedEstimates.class, () -> new EnhancedEstimatesImpl());
+ mProviders.put(AppOpsListener.class, () -> new AppOpsListener(mContext));
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index a2c9ab4871c2..5a2263cf26c7 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -14,7 +14,9 @@
package com.android.systemui;
+import android.annotation.Nullable;
import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
public interface ForegroundServiceController {
/**
@@ -46,4 +48,32 @@ public interface ForegroundServiceController {
* @return true if sbn is the system-provided "dungeon" (list of running foreground services).
*/
boolean isDungeonNotification(StatusBarNotification sbn);
+
+ /**
+ * @return true if sbn is one of the window manager "drawing over other apps" notifications
+ */
+ boolean isSystemAlertNotification(StatusBarNotification sbn);
+
+ /**
+ * Returns the key of the foreground service from this package using the standard template,
+ * if one exists.
+ */
+ @Nullable String getStandardLayoutKey(int userId, String pkg);
+
+ /**
+ * @return true if this user/pkg has a missing or custom layout notification and therefore needs
+ * a disclosure notification for system alert windows.
+ */
+ boolean isSystemAlertWarningNeeded(int userId, String pkg);
+
+ /**
+ * Records active app ops. App Ops are stored in FSC in addition to NotificationData in
+ * case they change before we have a notification to tag.
+ */
+ void onAppOpChanged(int code, int uid, String packageName, boolean active);
+
+ /**
+ * Gets active app ops for this user and package.
+ */
+ @Nullable ArraySet<Integer> getAppOps(int userId, String packageName);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java
index 3714c4ea7e2c..fc2b5b490e2c 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java
@@ -18,13 +18,13 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
+import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto;
import java.util.Arrays;
@@ -34,17 +34,19 @@ import java.util.Arrays;
*/
public class ForegroundServiceControllerImpl
implements ForegroundServiceController {
-
+
// shelf life of foreground services before they go bad
public static final long FG_SERVICE_GRACE_MILLIS = 5000;
private static final String TAG = "FgServiceController";
private static final boolean DBG = false;
+ private final Context mContext;
private final SparseArray<UserServices> mUserServices = new SparseArray<>();
private final Object mMutex = new Object();
public ForegroundServiceControllerImpl(Context context) {
+ mContext = context;
}
@Override
@@ -57,6 +59,52 @@ public class ForegroundServiceControllerImpl
}
@Override
+ public boolean isSystemAlertWarningNeeded(int userId, String pkg) {
+ synchronized (mMutex) {
+ final UserServices services = mUserServices.get(userId);
+ if (services == null) return false;
+ return services.getStandardLayoutKey(pkg) == null;
+ }
+ }
+
+ @Override
+ public String getStandardLayoutKey(int userId, String pkg) {
+ synchronized (mMutex) {
+ final UserServices services = mUserServices.get(userId);
+ if (services == null) return null;
+ return services.getStandardLayoutKey(pkg);
+ }
+ }
+
+ @Override
+ public ArraySet<Integer> getAppOps(int userId, String pkg) {
+ synchronized (mMutex) {
+ final UserServices services = mUserServices.get(userId);
+ if (services == null) {
+ return null;
+ }
+ return services.getFeatures(pkg);
+ }
+ }
+
+ @Override
+ public void onAppOpChanged(int code, int uid, String packageName, boolean active) {
+ int userId = UserHandle.getUserId(uid);
+ synchronized (mMutex) {
+ UserServices userServices = mUserServices.get(userId);
+ if (userServices == null) {
+ userServices = new UserServices();
+ mUserServices.put(userId, userServices);
+ }
+ if (active) {
+ userServices.addOp(packageName, code);
+ } else {
+ userServices.removeOp(packageName, code);
+ }
+ }
+ }
+
+ @Override
public void addNotification(StatusBarNotification sbn, int importance) {
updateNotification(sbn, importance);
}
@@ -102,9 +150,16 @@ public class ForegroundServiceControllerImpl
}
} else {
userServices.removeNotification(sbn.getPackageName(), sbn.getKey());
- if (0 != (sbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE)
- && newImportance > NotificationManager.IMPORTANCE_MIN) {
- userServices.addNotification(sbn.getPackageName(), sbn.getKey());
+ if (0 != (sbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE)) {
+ if (newImportance > NotificationManager.IMPORTANCE_MIN) {
+ userServices.addImportantNotification(sbn.getPackageName(), sbn.getKey());
+ }
+ final Notification.Builder builder = Notification.Builder.recoverBuilder(
+ mContext, sbn.getNotification());
+ if (builder.usesStandardHeader()) {
+ userServices.addStandardLayoutNotification(
+ sbn.getPackageName(), sbn.getKey());
+ }
}
}
}
@@ -117,42 +172,105 @@ public class ForegroundServiceControllerImpl
&& sbn.getPackageName().equals("android");
}
+ @Override
+ public boolean isSystemAlertNotification(StatusBarNotification sbn) {
+ // TODO: tag system alert notifications so they can be suppressed if app's notification
+ // is tagged
+ return false;
+ }
+
/**
* Struct to track relevant packages and notifications for a userid's foreground services.
*/
private static class UserServices {
private String[] mRunning = null;
private long mServiceStartTime = 0;
- private ArrayMap<String, ArraySet<String>> mNotifications = new ArrayMap<>(1);
+ // package -> sufficiently important posted notification keys
+ private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1);
+ // package -> standard layout posted notification keys
+ private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1);
+
+ // package -> app ops
+ private ArrayMap<String, ArraySet<Integer>> mAppOps = new ArrayMap<>(1);
+
public void setRunningServices(String[] pkgs, long serviceStartTime) {
mRunning = pkgs != null ? Arrays.copyOf(pkgs, pkgs.length) : null;
mServiceStartTime = serviceStartTime;
}
- public void addNotification(String pkg, String key) {
- if (mNotifications.get(pkg) == null) {
- mNotifications.put(pkg, new ArraySet<String>());
+
+ public void addOp(String pkg, int op) {
+ if (mAppOps.get(pkg) == null) {
+ mAppOps.put(pkg, new ArraySet<>(3));
+ }
+ mAppOps.get(pkg).add(op);
+ }
+
+ public boolean removeOp(String pkg, int op) {
+ final boolean found;
+ final ArraySet<Integer> keys = mAppOps.get(pkg);
+ if (keys == null) {
+ found = false;
+ } else {
+ found = keys.remove(op);
+ if (keys.size() == 0) {
+ mAppOps.remove(pkg);
+ }
}
- mNotifications.get(pkg).add(key);
+ return found;
}
+
+ public void addImportantNotification(String pkg, String key) {
+ addNotification(mImportantNotifications, pkg, key);
+ }
+
+ public boolean removeImportantNotification(String pkg, String key) {
+ return removeNotification(mImportantNotifications, pkg, key);
+ }
+
+ public void addStandardLayoutNotification(String pkg, String key) {
+ addNotification(mStandardLayoutNotifications, pkg, key);
+ }
+
+ public boolean removeStandardLayoutNotification(String pkg, String key) {
+ return removeNotification(mStandardLayoutNotifications, pkg, key);
+ }
+
public boolean removeNotification(String pkg, String key) {
+ boolean removed = false;
+ removed |= removeImportantNotification(pkg, key);
+ removed |= removeStandardLayoutNotification(pkg, key);
+ return removed;
+ }
+
+ public void addNotification(ArrayMap<String, ArraySet<String>> map, String pkg,
+ String key) {
+ if (map.get(pkg) == null) {
+ map.put(pkg, new ArraySet<>());
+ }
+ map.get(pkg).add(key);
+ }
+
+ public boolean removeNotification(ArrayMap<String, ArraySet<String>> map,
+ String pkg, String key) {
final boolean found;
- final ArraySet<String> keys = mNotifications.get(pkg);
+ final ArraySet<String> keys = map.get(pkg);
if (keys == null) {
found = false;
} else {
found = keys.remove(key);
if (keys.size() == 0) {
- mNotifications.remove(pkg);
+ map.remove(pkg);
}
}
return found;
}
+
public boolean isDungeonNeeded() {
if (mRunning != null
&& System.currentTimeMillis() - mServiceStartTime >= FG_SERVICE_GRACE_MILLIS) {
for (String pkg : mRunning) {
- final ArraySet<String> set = mNotifications.get(pkg);
+ final ArraySet<String> set = mImportantNotifications.get(pkg);
if (set == null || set.size() == 0) {
return true;
}
@@ -160,5 +278,27 @@ public class ForegroundServiceControllerImpl
}
return false;
}
+
+ public ArraySet<Integer> getFeatures(String pkg) {
+ return mAppOps.get(pkg);
+ }
+
+ public String getStandardLayoutKey(String pkg) {
+ final ArraySet<String> set = mStandardLayoutNotifications.get(pkg);
+ if (set == null || set.size() == 0) {
+ return null;
+ }
+ return set.valueAt(0);
+ }
+
+ @Override
+ public String toString() {
+ return "UserServices{" +
+ "mRunning=" + Arrays.toString(mRunning) +
+ ", mServiceStartTime=" + mServiceStartTime +
+ ", mImportantNotifications=" + mImportantNotifications +
+ ", mStandardLayoutNotifications=" + mStandardLayoutNotifications +
+ '}';
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 47b0de94f133..df4a975cb0a8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -449,7 +449,7 @@ public class Recents extends SystemUI
final int activityType = runningTask != null
? runningTask.configuration.windowConfiguration.getActivityType()
: ACTIVITY_TYPE_UNDEFINED;
- boolean screenPinningActive = ActivityManagerWrapper.getInstance().isLockToAppActive();
+ boolean screenPinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
boolean isRunningTaskInHomeOrRecentsStack =
activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS;
if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 3f6f30bba8c4..055e72e2f8fb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -24,7 +24,6 @@ import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASO
import android.app.ActivityManager;
import android.app.ActivityOptions;
-import android.app.KeyguardManager;
import android.app.trust.TrustManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -34,7 +33,6 @@ import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
-import android.os.AsyncTask.Status;
import android.os.Handler;
import android.os.SystemClock;
import android.util.ArraySet;
@@ -385,8 +383,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
}
public void toggleRecents(int growTarget) {
- // Skip preloading if the task is locked
- if (ActivityManagerWrapper.getInstance().isLockToAppActive()) {
+ if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
return;
}
@@ -464,8 +461,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
}
public void preloadRecents() {
- // Skip preloading if the task is locked
- if (ActivityManagerWrapper.getInstance().isLockToAppActive()) {
+ if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 3cc3273c0db4..89288d84aceb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -2188,7 +2188,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
private void readSystemFlags() {
SystemServicesProxy ssp = Recents.getSystemServices();
mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
- mScreenPinningEnabled = ActivityManagerWrapper.getInstance().isLockToAppEnabled();
+ mScreenPinningEnabled = ActivityManagerWrapper.getInstance().isScreenPinningEnabled()
+ && !ActivityManagerWrapper.getInstance().isLockToAppActive();
}
private void updateStackActionButtonVisibility() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java
new file mode 100644
index 000000000000..2ec78cfe9382
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java
@@ -0,0 +1,68 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.ForegroundServiceController;
+
+/**
+ * This class handles listening to notification updates and passing them along to
+ * NotificationPresenter to be displayed to the user.
+ */
+public class AppOpsListener implements AppOpsManager.OnOpActiveChangedListener {
+ private static final String TAG = "NotificationListener";
+
+ // Dependencies:
+ private final ForegroundServiceController mFsc =
+ Dependency.get(ForegroundServiceController.class);
+
+ private final Context mContext;
+ protected NotificationPresenter mPresenter;
+ protected NotificationEntryManager mEntryManager;
+ protected final AppOpsManager mAppOps;
+
+ protected static final int[] OPS = new int[] {AppOpsManager.OP_CAMERA,
+ AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
+ AppOpsManager.OP_RECORD_AUDIO};
+
+ public AppOpsListener(Context context) {
+ mContext = context;
+ mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ }
+
+ public void setUpWithPresenter(NotificationPresenter presenter,
+ NotificationEntryManager entryManager) {
+ mPresenter = presenter;
+ mEntryManager = entryManager;
+ mAppOps.startWatchingActive(OPS, this);
+ }
+
+ public void destroy() {
+ mAppOps.stopWatchingActive(this);
+ }
+
+ @Override
+ public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
+ mFsc.onAppOpChanged(code, uid, packageName, active);
+ mPresenter.getHandler().post(() -> {
+ mEntryManager.updateNotificationsForAppOps(code, uid, packageName, active);
+ });
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index bc2dff917b9a..785fc1cc5922 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -36,6 +36,7 @@ import android.os.Build;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.MathUtils;
@@ -1354,6 +1355,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mHelperButton.setVisibility(show ? View.VISIBLE : View.GONE);
}
+ public void showAppOpsIcons(ArraySet<Integer> activeOps) {
+ if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() != null) {
+ mChildrenContainer.getHeaderView().showAppOpsIcons(activeOps);
+ }
+ mPrivateLayout.showAppOpsIcons(activeOps);
+ mPublicLayout.showAppOpsIcons(activeOps);
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -2629,6 +2638,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mChildrenContainer = childrenContainer;
}
+ @VisibleForTesting
+ protected void setPrivateLayout(NotificationContentView privateLayout) {
+ mPrivateLayout = privateLayout;
+ }
+
+ @VisibleForTesting
+ protected void setPublicLayout(NotificationContentView publicLayout) {
+ mPublicLayout = publicLayout;
+ }
+
/**
* Equivalent to View.OnLongClickListener with coordinates
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 91960df9b01d..73c87953cf45 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
import android.view.NotificationHeaderView;
@@ -1423,6 +1424,17 @@ public class NotificationContentView extends FrameLayout {
return header;
}
+ public void showAppOpsIcons(ArraySet<Integer> activeOps) {
+ if (mContractedChild != null && mContractedWrapper.getNotificationHeader() != null) {
+ mContractedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+ }
+ if (mExpandedChild != null && mExpandedWrapper.getNotificationHeader() != null) {
+ mExpandedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+ }
+ if (mHeadsUpChild != null && mHeadsUpWrapper.getNotificationHeader() != null) {
+ mHeadsUpWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+ }
+ }
public NotificationHeaderView getContractedNotificationHeader() {
if (mContractedChild != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 127f3f918fba..d53cb03cfcb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar;
import android.app.AppGlobals;
+import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -34,6 +35,7 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RemoteViews;
@@ -65,6 +67,8 @@ public class NotificationData {
private final Environment mEnvironment;
private HeadsUpManager mHeadsUpManager;
+ final ForegroundServiceController mFsc = Dependency.get(ForegroundServiceController.class);
+
public static final class Entry {
private static final long LAUNCH_COOLDOWN = 2000;
private static final long REMOTE_INPUT_COOLDOWN = 500;
@@ -95,6 +99,7 @@ public class NotificationData {
private Throwable mDebugThrowable;
public CharSequence remoteInputTextWhenReset;
public long lastRemoteInputSent = NOT_LAUNCHED_YET;
+ public ArraySet<Integer> mActiveAppOps = new ArraySet<>(3);
public Entry(StatusBarNotification n) {
this.key = n.getKey();
@@ -194,7 +199,7 @@ public class NotificationData {
/**
* Update the notification icons.
* @param context the context to create the icons with.
- * @param n the notification to read the icon from.
+ * @param sbn the notification to read the icon from.
* @throws InflationException
*/
public void updateIcons(Context context, StatusBarNotification sbn)
@@ -375,6 +380,8 @@ public class NotificationData {
}
mGroupManager.onEntryAdded(entry);
+ updateAppOps(entry);
+
updateRankingAndSort(mRankingMap);
}
@@ -393,6 +400,35 @@ public class NotificationData {
updateRankingAndSort(ranking);
}
+ private void updateAppOps(Entry entry) {
+ final int uid = entry.notification.getUid();
+ final String pkg = entry.notification.getPackageName();
+ ArraySet<Integer> activeOps = mFsc.getAppOps(entry.notification.getUserId(), pkg);
+ if (activeOps != null) {
+ int N = activeOps.size();
+ for (int i = 0; i < N; i++) {
+ updateAppOp(activeOps.valueAt(i), uid, pkg, true);
+ }
+ }
+ }
+
+ public void updateAppOp(int appOp, int uid, String pkg, boolean showIcon) {
+ synchronized (mEntries) {
+ final int N = mEntries.size();
+ for (int i = 0; i < N; i++) {
+ Entry entry = mEntries.valueAt(i);
+ if (uid == entry.notification.getUid()
+ && pkg.equals(entry.notification.getPackageName())) {
+ if (showIcon) {
+ entry.mActiveAppOps.add(appOp);
+ } else {
+ entry.mActiveAppOps.remove(appOp);
+ }
+ }
+ }
+ }
+ }
+
public boolean isAmbient(String key) {
if (mRankingMap != null) {
getRanking(key, mTmpRanking);
@@ -545,11 +581,14 @@ public class NotificationData {
return true;
}
- final ForegroundServiceController fsc = Dependency.get(ForegroundServiceController.class);
- if (fsc.isDungeonNotification(sbn) && !fsc.isDungeonNeededForUser(sbn.getUserId())) {
+ if (mFsc.isDungeonNotification(sbn) && !mFsc.isDungeonNeededForUser(sbn.getUserId())) {
// this is a foreground-service disclosure for a user that does not need to show one
return true;
}
+ if (mFsc.isSystemAlertNotification(sbn) && !mFsc.isSystemAlertWarningNeeded(
+ sbn.getUserId(), sbn.getPackageName())) {
+ return true;
+ }
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
index 7360486ac7e9..71f7911b41f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -31,6 +31,7 @@ import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
@@ -77,7 +78,7 @@ import java.util.List;
public class NotificationEntryManager implements Dumpable, NotificationInflater.InflationCallback,
ExpandableNotificationRow.ExpansionLogger, NotificationUpdateHandler,
VisualStabilityManager.Callback {
- private static final String TAG = "NotificationEntryManager";
+ private static final String TAG = "NotificationEntryMgr";
protected static final boolean DEBUG = false;
protected static final boolean ENABLE_HEADS_UP = true;
protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
@@ -734,6 +735,14 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
}
}
+ public void updateNotificationsForAppOps(int appOp, int uid, String pkg, boolean showIcon) {
+ if (mForegroundServiceController.getStandardLayoutKey(
+ UserHandle.getUserId(uid), pkg) != null) {
+ mNotificationData.updateAppOp(appOp, uid, pkg, showIcon);
+ updateNotifications();
+ }
+ }
+
private boolean alertAgain(NotificationData.Entry oldEntry, Notification newNotification) {
return oldEntry == null || !oldEntry.hasInterrupted()
|| (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index cd4c7ae8d57e..75b8b371119e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -342,6 +342,8 @@ public class NotificationViewHierarchyManager {
row.showBlockingHelper(entry.userSentiment ==
NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+
+ row.showAppOpsIcons(entry.mActiveAppOps);
}
mPresenter.onUpdateRowStates();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index aba5cdf0ca2b..d2cdc27d982c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.support.v4.util.ArraySet;
import android.util.Log;
@@ -32,6 +33,7 @@ import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
@@ -45,12 +47,12 @@ import java.util.Stack;
*/
public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
ViewTreeObserver.OnComputeInternalInsetsListener, VisualStabilityManager.Callback,
- OnHeadsUpChangedListener {
+ OnHeadsUpChangedListener, ConfigurationController.ConfigurationListener {
private static final String TAG = "HeadsUpManagerPhone";
private static final boolean DEBUG = false;
private final View mStatusBarWindowView;
- private final int mStatusBarHeight;
+ private int mStatusBarHeight;
private final NotificationGroupManager mGroupManager;
private final StatusBar mBar;
private final VisualStabilityManager mVisualStabilityManager;
@@ -291,6 +293,13 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
}
}
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ Resources resources = mContext.getResources();
+ mStatusBarHeight = resources.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height);
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////
// VisualStabilityManager.Callback overrides:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 62151cfa258b..0ed69e66b03e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -708,7 +708,8 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
@VisibleForTesting
boolean onHomeLongClick(View v) {
- if (!mNavigationBarView.isRecentsButtonVisible() && mNavigationBarView.inScreenPinning()) {
+ if (!mNavigationBarView.isRecentsButtonVisible()
+ && ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
return onLongPressBackHome(v);
}
if (shouldDisableNavbarGestures()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index 320b56f98c85..a4daed92cabf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -43,6 +43,7 @@ import com.android.systemui.RecentsComponent;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
import com.android.systemui.shared.recents.IOverviewProxy;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.tuner.TunerService;
@@ -149,7 +150,8 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
}
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (mNavigationBarView.inScreenPinning() || mStatusBar.isKeyguardShowing()) {
+ if (ActivityManagerWrapper.getInstance().isScreenPinningActive()
+ || mStatusBar.isKeyguardShowing()) {
return false;
}
@@ -182,7 +184,8 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
}
public boolean onTouchEvent(MotionEvent event) {
- if (mNavigationBarView.inScreenPinning() || mStatusBar.isKeyguardShowing()) {
+ if (ActivityManagerWrapper.getInstance().isScreenPinningActive()
+ || mStatusBar.isKeyguardShowing()) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index a5621e5a4010..74fbed1b0da7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -21,8 +21,6 @@ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition;
import android.animation.LayoutTransition.TransitionListener;
import android.animation.ObjectAnimator;
@@ -30,7 +28,6 @@ import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.DrawableRes;
import android.annotation.StyleRes;
-import android.app.ActivityManager;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
@@ -41,7 +38,6 @@ import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.os.SystemProperties;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
@@ -60,7 +56,6 @@ import android.widget.FrameLayout;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.DockedStackExistsListener;
-import com.android.systemui.Interpolators;
import com.android.systemui.OverviewProxyService;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
@@ -379,15 +374,20 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
return getRecentsButton().getVisibility() == View.VISIBLE;
}
+ public boolean isOverviewEnabled() {
+ return (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) == 0;
+ }
+
public boolean isQuickStepSwipeUpEnabled() {
return mOverviewProxyService.getProxy() != null
+ && isOverviewEnabled()
&& ((mOverviewProxyService.getInteractionFlags()
& FLAG_DISABLE_SWIPE_UP) == 0);
}
public boolean isQuickScrubEnabled() {
return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true)
- && mOverviewProxyService.getProxy() != null && !isRecentsButtonVisible()
+ && mOverviewProxyService.getProxy() != null && isOverviewEnabled()
&& ((mOverviewProxyService.getInteractionFlags()
& FLAG_DISABLE_QUICK_SCRUB) == 0);
}
@@ -575,8 +575,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
// Always disable recents when alternate car mode UI is active.
- boolean disableRecent = mUseCarModeUi
- || ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
+ boolean disableRecent = mUseCarModeUi || !isOverviewEnabled();
boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
&& ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0);
@@ -584,17 +583,18 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
// When screen pinning, don't hide back and home when connected service or back and
// recents buttons when disconnected from launcher service in screen pinning mode,
// as they are used for exiting.
+ final boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
if (mOverviewProxyService.getProxy() != null) {
// Use interaction flags to show/hide navigation buttons but will be shown if required
// to exit screen pinning.
final int flags = mOverviewProxyService.getInteractionFlags();
disableRecent |= (flags & FLAG_SHOW_OVERVIEW_BUTTON) == 0;
- if (inScreenPinning()) {
+ if (pinningActive) {
disableBack = disableHome = false;
} else {
disableBack |= (flags & FLAG_HIDE_BACK_BUTTON) != 0;
}
- } else if (inScreenPinning()) {
+ } else if (pinningActive) {
disableBack = disableRecent = false;
}
@@ -614,7 +614,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
}
public boolean inScreenPinning() {
- return ActivityManagerWrapper.getInstance().isLockToAppActive();
+ return ActivityManagerWrapper.getInstance().isScreenPinningActive();
}
public void setLayoutTransitionsEnabled(boolean enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index cc5a93ce71b6..900ec0be4b54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -264,7 +264,7 @@ public class PhoneStatusBarView extends PanelBar {
mScrimController.setPanelExpansion(scrimFraction);
}
- public void onDensityOrFontScaleChanged() {
+ public void updateResources() {
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.height = getResources().getDimensionPixelSize(
R.dimen.status_bar_height);
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 2afd05f18f7a..86e618e4690c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -180,6 +180,7 @@ import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.AppOpsListener;
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CrossFadeHelper;
@@ -405,6 +406,7 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationLogger mNotificationLogger;
protected NotificationEntryManager mEntryManager;
protected NotificationViewHierarchyManager mViewHierarchyManager;
+ protected AppOpsListener mAppOpsListener;
/**
* Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -622,6 +624,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mMediaManager = Dependency.get(NotificationMediaManager.class);
mEntryManager = Dependency.get(NotificationEntryManager.class);
mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
+ mAppOpsListener = Dependency.get(AppOpsListener.class);
+ mAppOpsListener.setUpWithPresenter(this, mEntryManager);
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mColorExtractor.addOnColorsChangedListener(this);
@@ -813,6 +817,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mHeadsUpManager = new HeadsUpManagerPhone(context, mStatusBarWindow, mGroupManager, this,
mVisualStabilityManager);
+ Dependency.get(ConfigurationController.class).addCallback(mHeadsUpManager);
mHeadsUpManager.addListener(this);
mHeadsUpManager.addListener(mNotificationPanel);
mHeadsUpManager.addListener(mGroupManager);
@@ -1069,7 +1074,6 @@ public class StatusBar extends SystemUI implements DemoMode,
// end old BaseStatusBar.onDensityOrFontScaleChanged().
mScrimController.onDensityOrFontScaleChanged();
// TODO: Remove this.
- if (mStatusBarView != null) mStatusBarView.onDensityOrFontScaleChanged();
if (mBrightnessMirrorController != null) {
mBrightnessMirrorController.onDensityOrFontScaleChanged();
}
@@ -3079,6 +3083,9 @@ public class StatusBar extends SystemUI implements DemoMode,
loadDimens();
+ if (mStatusBarView != null) {
+ mStatusBarView.updateResources();
+ }
if (mNotificationPanel != null) {
mNotificationPanel.updateResources();
}
@@ -3293,6 +3300,7 @@ public class StatusBar extends SystemUI implements DemoMode,
Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(null);
mDeviceProvisionedController.removeCallback(mUserSetupObserver);
Dependency.get(ConfigurationController.class).removeCallback(this);
+ mAppOpsListener.destroy();
}
private boolean mDemoModeAllowed;
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 1b55a5b0325f..66fde7986b00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1394,6 +1394,7 @@ public class NotificationStackScrollLayout extends ViewGroup
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
+ mStatusBarHeight = getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
float densityScale = getResources().getDisplayMetrics().density;
mSwipeHelper.setDensityScale(densityScale);
float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 943020c7b28e..18dd3c734660 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -16,6 +16,14 @@
package com.android.systemui;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.annotation.UserIdInt;
import android.app.Notification;
import android.app.NotificationManager;
@@ -24,17 +32,14 @@ import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.widget.RemoteViews;
+
import com.android.internal.messages.nano.SystemMessageProto;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ForegroundServiceControllerTest extends SysuiTestCase {
@@ -49,7 +54,7 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
}
@Test
- public void testNotificationCRUD() {
+ public void testNotificationCRUD_dungeon() {
StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, "com.example.app1");
StatusBarNotification sbn_user2_app2_fg = makeMockFgSBN(USERID_TWO, "com.example.app2");
StatusBarNotification sbn_user1_app3_fg = makeMockFgSBN(USERID_ONE, "com.example.app3");
@@ -98,6 +103,101 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
}
@Test
+ public void testNotificationCRUD_stdLayout() {
+ StatusBarNotification sbn_user1_app1_fg =
+ makeMockFgSBN(USERID_ONE, "com.example.app1", 0, true);
+ StatusBarNotification sbn_user2_app2_fg =
+ makeMockFgSBN(USERID_TWO, "com.example.app2", 1, true);
+ StatusBarNotification sbn_user1_app3_fg =
+ makeMockFgSBN(USERID_ONE, "com.example.app3", 2, true);
+ StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1",
+ 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
+ StatusBarNotification sbn_user2_app1 = makeMockSBN(USERID_TWO, "com.example.app1",
+ 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
+
+ assertFalse(fsc.removeNotification(sbn_user1_app3_fg));
+ assertFalse(fsc.removeNotification(sbn_user2_app2_fg));
+ assertFalse(fsc.removeNotification(sbn_user1_app1_fg));
+ assertFalse(fsc.removeNotification(sbn_user1_app1));
+ assertFalse(fsc.removeNotification(sbn_user2_app1));
+
+ fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+ fsc.addNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_MIN);
+ fsc.addNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_MIN);
+ fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
+ fsc.addNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_MIN);
+
+ // these are never added to the tracker
+ assertFalse(fsc.removeNotification(sbn_user1_app1));
+ assertFalse(fsc.removeNotification(sbn_user2_app1));
+
+ fsc.updateNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
+ fsc.updateNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_MIN);
+ // should still not be there
+ assertFalse(fsc.removeNotification(sbn_user1_app1));
+ assertFalse(fsc.removeNotification(sbn_user2_app1));
+
+ fsc.updateNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_MIN);
+ fsc.updateNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_MIN);
+ fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+
+ assertTrue(fsc.removeNotification(sbn_user1_app3_fg));
+ assertFalse(fsc.removeNotification(sbn_user1_app3_fg));
+
+ assertTrue(fsc.removeNotification(sbn_user2_app2_fg));
+ assertFalse(fsc.removeNotification(sbn_user2_app2_fg));
+
+ assertTrue(fsc.removeNotification(sbn_user1_app1_fg));
+ assertFalse(fsc.removeNotification(sbn_user1_app1_fg));
+
+ assertFalse(fsc.removeNotification(sbn_user1_app1));
+ assertFalse(fsc.removeNotification(sbn_user2_app1));
+ }
+
+ @Test
+ public void testAppOpsCRUD() {
+ // no crash on remove that doesn't exist
+ fsc.onAppOpChanged(9, 1000, "pkg1", false);
+ assertNull(fsc.getAppOps(0, "pkg1"));
+
+ // multiuser & multipackage
+ fsc.onAppOpChanged(8, 50, "pkg1", true);
+ fsc.onAppOpChanged(1, 60, "pkg3", true);
+ fsc.onAppOpChanged(7, 500000, "pkg2", true);
+
+ assertEquals(1, fsc.getAppOps(0, "pkg1").size());
+ assertTrue(fsc.getAppOps(0, "pkg1").contains(8));
+
+ assertEquals(1, fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size());
+ assertTrue(fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7));
+
+ assertEquals(1, fsc.getAppOps(0, "pkg3").size());
+ assertTrue(fsc.getAppOps(0, "pkg3").contains(1));
+
+ // multiple ops for the same package
+ fsc.onAppOpChanged(9, 50, "pkg1", true);
+ fsc.onAppOpChanged(5, 50, "pkg1", true);
+
+ assertEquals(3, fsc.getAppOps(0, "pkg1").size());
+ assertTrue(fsc.getAppOps(0, "pkg1").contains(8));
+ assertTrue(fsc.getAppOps(0, "pkg1").contains(9));
+ assertTrue(fsc.getAppOps(0, "pkg1").contains(5));
+
+ assertEquals(1, fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size());
+ assertTrue(fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7));
+
+ // remove one of the multiples
+ fsc.onAppOpChanged(9, 50, "pkg1", false);
+ assertEquals(2, fsc.getAppOps(0, "pkg1").size());
+ assertTrue(fsc.getAppOps(0, "pkg1").contains(8));
+ assertTrue(fsc.getAppOps(0, "pkg1").contains(5));
+
+ // remove last op
+ fsc.onAppOpChanged(1, 60, "pkg3", false);
+ assertNull(fsc.getAppOps(0, "pkg3"));
+ }
+
+ @Test
public void testDungeonPredicate() {
StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1",
5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
@@ -252,6 +352,14 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
assertFalse(fsc.isDungeonNeededForUser(USERID_TWO));
assertTrue(fsc.isDungeonNeededForUser(USERID_ONE));
+ // importance upgrade
+ fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+ assertTrue(fsc.isDungeonNeededForUser(USERID_ONE));
+ assertFalse(fsc.isDungeonNeededForUser(USERID_TWO));
+ sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+ fsc.updateNotification(sbn_user1_app1_fg,
+ NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification
+
// finally, let's turn off the service
fsc.addNotification(makeMockDungeon(USERID_ONE, null),
NotificationManager.IMPORTANCE_DEFAULT);
@@ -260,12 +368,71 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
assertFalse(fsc.isDungeonNeededForUser(USERID_TWO));
}
+ @Test
+ public void testStdLayoutBasic() {
+ final String PKG1 = "com.example.app0";
+
+ StatusBarNotification sbn_user1_app1 = makeMockFgSBN(USERID_ONE, PKG1, 0, true);
+ sbn_user1_app1.getNotification().flags = 0;
+ StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
+ fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); // not fg
+ assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+ fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // app1 has got it covered
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "otherpkg"));
+ // let's take out the non-fg notification and see what happens.
+ fsc.removeNotification(sbn_user1_app1);
+ // still covered by sbn_user1_app1_fg
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anyPkg"));
+
+ // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get
+ StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
+ sbn_user1_app1_fg_sneaky.getNotification().flags = 0;
+ fsc.updateNotification(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
+ assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
+ // ok, ok, we'll put it back
+ sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
+ fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "whatever"));
+
+ assertTrue(fsc.removeNotification(sbn_user1_app1_fg_sneaky));
+ assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "a"));
+
+ // let's try a custom layout
+ sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, false);
+ fsc.updateNotification(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
+ assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
+ // now let's test an upgrade (non fg to fg)
+ fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
+ assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "b"));
+ sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+ fsc.updateNotification(sbn_user1_app1,
+ NotificationManager.IMPORTANCE_MIN); // this is now a fg notification
+
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+
+ // remove it, make sure we're out of compliance again
+ assertTrue(fsc.removeNotification(sbn_user1_app1)); // was fg, should return true
+ assertFalse(fsc.removeNotification(sbn_user1_app1));
+ assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
+ assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+ }
+
private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
int flags) {
final Notification n = mock(Notification.class);
+ n.extras = new Bundle();
n.flags = flags;
return makeMockSBN(userid, pkg, id, tag, n);
}
+
private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
Notification n) {
final StatusBarNotification sbn = mock(StatusBarNotification.class);
@@ -278,9 +445,25 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
when(sbn.getKey()).thenReturn("MOCK:"+userid+"|"+pkg+"|"+id+"|"+tag);
return sbn;
}
+
+ private StatusBarNotification makeMockFgSBN(int userid, String pkg, int id,
+ boolean usesStdLayout) {
+ StatusBarNotification sbn =
+ makeMockSBN(userid, pkg, id, "foo", Notification.FLAG_FOREGROUND_SERVICE);
+ if (usesStdLayout) {
+ sbn.getNotification().contentView = null;
+ sbn.getNotification().headsUpContentView = null;
+ sbn.getNotification().bigContentView = null;
+ } else {
+ sbn.getNotification().contentView = mock(RemoteViews.class);
+ }
+ return sbn;
+ }
+
private StatusBarNotification makeMockFgSBN(int userid, String pkg) {
return makeMockSBN(userid, pkg, 1000, "foo", Notification.FLAG_FOREGROUND_SERVICE);
}
+
private StatusBarNotification makeMockDungeon(int userid, String[] pkgs) {
final Notification n = mock(Notification.class);
n.flags = Notification.FLAG_ONGOING_EVENT;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
new file mode 100644
index 000000000000..2a48c4b67e0e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AppOpsManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.ForegroundServiceController;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class AppOpsListenerTest extends SysuiTestCase {
+ private static final String TEST_PACKAGE_NAME = "test";
+ private static final int TEST_UID = 0;
+
+ @Mock private NotificationPresenter mPresenter;
+ @Mock private AppOpsManager mAppOpsManager;
+
+ // Dependency mocks:
+ @Mock private NotificationEntryManager mEntryManager;
+ @Mock private ForegroundServiceController mFsc;
+
+ private AppOpsListener mListener;
+ private Handler mHandler;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
+ mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
+ getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
+ mHandler = new Handler(Looper.getMainLooper());
+ when(mPresenter.getHandler()).thenReturn(mHandler);
+
+ mListener = new AppOpsListener(mContext);
+ }
+
+ @Test
+ public void testOnlyListenForFewOps() {
+ mListener.setUpWithPresenter(mPresenter, mEntryManager);
+
+ verify(mAppOpsManager, times(1)).startWatchingActive(AppOpsListener.OPS, mListener);
+ }
+
+ @Test
+ public void testStopListening() {
+ mListener.destroy();
+ verify(mAppOpsManager, times(1)).stopWatchingActive(mListener);
+ }
+
+ @Test
+ public void testInformEntryMgrOnAppOpsChange() {
+ mListener.setUpWithPresenter(mPresenter, mEntryManager);
+ mListener.onOpActiveChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ waitForIdleSync(mHandler);
+ verify(mEntryManager, times(1)).updateNotificationsForAppOps(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ }
+
+ @Test
+ public void testInformFscOnAppOpsChange() {
+ mListener.setUpWithPresenter(mPresenter, mEntryManager);
+ mListener.onOpActiveChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ waitForIdleSync(mHandler);
+ verify(mFsc, times(1)).onAppOpChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index 544585a4a917..ce629bb41e7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -19,10 +19,15 @@ package com.android.systemui.statusbar;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import android.app.AppOpsManager;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+import android.view.NotificationHeaderView;
import android.view.View;
import com.android.systemui.SysuiTestCase;
@@ -146,4 +151,34 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
Assert.assertTrue("Should always play sounds when not trusted.",
mGroup.isSoundEffectsEnabled());
}
+
+ @Test
+ public void testShowAppOpsIcons_noHeader() {
+ // public notification is custom layout - no header
+ mGroup.setSensitive(true, true);
+ mGroup.showAppOpsIcons(new ArraySet<>());
+ }
+
+ @Test
+ public void testShowAppOpsIcons_header() throws Exception {
+ NotificationHeaderView mockHeader = mock(NotificationHeaderView.class);
+
+ NotificationContentView publicLayout = mock(NotificationContentView.class);
+ mGroup.setPublicLayout(publicLayout);
+ NotificationContentView privateLayout = mock(NotificationContentView.class);
+ mGroup.setPrivateLayout(privateLayout);
+ NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
+ when(mockContainer.getNotificationChildCount()).thenReturn(1);
+ when(mockContainer.getHeaderView()).thenReturn(mockHeader);
+ mGroup.setChildrenContainer(mockContainer);
+
+ ArraySet<Integer> ops = new ArraySet<>();
+ ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
+ mGroup.showAppOpsIcons(ops);
+
+ verify(mockHeader, times(1)).showAppOpsIcons(ops);
+ verify(privateLayout, times(1)).showAppOpsIcons(ops);
+ verify(publicLayout, times(1)).showAppOpsIcons(ops);
+
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 436849c9d700..1fb4c371a408 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,14 +16,23 @@
package com.android.systemui.statusbar;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import android.app.AppOpsManager;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+import android.view.NotificationHeaderView;
import android.view.View;
import com.android.systemui.SysuiTestCase;
@@ -75,4 +84,35 @@ public class NotificationContentViewTest extends SysuiTestCase {
mView.setHeadsUpAnimatingAway(true);
Assert.assertFalse(mView.isAnimatingVisibleType());
}
+
+ @Test
+ @UiThreadTest
+ public void testShowAppOpsIcons() {
+ NotificationHeaderView mockContracted = mock(NotificationHeaderView.class);
+ when(mockContracted.findViewById(com.android.internal.R.id.notification_header))
+ .thenReturn(mockContracted);
+ NotificationHeaderView mockExpanded = mock(NotificationHeaderView.class);
+ when(mockExpanded.findViewById(com.android.internal.R.id.notification_header))
+ .thenReturn(mockExpanded);
+ NotificationHeaderView mockHeadsUp = mock(NotificationHeaderView.class);
+ when(mockHeadsUp.findViewById(com.android.internal.R.id.notification_header))
+ .thenReturn(mockHeadsUp);
+ NotificationHeaderView mockAmbient = mock(NotificationHeaderView.class);
+ when(mockAmbient.findViewById(com.android.internal.R.id.notification_header))
+ .thenReturn(mockAmbient);
+
+ mView.setContractedChild(mockContracted);
+ mView.setExpandedChild(mockExpanded);
+ mView.setHeadsUpChild(mockHeadsUp);
+ mView.setAmbientChild(mockAmbient);
+
+ ArraySet<Integer> ops = new ArraySet<>();
+ ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
+ mView.showAppOpsIcons(ops);
+
+ verify(mockContracted, times(1)).showAppOpsIcons(ops);
+ verify(mockExpanded, times(1)).showAppOpsIcons(ops);
+ verify(mockAmbient, never()).showAppOpsIcons(ops);
+ verify(mockHeadsUp, times(1)).showAppOpsIcons(any());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
index 972eddb46901..b1e1c02a035f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
@@ -16,8 +16,16 @@
package com.android.systemui.statusbar;
+import static android.app.AppOpsManager.OP_ACCEPT_HANDOVER;
+import static android.app.AppOpsManager.OP_CAMERA;
+
+import static junit.framework.Assert.assertEquals;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -33,7 +41,9 @@ import android.service.notification.StatusBarNotification;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+import com.android.systemui.ForegroundServiceController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -41,6 +51,8 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -51,6 +63,10 @@ public class NotificationDataTest extends SysuiTestCase {
private final StatusBarNotification mMockStatusBarNotification =
mock(StatusBarNotification.class);
+ @Mock
+ ForegroundServiceController mFsc;
+ @Mock
+ NotificationData.Environment mEnvironment;
private final IPackageManager mMockPackageManager = mock(IPackageManager.class);
private NotificationData mNotificationData;
@@ -58,6 +74,7 @@ public class NotificationDataTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
when(mMockStatusBarNotification.getUid()).thenReturn(UID_NORMAL);
when(mMockPackageManager.checkUidPermission(
@@ -69,9 +86,11 @@ public class NotificationDataTest extends SysuiTestCase {
eq(UID_ALLOW_DURING_SETUP)))
.thenReturn(PackageManager.PERMISSION_GRANTED);
- NotificationData.Environment mock = mock(NotificationData.Environment.class);
- when(mock.getGroupManager()).thenReturn(new NotificationGroupManager());
- mNotificationData = new TestableNotificationData(mock);
+ mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
+ when(mEnvironment.getGroupManager()).thenReturn(new NotificationGroupManager());
+ when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
+ when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
+ mNotificationData = new TestableNotificationData(mEnvironment);
mNotificationData.updateRanking(mock(NotificationListenerService.RankingMap.class));
mRow = new NotificationTestHelper(getContext()).createRow();
}
@@ -117,6 +136,117 @@ public class NotificationDataTest extends SysuiTestCase {
Assert.assertTrue(mRow.getEntry().channel != null);
}
+ @Test
+ public void testAdd_appOpsAdded() {
+ ArraySet<Integer> expected = new ArraySet<>();
+ expected.add(3);
+ expected.add(235);
+ expected.add(1);
+ when(mFsc.getAppOps(mRow.getEntry().notification.getUserId(),
+ mRow.getEntry().notification.getPackageName())).thenReturn(expected);
+
+ mNotificationData.add(mRow.getEntry());
+ assertEquals(expected.size(),
+ mNotificationData.get(mRow.getEntry().key).mActiveAppOps.size());
+ for (int op : expected) {
+ assertTrue(" entry missing op " + op,
+ mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(op));
+ }
+ }
+
+ @Test
+ public void testAdd_noExistingAppOps() {
+ when(mFsc.getAppOps(mRow.getEntry().notification.getUserId(),
+ mRow.getEntry().notification.getPackageName())).thenReturn(null);
+
+ mNotificationData.add(mRow.getEntry());
+ assertEquals(0, mNotificationData.get(mRow.getEntry().key).mActiveAppOps.size());
+ }
+
+ @Test
+ public void testAllRelevantNotisTaggedWithAppOps() throws Exception {
+ mNotificationData.add(mRow.getEntry());
+ ExpandableNotificationRow row2 = new NotificationTestHelper(getContext()).createRow();
+ mNotificationData.add(row2.getEntry());
+ ExpandableNotificationRow diffPkg =
+ new NotificationTestHelper(getContext()).createRow("pkg", 4000);
+ mNotificationData.add(diffPkg.getEntry());
+
+ ArraySet<Integer> expectedOps = new ArraySet<>();
+ expectedOps.add(OP_CAMERA);
+ expectedOps.add(OP_ACCEPT_HANDOVER);
+
+ for (int op : expectedOps) {
+ mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
+ NotificationTestHelper.PKG, true);
+ }
+ for (int op : expectedOps) {
+ assertTrue(mRow.getEntry().key + " doesn't have op " + op,
+ mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(op));
+ assertTrue(row2.getEntry().key + " doesn't have op " + op,
+ mNotificationData.get(row2.getEntry().key).mActiveAppOps.contains(op));
+ assertFalse(diffPkg.getEntry().key + " has op " + op,
+ mNotificationData.get(diffPkg.getEntry().key).mActiveAppOps.contains(op));
+ }
+ }
+
+ @Test
+ public void testAppOpsRemoval() throws Exception {
+ mNotificationData.add(mRow.getEntry());
+ ExpandableNotificationRow row2 = new NotificationTestHelper(getContext()).createRow();
+ mNotificationData.add(row2.getEntry());
+
+ ArraySet<Integer> expectedOps = new ArraySet<>();
+ expectedOps.add(OP_CAMERA);
+ expectedOps.add(OP_ACCEPT_HANDOVER);
+
+ for (int op : expectedOps) {
+ mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
+ NotificationTestHelper.PKG, true);
+ }
+
+ expectedOps.remove(OP_ACCEPT_HANDOVER);
+ mNotificationData.updateAppOp(OP_ACCEPT_HANDOVER, NotificationTestHelper.UID,
+ NotificationTestHelper.PKG, false);
+
+ assertTrue(mRow.getEntry().key + " doesn't have op " + OP_CAMERA,
+ mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(OP_CAMERA));
+ assertTrue(row2.getEntry().key + " doesn't have op " + OP_CAMERA,
+ mNotificationData.get(row2.getEntry().key).mActiveAppOps.contains(OP_CAMERA));
+ assertFalse(mRow.getEntry().key + " has op " + OP_ACCEPT_HANDOVER,
+ mNotificationData.get(mRow.getEntry().key)
+ .mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
+ assertFalse(row2.getEntry().key + " has op " + OP_ACCEPT_HANDOVER,
+ mNotificationData.get(row2.getEntry().key)
+ .mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
+ }
+
+ @Test
+ public void testSuppressSystemAlertNotification() {
+ when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
+ when(mFsc.isSystemAlertNotification(any())).thenReturn(true);
+
+ assertTrue(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+ }
+
+ @Test
+ public void testDoNotSuppressSystemAlertNotification() {
+ when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true);
+ when(mFsc.isSystemAlertNotification(any())).thenReturn(true);
+
+ assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+
+ when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true);
+ when(mFsc.isSystemAlertNotification(any())).thenReturn(false);
+
+ assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+
+ when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
+ when(mFsc.isSystemAlertNotification(any())).thenReturn(false);
+
+ assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+ }
+
private void initStatusBarNotification(boolean allowDuringSetup) {
Bundle bundle = new Bundle();
bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
index f9ec3f92181f..37dd939ea70a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
@@ -23,14 +23,17 @@ import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
@@ -274,4 +277,40 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
assertNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
}
+
+ @Test
+ public void testUpdateAppOps_foregroundNoti() {
+ com.android.systemui.util.Assert.isNotMainThread();
+
+ when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
+ .thenReturn("something");
+ mEntry.row = mRow;
+ mEntryManager.getNotificationData().add(mEntry);
+
+
+ mHandler.post(() -> {
+ mEntryManager.updateNotificationsForAppOps(
+ AppOpsManager.OP_CAMERA, mEntry.notification.getUid(),
+ mEntry.notification.getPackageName(), true);
+ });
+ waitForIdleSync(mHandler);
+
+ verify(mPresenter, times(1)).updateNotificationViews();
+ assertTrue(mEntryManager.getNotificationData().get(mEntry.key).mActiveAppOps.contains(
+ AppOpsManager.OP_CAMERA));
+ }
+
+ @Test
+ public void testUpdateAppOps_otherNoti() {
+ com.android.systemui.util.Assert.isNotMainThread();
+
+ when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
+ .thenReturn(null);
+ mHandler.post(() -> {
+ mEntryManager.updateNotificationsForAppOps(AppOpsManager.OP_CAMERA, 1000, "pkg", true);
+ });
+ waitForIdleSync(mHandler);
+
+ verify(mPresenter, never()).updateNotificationViews();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index f3c1171f650c..27642544c129 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -48,6 +48,8 @@ public class NotificationTestHelper {
private ExpandableNotificationRow mRow;
private InflationException mException;
private HeadsUpManager mHeadsUpManager;
+ protected static final String PKG = "com.android.systemui";
+ protected static final int UID = 1000;
public NotificationTestHelper(Context context) {
mContext = context;
@@ -55,7 +57,7 @@ public class NotificationTestHelper {
mHeadsUpManager = new HeadsUpManagerPhone(mContext, null, mGroupManager, null, null);
}
- public ExpandableNotificationRow createRow() throws Exception {
+ public ExpandableNotificationRow createRow(String pkg, int uid) throws Exception {
Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
R.drawable.ic_person)
.setCustomContentView(new RemoteViews(mContext.getPackageName(),
@@ -67,10 +69,19 @@ public class NotificationTestHelper {
.setContentText("Text")
.setPublicVersion(publicVersion)
.build();
- return createRow(notification);
+ return createRow(notification, pkg, uid);
+ }
+
+ public ExpandableNotificationRow createRow() throws Exception {
+ return createRow(PKG, UID);
}
public ExpandableNotificationRow createRow(Notification notification) throws Exception {
+ return createRow(notification, PKG, UID);
+ }
+
+ public ExpandableNotificationRow createRow(Notification notification, String pkg, int uid)
+ throws Exception {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
mContext.LAYOUT_INFLATER_SERVICE);
mInstrumentation.runOnMainSync(() -> {
@@ -83,8 +94,7 @@ public class NotificationTestHelper {
row.setHeadsUpManager(mHeadsUpManager);
row.setAboveShelfChangedListener(aboveShelf -> {});
UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
- StatusBarNotification sbn = new StatusBarNotification("com.android.systemui",
- "com.android.systemui", mId++, null, 1000,
+ StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, mId++, null, uid,
2000, notification, mUser, null, System.currentTimeMillis());
NotificationData.Entry entry = new NotificationData.Entry(sbn);
entry.row = row;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index fbe730a64c6f..76ed45206dff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -19,6 +19,9 @@ package com.android.systemui.statusbar;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -170,6 +173,19 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
assertEquals(View.VISIBLE, entry1.row.getVisibility());
}
+ @Test
+ public void testUpdateNotificationViews_appOps() throws Exception {
+ NotificationData.Entry entry0 = createEntry();
+ entry0.row = spy(entry0.row);
+ when(mNotificationData.getActiveNotifications()).thenReturn(
+ Lists.newArrayList(entry0));
+ mListContainer.addContainerView(entry0.row);
+
+ mViewHierarchyManager.updateNotificationViews();
+
+ verify(entry0.row, times(1)).showAppOpsIcons(any());
+ }
+
private class FakeListContainer implements NotificationListContainer {
final LinearLayout mLayout = new LinearLayout(mContext);
final List<View> mRows = Lists.newArrayList();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 31442af5a04c..ff545f0bd653 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -69,6 +69,7 @@ import com.android.systemui.assist.AssistManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.AppOpsListener;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationData;
@@ -145,6 +146,7 @@ public class StatusBarTest extends SysuiTestCase {
mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
mDependency.injectTestDependency(NotificationListener.class, mNotificationListener);
mDependency.injectTestDependency(KeyguardMonitor.class, mock(KeyguardMonitorImpl.class));
+ mDependency.injectTestDependency(AppOpsListener.class, mock(AppOpsListener.class));
mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml
index a584a7f3fb90..c22b2e778ff1 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml
@@ -46,7 +46,8 @@
<bool name="config_fillMainBuiltInDisplayCutout">true</bool>
<!-- Height of the status bar -->
- <dimen name="status_bar_height">48dp</dimen>
+ <dimen name="status_bar_height_portrait">48dp</dimen>
+ <dimen name="status_bar_height_landscape">28dp</dimen>
<!-- Height of area above QQS where battery/time go (equal to status bar height if > 48dp) -->
<dimen name="quick_qs_offset_height">48dp</dimen>
<!-- Total height of QQS (quick_qs_offset_height + 128) -->
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml
index 915e16412155..401e09211ae7 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml
@@ -46,7 +46,8 @@
<bool name="config_fillMainBuiltInDisplayCutout">true</bool>
<!-- Height of the status bar -->
- <dimen name="status_bar_height">48dp</dimen>
+ <dimen name="status_bar_height_portrait">48dp</dimen>
+ <dimen name="status_bar_height_landscape">28dp</dimen>
<!-- Height of area above QQS where battery/time go (equal to status bar height if > 48dp) -->
<dimen name="quick_qs_offset_height">48dp</dimen>
<!-- Total height of QQS (quick_qs_offset_height + 128) -->
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml
index b8e29da8c8e7..f328b83c1cbf 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml
@@ -46,7 +46,8 @@
<bool name="config_fillMainBuiltInDisplayCutout">true</bool>
<!-- Height of the status bar -->
- <dimen name="status_bar_height">48dp</dimen>
+ <dimen name="status_bar_height_portrait">48dp</dimen>
+ <dimen name="status_bar_height_landscape">28dp</dimen>
<!-- Height of area above QQS where battery/time go (equal to status bar height if > 48dp) -->
<dimen name="quick_qs_offset_height">48dp</dimen>
<!-- Total height of QQS (quick_qs_offset_height + 128) -->
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index b897c7cc8873..6f31b0a22445 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5343,6 +5343,11 @@ message MetricsEvent {
// OS: P
ACTION_BATTERY_TIP_SHOWN = 1324;
+ // OPEN: Settings > Security & Location > Location > See all
+ // CATEGORY: SETTINGS
+ // OS: P
+ RECENT_LOCATION_REQUESTS_ALL = 1325;
+
// ---- End P Constants, all P constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 62a7b8feb19e..d17ca7f9e77a 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -2191,42 +2191,42 @@ class AlarmManagerService extends SystemService {
synchronized (mLock) {
final long nowRTC = System.currentTimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime();
- proto.write(AlarmManagerServiceProto.CURRENT_TIME, nowRTC);
- proto.write(AlarmManagerServiceProto.ELAPSED_REALTIME, nowElapsed);
- proto.write(AlarmManagerServiceProto.LAST_TIME_CHANGE_CLOCK_TIME,
+ proto.write(AlarmManagerServiceDumpProto.CURRENT_TIME, nowRTC);
+ proto.write(AlarmManagerServiceDumpProto.ELAPSED_REALTIME, nowElapsed);
+ proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_CLOCK_TIME,
mLastTimeChangeClockTime);
- proto.write(AlarmManagerServiceProto.LAST_TIME_CHANGE_REALTIME,
+ proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_REALTIME,
mLastTimeChangeRealtime);
- mConstants.dumpProto(proto, AlarmManagerServiceProto.SETTINGS);
+ mConstants.dumpProto(proto, AlarmManagerServiceDumpProto.SETTINGS);
if (mAppStateTracker != null) {
mAppStateTracker.dumpProto(proto,
- AlarmManagerServiceProto.FORCE_APP_STANDBY_TRACKER);
+ AlarmManagerServiceDumpProto.FORCE_APP_STANDBY_TRACKER);
}
- proto.write(AlarmManagerServiceProto.IS_INTERACTIVE, mInteractive);
+ proto.write(AlarmManagerServiceDumpProto.IS_INTERACTIVE, mInteractive);
if (!mInteractive) {
// Durations
- proto.write(AlarmManagerServiceProto.TIME_SINCE_NON_INTERACTIVE_MS,
+ proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_NON_INTERACTIVE_MS,
nowElapsed - mNonInteractiveStartTime);
- proto.write(AlarmManagerServiceProto.MAX_WAKEUP_DELAY_MS,
+ proto.write(AlarmManagerServiceDumpProto.MAX_WAKEUP_DELAY_MS,
currentNonWakeupFuzzLocked(nowElapsed));
- proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_DISPATCH_MS,
+ proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_DISPATCH_MS,
nowElapsed - mLastAlarmDeliveryTime);
- proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS,
+ proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS,
nowElapsed - mNextNonWakeupDeliveryTime);
}
- proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS,
+ proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS,
mNextNonWakeup - nowElapsed);
- proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_WAKEUP_MS,
+ proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_WAKEUP_MS,
mNextWakeup - nowElapsed);
- proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_MS,
+ proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_MS,
nowElapsed - mLastWakeup);
- proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_SET_MS,
+ proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_SET_MS,
nowElapsed - mLastWakeupSet);
- proto.write(AlarmManagerServiceProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged);
+ proto.write(AlarmManagerServiceDumpProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged);
final TreeSet<Integer> users = new TreeSet<>();
final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size();
@@ -2242,14 +2242,14 @@ class AlarmManagerService extends SystemService {
final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user);
final long time = next != null ? next.getTriggerTime() : 0;
final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user);
- final long aToken = proto.start(AlarmManagerServiceProto.NEXT_ALARM_CLOCK_METADATA);
+ final long aToken = proto.start(AlarmManagerServiceDumpProto.NEXT_ALARM_CLOCK_METADATA);
proto.write(AlarmClockMetadataProto.USER, user);
proto.write(AlarmClockMetadataProto.IS_PENDING_SEND, pendingSend);
proto.write(AlarmClockMetadataProto.TRIGGER_TIME_MS, time);
proto.end(aToken);
}
for (Batch b : mAlarmBatches) {
- b.writeToProto(proto, AlarmManagerServiceProto.PENDING_ALARM_BATCHES,
+ b.writeToProto(proto, AlarmManagerServiceDumpProto.PENDING_ALARM_BATCHES,
nowElapsed, nowRTC);
}
for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {
@@ -2257,66 +2257,66 @@ class AlarmManagerService extends SystemService {
if (blockedAlarms != null) {
for (Alarm a : blockedAlarms) {
a.writeToProto(proto,
- AlarmManagerServiceProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS,
+ AlarmManagerServiceDumpProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS,
nowElapsed, nowRTC);
}
}
}
if (mPendingIdleUntil != null) {
mPendingIdleUntil.writeToProto(
- proto, AlarmManagerServiceProto.PENDING_IDLE_UNTIL, nowElapsed, nowRTC);
+ proto, AlarmManagerServiceDumpProto.PENDING_IDLE_UNTIL, nowElapsed, nowRTC);
}
for (Alarm a : mPendingWhileIdleAlarms) {
- a.writeToProto(proto, AlarmManagerServiceProto.PENDING_WHILE_IDLE_ALARMS,
+ a.writeToProto(proto, AlarmManagerServiceDumpProto.PENDING_WHILE_IDLE_ALARMS,
nowElapsed, nowRTC);
}
if (mNextWakeFromIdle != null) {
- mNextWakeFromIdle.writeToProto(proto, AlarmManagerServiceProto.NEXT_WAKE_FROM_IDLE,
+ mNextWakeFromIdle.writeToProto(proto, AlarmManagerServiceDumpProto.NEXT_WAKE_FROM_IDLE,
nowElapsed, nowRTC);
}
for (Alarm a : mPendingNonWakeupAlarms) {
- a.writeToProto(proto, AlarmManagerServiceProto.PAST_DUE_NON_WAKEUP_ALARMS,
+ a.writeToProto(proto, AlarmManagerServiceDumpProto.PAST_DUE_NON_WAKEUP_ALARMS,
nowElapsed, nowRTC);
}
- proto.write(AlarmManagerServiceProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms);
- proto.write(AlarmManagerServiceProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime);
- proto.write(AlarmManagerServiceProto.MAX_DELAY_DURATION_MS, mMaxDelayTime);
- proto.write(AlarmManagerServiceProto.MAX_NON_INTERACTIVE_DURATION_MS,
+ proto.write(AlarmManagerServiceDumpProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms);
+ proto.write(AlarmManagerServiceDumpProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime);
+ proto.write(AlarmManagerServiceDumpProto.MAX_DELAY_DURATION_MS, mMaxDelayTime);
+ proto.write(AlarmManagerServiceDumpProto.MAX_NON_INTERACTIVE_DURATION_MS,
mNonInteractiveTime);
- proto.write(AlarmManagerServiceProto.BROADCAST_REF_COUNT, mBroadcastRefCount);
- proto.write(AlarmManagerServiceProto.PENDING_INTENT_SEND_COUNT, mSendCount);
- proto.write(AlarmManagerServiceProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount);
- proto.write(AlarmManagerServiceProto.LISTENER_SEND_COUNT, mListenerCount);
- proto.write(AlarmManagerServiceProto.LISTENER_FINISH_COUNT, mListenerFinishCount);
+ proto.write(AlarmManagerServiceDumpProto.BROADCAST_REF_COUNT, mBroadcastRefCount);
+ proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_SEND_COUNT, mSendCount);
+ proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount);
+ proto.write(AlarmManagerServiceDumpProto.LISTENER_SEND_COUNT, mListenerCount);
+ proto.write(AlarmManagerServiceDumpProto.LISTENER_FINISH_COUNT, mListenerFinishCount);
for (InFlight f : mInFlight) {
- f.writeToProto(proto, AlarmManagerServiceProto.OUTSTANDING_DELIVERIES);
+ f.writeToProto(proto, AlarmManagerServiceDumpProto.OUTSTANDING_DELIVERIES);
}
for (int i = 0; i < mLastAllowWhileIdleDispatch.size(); ++i) {
final long token = proto.start(
- AlarmManagerServiceProto.LAST_ALLOW_WHILE_IDLE_DISPATCH_TIMES);
+ AlarmManagerServiceDumpProto.LAST_ALLOW_WHILE_IDLE_DISPATCH_TIMES);
final int uid = mLastAllowWhileIdleDispatch.keyAt(i);
final long lastTime = mLastAllowWhileIdleDispatch.valueAt(i);
- proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.UID, uid);
- proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.TIME_MS, lastTime);
- proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.NEXT_ALLOWED_MS,
+ proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.UID, uid);
+ proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.TIME_MS, lastTime);
+ proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.NEXT_ALLOWED_MS,
lastTime + getWhileIdleMinIntervalLocked(uid));
proto.end(token);
}
for (int i = 0; i < mUseAllowWhileIdleShortTime.size(); i++) {
if (mUseAllowWhileIdleShortTime.valueAt(i)) {
- proto.write(AlarmManagerServiceProto.USE_ALLOW_WHILE_IDLE_SHORT_TIME,
+ proto.write(AlarmManagerServiceDumpProto.USE_ALLOW_WHILE_IDLE_SHORT_TIME,
mUseAllowWhileIdleShortTime.keyAt(i));
}
}
- mLog.writeToProto(proto, AlarmManagerServiceProto.RECENT_PROBLEMS);
+ mLog.writeToProto(proto, AlarmManagerServiceDumpProto.RECENT_PROBLEMS);
final FilterStats[] topFilters = new FilterStats[10];
final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {
@@ -2357,13 +2357,13 @@ class AlarmManagerService extends SystemService {
}
}
for (int i = 0; i < len; ++i) {
- final long token = proto.start(AlarmManagerServiceProto.TOP_ALARMS);
+ final long token = proto.start(AlarmManagerServiceDumpProto.TOP_ALARMS);
FilterStats fs = topFilters[i];
- proto.write(AlarmManagerServiceProto.TopAlarm.UID, fs.mBroadcastStats.mUid);
- proto.write(AlarmManagerServiceProto.TopAlarm.PACKAGE_NAME,
+ proto.write(AlarmManagerServiceDumpProto.TopAlarm.UID, fs.mBroadcastStats.mUid);
+ proto.write(AlarmManagerServiceDumpProto.TopAlarm.PACKAGE_NAME,
fs.mBroadcastStats.mPackageName);
- fs.writeToProto(proto, AlarmManagerServiceProto.TopAlarm.FILTER);
+ fs.writeToProto(proto, AlarmManagerServiceDumpProto.TopAlarm.FILTER);
proto.end(token);
}
@@ -2372,10 +2372,10 @@ class AlarmManagerService extends SystemService {
for (int iu = 0; iu < mBroadcastStats.size(); ++iu) {
ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
for (int ip = 0; ip < uidStats.size(); ++ip) {
- final long token = proto.start(AlarmManagerServiceProto.ALARM_STATS);
+ final long token = proto.start(AlarmManagerServiceDumpProto.ALARM_STATS);
BroadcastStats bs = uidStats.valueAt(ip);
- bs.writeToProto(proto, AlarmManagerServiceProto.AlarmStat.BROADCAST);
+ bs.writeToProto(proto, AlarmManagerServiceDumpProto.AlarmStat.BROADCAST);
// uidStats is an ArrayMap, which we can't sort.
tmpFilters.clear();
@@ -2384,7 +2384,7 @@ class AlarmManagerService extends SystemService {
}
Collections.sort(tmpFilters, comparator);
for (FilterStats fs : tmpFilters) {
- fs.writeToProto(proto, AlarmManagerServiceProto.AlarmStat.FILTERS);
+ fs.writeToProto(proto, AlarmManagerServiceDumpProto.AlarmStat.FILTERS);
}
proto.end(token);
@@ -2395,7 +2395,7 @@ class AlarmManagerService extends SystemService {
for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) {
IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i);
final long token = proto.start(
- AlarmManagerServiceProto.ALLOW_WHILE_IDLE_DISPATCHES);
+ AlarmManagerServiceDumpProto.ALLOW_WHILE_IDLE_DISPATCHES);
proto.write(IdleDispatchEntryProto.UID, ent.uid);
proto.write(IdleDispatchEntryProto.PKG, ent.pkg);
@@ -2411,7 +2411,7 @@ class AlarmManagerService extends SystemService {
if (WAKEUP_STATS) {
for (WakeupEvent event : mRecentWakeups) {
- final long token = proto.start(AlarmManagerServiceProto.RECENT_WAKEUP_HISTORY);
+ final long token = proto.start(AlarmManagerServiceDumpProto.RECENT_WAKEUP_HISTORY);
proto.write(WakeupEventProto.UID, event.uid);
proto.write(WakeupEventProto.ACTION, event.action);
proto.write(WakeupEventProto.WHEN, event.when);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5fc43732b404..0c6746e15988 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3861,8 +3861,9 @@ public final class ActiveServices {
return new ServiceDumper(fd, pw, args, opti, dumpAll, dumpPackage);
}
- protected void writeToProto(ProtoOutputStream proto) {
+ protected void writeToProto(ProtoOutputStream proto, long fieldId) {
synchronized (mAm) {
+ final long outterToken = proto.start(fieldId);
int[] users = mAm.mUserController.getUsers();
for (int user : users) {
ServiceMap smap = mServiceMap.get(user);
@@ -3878,6 +3879,7 @@ public final class ActiveServices {
}
proto.end(token);
}
+ proto.end(outterToken);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f4b0dba9d860..28a79bdb79c8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -440,15 +440,17 @@ import com.android.server.Watchdog;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.am.MemoryStatUtil.MemoryStat;
import com.android.server.am.proto.ActivityManagerServiceProto;
-import com.android.server.am.proto.BroadcastProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpActivitiesProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpBroadcastsProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpServicesProto;
import com.android.server.am.proto.GrantUriProto;
import com.android.server.am.proto.ImportanceTokenProto;
-import com.android.server.am.proto.MemInfoProto;
+import com.android.server.am.proto.MemInfoDumpProto;
import com.android.server.am.proto.NeededUriGrantsProto;
import com.android.server.am.proto.ProcessOomProto;
import com.android.server.am.proto.ProcessToGcProto;
-import com.android.server.am.proto.ProcessesProto;
-import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
import com.android.server.am.proto.StickyBroadcastProto;
import com.android.server.firewall.IntentFirewall;
import com.android.server.job.JobSchedulerInternal;
@@ -1376,9 +1378,9 @@ public class ActivityManagerService extends IActivityManager.Stub
void writeToProto(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
- proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
- proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
+ proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
+ proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
+ proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
proto.end(token);
}
}
@@ -12879,6 +12881,25 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public boolean isBackgroundRestricted(String packageName) {
+ final int callingUid = Binder.getCallingUid();
+ final IPackageManager pm = AppGlobals.getPackageManager();
+ try {
+ final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
+ UserHandle.getUserId(callingUid));
+ if (packageUid != callingUid) {
+ throw new IllegalArgumentException("Uid " + callingUid
+ + " cannot query restriction state for package " + packageName);
+ }
+ } catch (RemoteException exc) {
+ // Ignore.
+ }
+ final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
+ callingUid, packageName);
+ return (mode != AppOpsManager.MODE_ALLOWED);
+ }
+
+ @Override
public void backgroundWhitelistUid(final int uid) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
@@ -15754,12 +15775,12 @@ public class ActivityManagerService extends IActivityManager.Stub
opti++;
if ("activities".equals(cmd) || "a".equals(cmd)) {
- // output proto is ActivityStackSupervisorProto
+ // output proto is ActivityManagerServiceDumpActivitiesProto
synchronized (this) {
writeActivitiesToProtoLocked(proto);
}
} else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
- // output proto is BroadcastProto
+ // output proto is ActivityManagerServiceDumpBroadcastsProto
synchronized (this) {
writeBroadcastsToProtoLocked(proto);
}
@@ -15781,7 +15802,8 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.println("Use -h for help.");
}
} else if ("service".equals(cmd)) {
- mServices.writeToProto(proto);
+ // output proto is ActivityManagerServiceDumpServicesProto
+ mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
} else if ("processes".equals(cmd) || "p".equals(cmd)) {
if (opti < args.length) {
dumpPackage = args[opti];
@@ -15803,7 +15825,7 @@ public class ActivityManagerService extends IActivityManager.Stub
proto.end(broadcastToken);
long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
- mServices.writeToProto(proto);
+ mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
proto.end(serviceToken);
long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
@@ -16166,8 +16188,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
- // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
- mStackSupervisor.writeToProto(proto);
+ // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
+ mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
}
private void dumpLastANRLocked(PrintWriter pw) {
@@ -16864,7 +16886,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
- r.writeToProto(proto, ProcessesProto.PROCS);
+ r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
if (r.persistent) {
numPers++;
}
@@ -16876,7 +16898,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
continue;
}
- r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
+ r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
}
for (int i=0; i<mActiveInstrumentation.size(); i++) {
@@ -16885,7 +16907,7 @@ public class ActivityManagerService extends IActivityManager.Stub
&& !ai.mTargetInfo.packageName.equals(dumpPackage)) {
continue;
}
- ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
+ ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
}
int whichAppId = getAppId(dumpPackage);
@@ -16894,7 +16916,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
continue;
}
- uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
+ uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
}
for (int i=0; i<mValidateUids.size(); i++) {
@@ -16902,16 +16924,16 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
continue;
}
- uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
+ uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
}
if (mLruProcesses.size() > 0) {
- long lruToken = proto.start(ProcessesProto.LRU_PROCS);
+ long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
int total = mLruProcesses.size();
- proto.write(ProcessesProto.LruProcesses.SIZE, total);
- proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
- proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
- writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
+ proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
+ proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
+ proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
+ writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
mLruProcesses,false, dumpPackage);
proto.end(lruToken);
}
@@ -16923,7 +16945,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (!r.pkgList.containsKey(dumpPackage)) {
continue;
}
- r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
+ r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
}
}
}
@@ -16937,7 +16959,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|| !r.pkgList.containsKey(dumpPackage))) {
continue;
}
- it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
+ it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
}
}
}
@@ -16947,7 +16969,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
continue;
}
- r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
+ r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
}
for (int i=0; i<mRemovedProcesses.size(); i++) {
@@ -16955,7 +16977,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
continue;
}
- r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
+ r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
}
for (int i=0; i<mProcessesOnHold.size(); i++) {
@@ -16963,41 +16985,41 @@ public class ActivityManagerService extends IActivityManager.Stub
if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
continue;
}
- r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
+ r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
}
- writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
- mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
+ writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
+ mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
if (dumpPackage == null) {
- mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
- getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
- proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
+ mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
+ getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
+ proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
}
if (mHomeProcess != null && (dumpPackage == null
|| mHomeProcess.pkgList.containsKey(dumpPackage))) {
- mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
+ mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
}
if (mPreviousProcess != null && (dumpPackage == null
|| mPreviousProcess.pkgList.containsKey(dumpPackage))) {
- mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
- proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
+ mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
+ proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
}
if (mHeavyWeightProcess != null && (dumpPackage == null
|| mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
- mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
+ mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
}
for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
String pkg = entry.getKey();
int mode = entry.getValue();
if (dumpPackage == null || dumpPackage.equals(pkg)) {
- long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
- proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
- proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
+ long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
+ proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
+ proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
proto.end(compatToken);
}
}
@@ -17007,89 +17029,89 @@ public class ActivityManagerService extends IActivityManager.Stub
final UidObserverRegistration reg = (UidObserverRegistration)
mUidObservers.getRegisteredCallbackCookie(i);
if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
- reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
+ reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
}
}
for (int v : mDeviceIdleWhitelist) {
- proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
+ proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
}
for (int v : mDeviceIdleTempWhitelist) {
- proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
+ proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
}
if (mPendingTempWhitelist.size() > 0) {
for (int i=0; i < mPendingTempWhitelist.size(); i++) {
mPendingTempWhitelist.valueAt(i).writeToProto(proto,
- ProcessesProto.PENDING_TEMP_WHITELIST);
+ ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
}
}
if (dumpPackage == null) {
- final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
- proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
+ final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
for (SleepToken st : mStackSupervisor.mSleepTokens) {
- proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
}
- proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
- proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
- proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
proto.end(sleepToken);
if (mRunningVoice != null) {
- final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
- proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
- mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
+ final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
+ proto.write(ActivityManagerServiceDumpProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
+ mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VoiceProto.WAKELOCK);
proto.end(vrToken);
}
- mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
+ mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
}
if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
|| mOrigWaitForDebugger) {
if (dumpPackage == null || dumpPackage.equals(mDebugApp)
|| dumpPackage.equals(mOrigDebugApp)) {
- final long debugAppToken = proto.start(ProcessesProto.DEBUG);
- proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
- proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
- proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
- proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
+ final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
+ proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
+ proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
+ proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
+ proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
proto.end(debugAppToken);
}
}
if (mCurAppTimeTracker != null) {
- mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
+ mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
}
if (mMemWatchProcesses.getMap().size() > 0) {
- final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
+ final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
for (int i=0; i<procs.size(); i++) {
final String proc = procs.keyAt(i);
final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
- final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
- proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
+ final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
for (int j=0; j<uids.size(); j++) {
- final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
+ final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
Pair<Long, String> val = uids.valueAt(j);
- proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
- proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
DebugUtils.sizeValueToString(val.first, new StringBuilder()));
- proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
proto.end(utoken);
}
proto.end(ptoken);
}
- final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
- proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
- proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
- proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
- proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
+ final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
proto.end(dtoken);
proto.end(token);
@@ -17097,58 +17119,58 @@ public class ActivityManagerService extends IActivityManager.Stub
if (mTrackAllocationApp != null) {
if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
- proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
+ proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
}
}
if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
(mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
- final long token = proto.start(ProcessesProto.PROFILE);
- proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
- mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
+ final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
+ proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
+ mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
if (mProfilerInfo != null) {
- mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
- proto.write(ProcessesProto.Profile.TYPE, mProfileType);
+ mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
+ proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
}
proto.end(token);
}
}
if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
- proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
+ proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
}
if (dumpPackage == null) {
- proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
+ proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
if (mController != null) {
- final long token = proto.start(ProcessesProto.CONTROLLER);
- proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
- proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
+ final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
+ proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
+ proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
proto.end(token);
}
- proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
- proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
- proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
- proto.write(ProcessesProto.BOOTED, mBooted);
- proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
- proto.write(ProcessesProto.BOOTING, mBooting);
- proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
- proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
- proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
- mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
- mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
- proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
- proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
- proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
- proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
- proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
- proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
- proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
- proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
+ proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
+ proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
+ proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
+ proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
+ proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
+ proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
+ proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
+ proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
+ proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
+ mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
+ mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
+ proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
+ proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
+ proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
+ proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
+ proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
+ proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
+ proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
+ proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
long now = SystemClock.uptimeMillis();
- ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
- proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
+ ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
+ proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
}
}
@@ -17458,15 +17480,15 @@ public class ActivityManagerService extends IActivityManager.Stub
Iterator it = mRegisteredReceivers.values().iterator();
while (it.hasNext()) {
ReceiverList r = (ReceiverList)it.next();
- r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
+ r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
}
}
- mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
+ mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
for (BroadcastQueue q : mBroadcastQueues) {
- q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
+ q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
}
for (int user=0; user<mStickyBroadcasts.size(); user++) {
- long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
+ long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
for (Map.Entry<String, ArrayList<Intent>> ent
: mStickyBroadcasts.valueAt(user).entrySet()) {
@@ -17481,9 +17503,10 @@ public class ActivityManagerService extends IActivityManager.Stub
proto.end(token);
}
- long handlerToken = proto.start(BroadcastProto.HANDLER);
- proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
- mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
+ long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
+ proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
+ mHandler.getLooper().writeToProto(proto,
+ ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
proto.end(handlerToken);
}
@@ -18245,17 +18268,17 @@ public class ActivityManagerService extends IActivityManager.Stub
MemItem mi = items.get(i);
final long token = proto.start(fieldId);
- proto.write(MemInfoProto.MemItem.TAG, tag);
- proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
- proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
- proto.write(MemInfoProto.MemItem.ID, mi.id);
- proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
- proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
+ proto.write(MemInfoDumpProto.MemItem.TAG, tag);
+ proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
+ proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
+ proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
+ proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
+ proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
if (dumpSwapPss) {
- proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
+ proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
}
if (mi.subitems != null) {
- dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
+ dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
true, dumpSwapPss);
}
proto.end(token);
@@ -19009,16 +19032,16 @@ public class ActivityManagerService extends IActivityManager.Stub
if (nativeProcs.size() > 0) {
ProtoOutputStream proto = new ProtoOutputStream(fd);
- proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
- proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
+ proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
+ proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
Debug.MemoryInfo mi = null;
for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
final ProcessCpuTracker.Stats r = nativeProcs.get(i);
final int pid = r.pid;
- final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
+ final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
- proto.write(MemInfoProto.ProcessMemory.PID, pid);
- proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
+ proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
+ proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
if (mi == null) {
mi = new Debug.MemoryInfo();
@@ -19050,8 +19073,8 @@ public class ActivityManagerService extends IActivityManager.Stub
ProtoOutputStream proto = new ProtoOutputStream(fd);
- proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
- proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
+ proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
+ proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
ArrayList<MemItem> procMems = new ArrayList<MemItem>();
final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
@@ -19116,10 +19139,10 @@ public class ActivityManagerService extends IActivityManager.Stub
}
if (opts.dumpDetails) {
if (opts.localOnly) {
- final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
- final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
- proto.write(MemInfoProto.ProcessMemory.PID, pid);
- proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
+ final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
+ final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
+ proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
+ proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
proto.end(mToken);
@@ -19131,7 +19154,7 @@ public class ActivityManagerService extends IActivityManager.Stub
thread.dumpMemInfoProto(tp.getWriteFd(),
mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
opts.dumpUnreachable, innerArgs);
- proto.write(MemInfoProto.APP_PROCESSES, tp.get());
+ proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
} finally {
tp.kill();
}
@@ -19319,13 +19342,13 @@ public class ActivityManagerService extends IActivityManager.Stub
opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
if (!opts.oomOnly) {
- dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
+ dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
procMems, true, opts.dumpSwapPss);
}
- dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
+ dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
oomMems, false, opts.dumpSwapPss);
if (!brief && !opts.oomOnly) {
- dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
+ dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
catMems, true, opts.dumpSwapPss);
}
MemInfoReader memInfo = new MemInfoReader();
@@ -19343,40 +19366,40 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
if (!brief) {
- proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
- proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
- proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
- proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
- proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
+ proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
+ proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
+ proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
+ proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
+ proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
}
long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
- proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
- proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
- proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
+ proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
+ proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
+ proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
if (!brief) {
if (memInfo.getZramTotalSizeKb() != 0) {
- proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
- proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
+ proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
+ proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
- proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
+ proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
}
final long[] ksm = getKsmInfo();
- proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
- proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
- proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
- proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
-
- proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
- proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
- proto.write(MemInfoProto.OOM_KB,
+ proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
+ proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
+ proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
+ proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
+
+ proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
+ proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
+ proto.write(MemInfoDumpProto.OOM_KB,
mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
- proto.write(MemInfoProto.RESTORE_LIMIT_KB,
+ proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
mProcessList.getCachedRestoreThresholdKb());
- proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
- proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
+ proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
+ proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 3d7c9d207f38..81dae394c792 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -51,6 +51,7 @@ import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
+import android.opengl.GLES10;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -82,16 +83,18 @@ import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
-import java.util.Map;
+import java.util.Set;
import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.opengles.GL;
-import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
import static android.app.ActivityManager.RESIZE_MODE_USER;
@@ -1858,6 +1861,137 @@ final class ActivityManagerShellCommand extends ShellCommand {
}
}
+ /**
+ * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
+ * and EGLSurface and querying extensions.
+ *
+ * @param egl An EGL API object
+ * @param display An EGLDisplay to create a context and surface with
+ * @param config The EGLConfig to get the extensions for
+ * @param surfaceSize eglCreatePbufferSurface generic parameters
+ * @param contextAttribs eglCreateContext generic parameters
+ * @param glExtensions A Set<String> to add GL extensions to
+ */
+ private static void addExtensionsForConfig(
+ EGL10 egl,
+ EGLDisplay display,
+ EGLConfig config,
+ int[] surfaceSize,
+ int[] contextAttribs,
+ Set<String> glExtensions) {
+ // Create a context.
+ EGLContext context =
+ egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
+ // No-op if we can't create a context.
+ if (context == EGL10.EGL_NO_CONTEXT) {
+ return;
+ }
+
+ // Create a surface.
+ EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
+ if (surface == EGL10.EGL_NO_SURFACE) {
+ egl.eglDestroyContext(display, context);
+ return;
+ }
+
+ // Update the current surface and context.
+ egl.eglMakeCurrent(display, surface, surface, context);
+
+ // Get the list of extensions.
+ String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
+ if (!TextUtils.isEmpty(extensionList)) {
+ // The list of extensions comes from the driver separated by spaces.
+ // Split them apart and add them into a Set for deduping purposes.
+ for (String extension : extensionList.split(" ")) {
+ glExtensions.add(extension);
+ }
+ }
+
+ // Tear down the context and surface for this config.
+ egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+ egl.eglDestroySurface(display, surface);
+ egl.eglDestroyContext(display, context);
+ }
+
+
+ Set<String> getGlExtensionsFromDriver() {
+ Set<String> glExtensions = new HashSet<>();
+
+ // Get the EGL implementation.
+ EGL10 egl = (EGL10) EGLContext.getEGL();
+ if (egl == null) {
+ getErrPrintWriter().println("Warning: couldn't get EGL");
+ return glExtensions;
+ }
+
+ // Get the default display and initialize it.
+ EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+ int[] version = new int[2];
+ egl.eglInitialize(display, version);
+
+ // Call getConfigs() in order to find out how many there are.
+ int[] numConfigs = new int[1];
+ if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
+ getErrPrintWriter().println("Warning: couldn't get EGL config count");
+ return glExtensions;
+ }
+
+ // Allocate space for all configs and ask again.
+ EGLConfig[] configs = new EGLConfig[numConfigs[0]];
+ if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
+ getErrPrintWriter().println("Warning: couldn't get EGL configs");
+ return glExtensions;
+ }
+
+ // Allocate surface size parameters outside of the main loop to cut down
+ // on GC thrashing. 1x1 is enough since we are only using it to get at
+ // the list of extensions.
+ int[] surfaceSize =
+ new int[] {
+ EGL10.EGL_WIDTH, 1,
+ EGL10.EGL_HEIGHT, 1,
+ EGL10.EGL_NONE
+ };
+
+ // For when we need to create a GLES2.0 context.
+ final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
+
+ // For getting return values from eglGetConfigAttrib
+ int[] attrib = new int[1];
+
+ for (int i = 0; i < numConfigs[0]; i++) {
+ // Get caveat for this config in order to skip slow (i.e. software) configs.
+ egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
+ if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
+ continue;
+ }
+
+ // If the config does not support pbuffers we cannot do an eglMakeCurrent
+ // on it in addExtensionsForConfig(), so skip it here. Attempting to make
+ // it current with a pbuffer will result in an EGL_BAD_MATCH error
+ egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
+ if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
+ continue;
+ }
+
+ final int EGL_OPENGL_ES_BIT = 0x0001;
+ final int EGL_OPENGL_ES2_BIT = 0x0004;
+ egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
+ if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
+ addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
+ }
+ if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
+ addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
+ }
+ }
+
+ // Release all EGL resources.
+ egl.eglTerminate(display);
+
+ return glExtensions;
+ }
+
private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
PrintWriter pw, Configuration config, DisplayManager dm) {
Point stableSize = dm.getStableDisplaySize();
@@ -1906,18 +2040,24 @@ final class ActivityManagerShellCommand extends ShellCommand {
}
}
- /*
- GL10 gl = ((GL10)((EGL10)EGLContext.getEGL()).eglGetCurrentContext().getGL());
- protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
- gl.glGetString(GL10.GL_VERSION));
- String glExtensions = gl.glGetString(GL10.GL_EXTENSIONS);
- for (String ext : glExtensions.split(" ")) {
- protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS, ext);
+ Set<String> glExtensionsSet = getGlExtensionsFromDriver();
+ String[] glExtensions = new String[glExtensionsSet.size()];
+ glExtensions = glExtensionsSet.toArray(glExtensions);
+ Arrays.sort(glExtensions);
+ for (int i = 0; i < glExtensions.length; i++) {
+ if (protoOutputStream != null) {
+ protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
+ glExtensions[i]);
+ }
+ if (pw != null) {
+ pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
+ }
+
}
- */
PackageManager pm = mInternal.mContext.getPackageManager();
List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
+ Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
for (int i = 0; i < slibs.size(); i++) {
if (protoOutputStream != null) {
protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
@@ -1929,6 +2069,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
}
FeatureInfo[] features = pm.getSystemAvailableFeatures();
+ Arrays.sort(features, (o1, o2) ->
+ (o1.name == o2.name ? 0 : (o1.name == null ? -1 : o1.name.compareTo(o2.name))));
for (int i = 0; i < features.length; i++) {
if (features[i].name != null) {
if (protoOutputStream != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 0157c7c3fd9a..26ffe9529982 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3777,7 +3777,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
mService.mLockTaskController.dump(pw, prefix);
}
- public void writeToProto(ProtoOutputStream proto) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
@@ -3795,6 +3796,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
proto.write(IS_HOME_RECENTS_COMPONENT,
mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
+ proto.end(token);
}
/**
diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java
index d32db7ea2ed9..9d34a8020345 100644
--- a/services/core/java/com/android/server/am/VrController.java
+++ b/services/core/java/com/android/server/am/VrController.java
@@ -24,7 +24,7 @@ import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;
import com.android.server.LocalServices;
-import com.android.server.am.proto.ProcessesProto.VrControllerProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto.VrControllerProto;
import com.android.server.vr.VrManagerInternal;
/**
diff --git a/services/core/java/com/android/server/media/MediaUpdateService.java b/services/core/java/com/android/server/media/MediaUpdateService.java
index 6921ccde250c..f38b35342f3a 100644
--- a/services/core/java/com/android/server/media/MediaUpdateService.java
+++ b/services/core/java/com/android/server/media/MediaUpdateService.java
@@ -16,27 +16,21 @@
package com.android.server.media;
-import android.content.Context;
-import android.content.Intent;
-import android.media.IMediaResourceMonitor;
-import android.os.Binder;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import android.util.Slog;
-import com.android.server.SystemService;
-
import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.media.IMediaExtractorUpdateService;
import android.os.IBinder;
+import android.os.Handler;
import android.os.PatternMatcher;
import android.os.ServiceManager;
-import android.media.IMediaExtractorUpdateService;
-
-import java.lang.Exception;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+import com.android.server.SystemService;
/** This class provides a system service that manages media framework updates. */
public class MediaUpdateService extends SystemService {
@@ -46,9 +40,11 @@ public class MediaUpdateService extends SystemService {
private static final String EXTRACTOR_UPDATE_SERVICE_NAME = "media.extractor.update";
private IMediaExtractorUpdateService mMediaExtractorUpdateService;
+ final Handler mHandler;
public MediaUpdateService(Context context) {
super(context);
+ mHandler = new Handler();
}
@Override
@@ -77,7 +73,12 @@ public class MediaUpdateService extends SystemService {
}
if (binder != null) {
mMediaExtractorUpdateService = IMediaExtractorUpdateService.Stub.asInterface(binder);
- packageStateChanged();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ packageStateChanged();
+ }
+ });
} else {
Slog.w(TAG, EXTRACTOR_UPDATE_SERVICE_NAME + " not found.");
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7efc9876993b..2f1fbf9c5fb4 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -485,7 +485,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mSafeMode;
private final ArraySet<WindowState> mScreenDecorWindows = new ArraySet<>();
WindowState mStatusBar = null;
- int mStatusBarHeight;
+ private final int[] mStatusBarHeightForRotation = new int[4];
WindowState mNavigationBar = null;
boolean mHasNavigationBar = false;
boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side?
@@ -2768,8 +2768,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Context uiContext = getSystemUiContext();
final Resources res = uiContext.getResources();
- mStatusBarHeight =
- res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ mStatusBarHeightForRotation[mPortraitRotation] =
+ mStatusBarHeightForRotation[mUpsideDownRotation] = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height_portrait);
+ mStatusBarHeightForRotation[mLandscapeRotation] =
+ mStatusBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height_landscape);
// Height of the navigation bar when presented horizontally at bottom
mNavigationBarHeightForRotationDefault[mPortraitRotation] =
@@ -2884,11 +2888,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// of the screen.
// TODO(multi-display): Support status bars on secondary displays.
if (displayId == DEFAULT_DISPLAY) {
- int statusBarHeight = mStatusBarHeight;
+ int statusBarHeight = mStatusBarHeightForRotation[rotation];
if (displayCutout != null) {
// If there is a cutout, it may already have accounted for some part of the status
// bar height.
- statusBarHeight = Math.max(0, mStatusBarHeight - displayCutout.getSafeInsetTop());
+ statusBarHeight = Math.max(0, statusBarHeight - displayCutout.getSafeInsetTop());
}
return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId,
displayCutout) - statusBarHeight;
@@ -4649,7 +4653,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
displayFrames.mDisplayCutout);
// For layout, the status bar is always at the top with our fixed height.
- displayFrames.mStable.top = displayFrames.mUnrestricted.top + mStatusBarHeight;
+ displayFrames.mStable.top = displayFrames.mUnrestricted.top
+ + mStatusBarHeightForRotation[displayFrames.mRotation];
boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
boolean statusBarTranslucent = (sysui
@@ -6938,7 +6943,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Navigation bar and status bar.
getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, displayCutout, outInsets);
- outInsets.top = Math.max(outInsets.top, mStatusBarHeight);
+ outInsets.top = Math.max(outInsets.top, mStatusBarHeightForRotation[displayRotation]);
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1521afc1b059..bab4399d76ad 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -100,15 +100,15 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSA
import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.proto.WindowManagerServiceProto.APP_TRANSITION;
-import static com.android.server.wm.proto.WindowManagerServiceProto.DISPLAY_FROZEN;
-import static com.android.server.wm.proto.WindowManagerServiceProto.FOCUSED_APP;
-import static com.android.server.wm.proto.WindowManagerServiceProto.FOCUSED_WINDOW;
-import static com.android.server.wm.proto.WindowManagerServiceProto.INPUT_METHOD_WINDOW;
-import static com.android.server.wm.proto.WindowManagerServiceProto.LAST_ORIENTATION;
-import static com.android.server.wm.proto.WindowManagerServiceProto.POLICY;
-import static com.android.server.wm.proto.WindowManagerServiceProto.ROOT_WINDOW_CONTAINER;
-import static com.android.server.wm.proto.WindowManagerServiceProto.ROTATION;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.APP_TRANSITION;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.FOCUSED_APP;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.FOCUSED_WINDOW;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.LAST_ORIENTATION;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.POLICY;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.ROTATION;
import android.Manifest;
import android.Manifest.permission;
@@ -6195,7 +6195,7 @@ public class WindowManagerService extends IWindowManager.Stub
/**
* Write to a protocol buffer output stream. Protocol buffer message definition is at
- * {@link com.android.server.wm.proto.WindowManagerServiceProto}.
+ * {@link com.android.server.wm.proto.WindowManagerServiceDumpProto}.
*
* @param proto Stream to write the WindowContainer object to.
* @param trim If true, reduce the amount of data written.
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
index 30ca9caf56de..1d4348c0b6d4 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
@@ -77,7 +77,9 @@ public class PhoneWindowManagerTestBase {
public void setUpBase() throws Exception {
mContext = new TestContextWrapper(InstrumentationRegistry.getTargetContext());
mContext.getResourceMocker().addOverride(
- com.android.internal.R.dimen.status_bar_height, STATUS_BAR_HEIGHT);
+ com.android.internal.R.dimen.status_bar_height_portrait, STATUS_BAR_HEIGHT);
+ mContext.getResourceMocker().addOverride(
+ com.android.internal.R.dimen.status_bar_height_landscape, STATUS_BAR_HEIGHT);
mContext.getResourceMocker().addOverride(
com.android.internal.R.dimen.navigation_bar_height, NAV_BAR_HEIGHT);
mContext.getResourceMocker().addOverride(