summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt4
-rw-r--r--api/removed.txt62
-rw-r--r--api/system-current.txt19
-rw-r--r--api/system-removed.txt59
-rw-r--r--api/test-current.txt4
-rw-r--r--api/test-removed.txt62
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java2
-rw-r--r--core/java/android/content/pm/PackageManager.java1
-rw-r--r--core/java/android/content/pm/PackageParser.java49
-rw-r--r--core/java/android/content/pm/SharedLibraryInfo.java3
-rw-r--r--core/java/android/net/INetworkPolicyManager.aidl2
-rw-r--r--core/java/android/os/BatteryStats.java36
-rw-r--r--core/java/android/os/Build.java10
-rw-r--r--core/java/android/os/INetworkManagementService.aidl2
-rw-r--r--core/java/android/os/MemoryFile.java2
-rw-r--r--core/java/android/os/SharedMemory.java7
-rw-r--r--core/java/android/provider/ContactsContract.java7
-rw-r--r--core/java/android/service/autofill/CharSequenceTransformation.java11
-rw-r--r--core/java/android/service/autofill/ImageTransformation.java3
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java10
-rw-r--r--core/java/com/android/internal/os/ClassLoaderFactory.java2
-rw-r--r--core/jni/AndroidRuntime.cpp6
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--core/res/res/values-mcc262-mnc02/strings.xml27
-rw-r--r--core/res/res/values/arrays.xml4
-rw-r--r--core/res/res/values/config.xml11
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--data/sounds/effects/InCallNotification.oggbin0 -> 6275 bytes
-rw-r--r--data/sounds/effects/ogg/InCallNotification.oggbin0 -> 6275 bytes
-rw-r--r--dirty-image-objects176
-rw-r--r--libs/hwui/Caches.cpp10
-rw-r--r--libs/hwui/Caches.h7
-rw-r--r--libs/hwui/DeviceInfo.cpp12
-rw-r--r--libs/hwui/DeviceInfo.h13
-rw-r--r--libs/hwui/FboCache.cpp2
-rw-r--r--libs/hwui/FontRenderer.cpp23
-rw-r--r--libs/hwui/GradientCache.cpp7
-rw-r--r--libs/hwui/GradientCache.h2
-rw-r--r--libs/hwui/PatchCache.cpp2
-rw-r--r--libs/hwui/PathCache.cpp17
-rw-r--r--libs/hwui/ProgramCache.cpp2
-rw-r--r--libs/hwui/ProgramCache.h2
-rw-r--r--libs/hwui/Properties.cpp38
-rw-r--r--libs/hwui/Properties.h89
-rw-r--r--libs/hwui/RenderBufferCache.cpp10
-rw-r--r--libs/hwui/TessellationCache.cpp2
-rw-r--r--libs/hwui/TextDropShadowCache.cpp2
-rw-r--r--libs/hwui/TextureCache.cpp10
-rw-r--r--libs/hwui/font/FontUtil.h5
-rw-r--r--libs/hwui/renderstate/OffscreenBufferPool.cpp4
-rw-r--r--libs/hwui/renderstate/RenderState.cpp13
-rw-r--r--libs/hwui/renderstate/RenderState.h4
-rw-r--r--libs/hwui/renderstate/Stencil.cpp2
-rw-r--r--libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp4
-rw-r--r--media/java/android/media/tv/TvView.java13
-rw-r--r--native/android/libandroid.map.txt1
-rw-r--r--native/android/sharedmem.cpp43
-rw-r--r--packages/SystemUI/res/values/strings.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java63
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java3
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java64
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java2
-rw-r--r--services/core/java/com/android/server/am/UserController.java9
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java53
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java20
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java11
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java78
-rw-r--r--services/core/java/com/android/server/notification/GroupHelper.java8
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java92
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java100
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java2
-rw-r--r--services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java15
-rw-r--r--services/tests/notification/src/com/android/server/notification/GroupHelperTest.java79
-rw-r--r--services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java18
-rw-r--r--services/tests/servicestests/res/raw/conntestappbin9172 -> 8260 bytes
-rw-r--r--services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java73
-rw-r--r--services/tests/servicestests/test-apps/ConnTestApp/Android.mk1
-rw-r--r--services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml3
-rw-r--r--services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java101
89 files changed, 981 insertions, 855 deletions
diff --git a/api/current.txt b/api/current.txt
index da2a8eea3fa3..80fdb30c8e47 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -121,7 +121,6 @@ package android {
field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
- field public static final java.lang.String SEND_EMBMS_INTENTS = "android.permission.SEND_EMBMS_INTENTS";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
@@ -31078,7 +31077,6 @@ package android.os {
ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
method public deprecated synchronized boolean allowPurging(boolean) throws java.io.IOException;
method public void close();
- method public java.io.FileDescriptor getFileDescriptor() throws java.io.IOException;
method public java.io.InputStream getInputStream();
method public java.io.OutputStream getOutputStream();
method public deprecated boolean isPurgingAllowed();
@@ -31510,8 +31508,6 @@ package android.os {
method public void close();
method public static android.os.SharedMemory create(java.lang.String, int) throws android.system.ErrnoException;
method public int describeContents();
- method public int getFd();
- method public java.io.FileDescriptor getFileDescriptor();
method public int getSize();
method public java.nio.ByteBuffer map(int, int, int) throws android.system.ErrnoException;
method public java.nio.ByteBuffer mapReadOnly() throws android.system.ErrnoException;
diff --git a/api/removed.txt b/api/removed.txt
index ca3414272a54..6c37a8fbf133 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -25,30 +25,9 @@ package android.app {
method public deprecated android.app.Notification.Builder setTimeout(long);
}
- public static final class Notification.TvExtender implements android.app.Notification.Extender {
- method public deprecated java.lang.String getChannel();
- }
-
public final deprecated class PictureInPictureArgs implements android.os.Parcelable {
- ctor public deprecated PictureInPictureArgs();
- ctor public deprecated PictureInPictureArgs(float, java.util.List<android.app.RemoteAction>);
method public static android.app.PictureInPictureArgs convert(android.app.PictureInPictureParams);
method public static android.app.PictureInPictureParams convert(android.app.PictureInPictureArgs);
- method public void copyOnlySet(android.app.PictureInPictureArgs);
- method public java.util.List<android.app.RemoteAction> getActions();
- method public float getAspectRatio();
- method public android.util.Rational getAspectRatioRational();
- method public android.graphics.Rect getSourceRectHint();
- method public android.graphics.Rect getSourceRectHintInsets();
- method public boolean hasSetActions();
- method public boolean hasSetAspectRatio();
- method public boolean hasSourceBoundsHint();
- method public boolean hasSourceBoundsHintInsets();
- method public deprecated void setActions(java.util.List<android.app.RemoteAction>);
- method public deprecated void setAspectRatio(float);
- method public deprecated void setSourceRectHint(android.graphics.Rect);
- method public deprecated void setSourceRectHintInsets(android.graphics.Rect);
- method public void truncateActions(int);
field public static final android.os.Parcelable.Creator<android.app.PictureInPictureArgs> CREATOR;
}
@@ -60,10 +39,6 @@ package android.app {
method public android.app.PictureInPictureArgs.Builder setSourceRectHint(android.graphics.Rect);
}
- public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
- method public deprecated void showAsNotification(android.content.Context);
- }
-
}
package android.app.admin {
@@ -71,8 +46,6 @@ package android.app.admin {
public class DevicePolicyManager {
method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
- method public deprecated java.lang.String getDeviceInitializerApp();
- method public deprecated android.content.ComponentName getDeviceInitializerComponent();
}
}
@@ -267,24 +240,12 @@ package android.net {
}
-package android.net.wifi {
-
- public class WifiManager {
- method public deprecated boolean setWifiApEnabled(android.net.wifi.WifiConfiguration, boolean);
- }
-
-}
-
package android.os {
public class BatteryManager {
ctor public BatteryManager();
}
- public class Build {
- field public static final boolean PERMISSIONS_REVIEW_REQUIRED;
- }
-
public final class PowerManager {
method public void goToSleep(long);
method public deprecated void userActivity(long, boolean);
@@ -355,11 +316,8 @@ package android.provider {
field public static final java.lang.String CREATED = "created";
field public static final java.lang.String DATE = "date";
field public static final java.lang.String FAVICON = "favicon";
- field public static final java.lang.String THUMBNAIL = "thumbnail";
field public static final java.lang.String TITLE = "title";
- field public static final java.lang.String TOUCH_ICON = "touch_icon";
field public static final java.lang.String URL = "url";
- field public static final java.lang.String USER_ENTERED = "user_entered";
field public static final java.lang.String VISITS = "visits";
}
@@ -450,26 +408,6 @@ package android.provider {
}
-package android.service.notification {
-
- public abstract class NotificationListenerService extends android.app.Service {
- method public android.service.notification.StatusBarNotification[] getActiveNotifications(int);
- method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[], int);
- method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException;
- method public final void setOnNotificationPostedTrim(int);
- method public final void snoozeNotification(java.lang.String, java.lang.String);
- method public void unregisterAsSystemService() throws android.os.RemoteException;
- field public static final int TRIM_FULL = 0; // 0x0
- field public static final int TRIM_LIGHT = 1; // 0x1
- }
-
- public static class NotificationListenerService.Ranking {
- method public java.util.List<java.lang.String> getAdditionalPeople();
- method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
- }
-
-}
-
package android.speech.tts {
public abstract class UtteranceProgressListener {
diff --git a/api/system-current.txt b/api/system-current.txt
index bd62aec44bb5..0be499ecdea1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -228,7 +228,6 @@ package android {
field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
field public static final java.lang.String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
field public static final java.lang.String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
- field public static final java.lang.String SEND_EMBMS_INTENTS = "android.permission.SEND_EMBMS_INTENTS";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
field public static final java.lang.String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION";
@@ -5323,7 +5322,6 @@ package android.app {
method public java.lang.String getGroup();
method public int getGroupAlertBehavior();
method public android.graphics.drawable.Icon getLargeIcon();
- method public static java.lang.Class<? extends android.app.Notification.Style> getNotificationStyleClass(java.lang.String);
method public java.lang.CharSequence getSettingsText();
method public java.lang.String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
@@ -6539,8 +6537,6 @@ package android.app.admin {
method public int getCurrentFailedPasswordAttempts();
method public java.util.List<java.lang.String> getDelegatePackages(android.content.ComponentName, java.lang.String);
method public java.util.List<java.lang.String> getDelegatedScopes(android.content.ComponentName, java.lang.String);
- method public deprecated java.lang.String getDeviceInitializerApp();
- method public deprecated android.content.ComponentName getDeviceInitializerComponent();
method public java.lang.String getDeviceOwner();
method public android.content.ComponentName getDeviceOwnerComponentOnAnyUser();
method public java.lang.CharSequence getDeviceOwnerLockScreenInfo();
@@ -29285,7 +29281,6 @@ package android.net.wifi {
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
- method public deprecated boolean setWifiApEnabled(android.net.wifi.WifiConfiguration, boolean);
method public boolean setWifiEnabled(boolean);
method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
method public deprecated boolean startLocationRestrictedScan(android.os.WorkSource);
@@ -33388,7 +33383,6 @@ package android.os {
field public static final java.lang.String ID;
field public static final java.lang.String MANUFACTURER;
field public static final java.lang.String MODEL;
- field public static final boolean PERMISSIONS_REVIEW_REQUIRED;
field public static final java.lang.String PRODUCT;
field public static final deprecated java.lang.String RADIO;
field public static final deprecated java.lang.String SERIAL;
@@ -33926,7 +33920,6 @@ package android.os {
ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
method public deprecated synchronized boolean allowPurging(boolean) throws java.io.IOException;
method public void close();
- method public java.io.FileDescriptor getFileDescriptor() throws java.io.IOException;
method public java.io.InputStream getInputStream();
method public java.io.OutputStream getOutputStream();
method public deprecated boolean isPurgingAllowed();
@@ -34387,8 +34380,6 @@ package android.os {
method public void close();
method public static android.os.SharedMemory create(java.lang.String, int) throws android.system.ErrnoException;
method public int describeContents();
- method public int getFd();
- method public java.io.FileDescriptor getFileDescriptor();
method public int getSize();
method public java.nio.ByteBuffer map(int, int, int) throws android.system.ErrnoException;
method public java.nio.ByteBuffer mapReadOnly() throws android.system.ErrnoException;
@@ -40627,9 +40618,7 @@ package android.service.notification {
method public final void cancelNotification(java.lang.String);
method public final void cancelNotifications(java.lang.String[]);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
- method public android.service.notification.StatusBarNotification[] getActiveNotifications(int);
method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[]);
- method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[], int);
method public final int getCurrentInterruptionFilter();
method public final int getCurrentListenerHints();
method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
@@ -40649,16 +40638,12 @@ package android.service.notification {
method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap, int);
- method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException;
method public final void requestInterruptionFilter(int);
method public final void requestListenerHints(int);
method public static void requestRebind(android.content.ComponentName);
method public final void requestUnbind();
method public final void setNotificationsShown(java.lang.String[]);
- method public final void setOnNotificationPostedTrim(int);
- method public final void snoozeNotification(java.lang.String, java.lang.String);
method public final void snoozeNotification(java.lang.String, long);
- method public void unregisterAsSystemService() throws android.os.RemoteException;
method public final void updateNotificationChannel(java.lang.String, android.os.UserHandle, android.app.NotificationChannel);
field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
@@ -40693,21 +40678,17 @@ package android.service.notification {
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
field public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1; // 0x1
field public static final int SUPPRESSED_EFFECT_SCREEN_ON = 2; // 0x2
- field public static final int TRIM_FULL = 0; // 0x0
- field public static final int TRIM_LIGHT = 1; // 0x1
}
public static class NotificationListenerService.Ranking {
ctor public NotificationListenerService.Ranking();
method public boolean canShowBadge();
- method public java.util.List<java.lang.String> getAdditionalPeople();
method public android.app.NotificationChannel getChannel();
method public int getImportance();
method public java.lang.CharSequence getImportanceExplanation();
method public java.lang.String getKey();
method public java.lang.String getOverrideGroupKey();
method public int getRank();
- method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
method public int getSuppressedVisualEffects();
method public boolean isAmbient();
method public boolean matchesInterruptionFilter();
diff --git a/api/system-removed.txt b/api/system-removed.txt
index dfadae4c83d8..a320a8cf3756 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -15,6 +15,7 @@ package android.app {
public class Notification implements android.os.Parcelable {
method public deprecated java.lang.String getChannel();
+ method public static java.lang.Class<? extends android.app.Notification.Style> getNotificationStyleClass(java.lang.String);
method public deprecated long getTimeout();
method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
}
@@ -29,25 +30,8 @@ package android.app {
}
public final deprecated class PictureInPictureArgs implements android.os.Parcelable {
- ctor public deprecated PictureInPictureArgs();
- ctor public deprecated PictureInPictureArgs(float, java.util.List<android.app.RemoteAction>);
method public static android.app.PictureInPictureArgs convert(android.app.PictureInPictureParams);
method public static android.app.PictureInPictureParams convert(android.app.PictureInPictureArgs);
- method public void copyOnlySet(android.app.PictureInPictureArgs);
- method public java.util.List<android.app.RemoteAction> getActions();
- method public float getAspectRatio();
- method public android.util.Rational getAspectRatioRational();
- method public android.graphics.Rect getSourceRectHint();
- method public android.graphics.Rect getSourceRectHintInsets();
- method public boolean hasSetActions();
- method public boolean hasSetAspectRatio();
- method public boolean hasSourceBoundsHint();
- method public boolean hasSourceBoundsHintInsets();
- method public deprecated void setActions(java.util.List<android.app.RemoteAction>);
- method public deprecated void setAspectRatio(float);
- method public deprecated void setSourceRectHint(android.graphics.Rect);
- method public deprecated void setSourceRectHintInsets(android.graphics.Rect);
- method public void truncateActions(int);
field public static final android.os.Parcelable.Creator<android.app.PictureInPictureArgs> CREATOR;
}
@@ -59,10 +43,6 @@ package android.app {
method public android.app.PictureInPictureArgs.Builder setSourceRectHint(android.graphics.Rect);
}
- public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
- method public deprecated void showAsNotification(android.content.Context);
- }
-
}
package android.app.admin {
@@ -70,6 +50,8 @@ package android.app.admin {
public class DevicePolicyManager {
method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
+ method public deprecated java.lang.String getDeviceInitializerApp();
+ method public deprecated android.content.ComponentName getDeviceInitializerComponent();
}
}
@@ -264,12 +246,24 @@ package android.net {
}
+package android.net.wifi {
+
+ public class WifiManager {
+ method public deprecated boolean setWifiApEnabled(android.net.wifi.WifiConfiguration, boolean);
+ }
+
+}
+
package android.os {
public class BatteryManager {
ctor public BatteryManager();
}
+ public class Build {
+ field public static final boolean PERMISSIONS_REVIEW_REQUIRED;
+ }
+
public final class PowerManager {
method public void goToSleep(long);
method public deprecated void userActivity(long, boolean);
@@ -340,11 +334,8 @@ package android.provider {
field public static final java.lang.String CREATED = "created";
field public static final java.lang.String DATE = "date";
field public static final java.lang.String FAVICON = "favicon";
- field public static final java.lang.String THUMBNAIL = "thumbnail";
field public static final java.lang.String TITLE = "title";
- field public static final java.lang.String TOUCH_ICON = "touch_icon";
field public static final java.lang.String URL = "url";
- field public static final java.lang.String USER_ENTERED = "user_entered";
field public static final java.lang.String VISITS = "visits";
}
@@ -435,6 +426,26 @@ package android.provider {
}
+package android.service.notification {
+
+ public abstract class NotificationListenerService extends android.app.Service {
+ method public android.service.notification.StatusBarNotification[] getActiveNotifications(int);
+ method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[], int);
+ method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException;
+ method public final void setOnNotificationPostedTrim(int);
+ method public final void snoozeNotification(java.lang.String, java.lang.String);
+ method public void unregisterAsSystemService() throws android.os.RemoteException;
+ field public static final int TRIM_FULL = 0; // 0x0
+ field public static final int TRIM_LIGHT = 1; // 0x1
+ }
+
+ public static class NotificationListenerService.Ranking {
+ method public java.util.List<java.lang.String> getAdditionalPeople();
+ method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
+ }
+
+}
+
package android.speech.tts {
public abstract class UtteranceProgressListener {
diff --git a/api/test-current.txt b/api/test-current.txt
index b38f25d9df71..cba0dfdf2713 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -121,7 +121,6 @@ package android {
field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
- field public static final java.lang.String SEND_EMBMS_INTENTS = "android.permission.SEND_EMBMS_INTENTS";
field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
field public static final java.lang.String SEND_SMS = "android.permission.SEND_SMS";
field public static final java.lang.String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
@@ -31235,7 +31234,6 @@ package android.os {
ctor public MemoryFile(java.lang.String, int) throws java.io.IOException;
method public deprecated synchronized boolean allowPurging(boolean) throws java.io.IOException;
method public void close();
- method public java.io.FileDescriptor getFileDescriptor() throws java.io.IOException;
method public java.io.InputStream getInputStream();
method public java.io.OutputStream getOutputStream();
method public deprecated boolean isPurgingAllowed();
@@ -31668,8 +31666,6 @@ package android.os {
method public void close();
method public static android.os.SharedMemory create(java.lang.String, int) throws android.system.ErrnoException;
method public int describeContents();
- method public int getFd();
- method public java.io.FileDescriptor getFileDescriptor();
method public int getSize();
method public java.nio.ByteBuffer map(int, int, int) throws android.system.ErrnoException;
method public java.nio.ByteBuffer mapReadOnly() throws android.system.ErrnoException;
diff --git a/api/test-removed.txt b/api/test-removed.txt
index ca3414272a54..6c37a8fbf133 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -25,30 +25,9 @@ package android.app {
method public deprecated android.app.Notification.Builder setTimeout(long);
}
- public static final class Notification.TvExtender implements android.app.Notification.Extender {
- method public deprecated java.lang.String getChannel();
- }
-
public final deprecated class PictureInPictureArgs implements android.os.Parcelable {
- ctor public deprecated PictureInPictureArgs();
- ctor public deprecated PictureInPictureArgs(float, java.util.List<android.app.RemoteAction>);
method public static android.app.PictureInPictureArgs convert(android.app.PictureInPictureParams);
method public static android.app.PictureInPictureParams convert(android.app.PictureInPictureArgs);
- method public void copyOnlySet(android.app.PictureInPictureArgs);
- method public java.util.List<android.app.RemoteAction> getActions();
- method public float getAspectRatio();
- method public android.util.Rational getAspectRatioRational();
- method public android.graphics.Rect getSourceRectHint();
- method public android.graphics.Rect getSourceRectHintInsets();
- method public boolean hasSetActions();
- method public boolean hasSetAspectRatio();
- method public boolean hasSourceBoundsHint();
- method public boolean hasSourceBoundsHintInsets();
- method public deprecated void setActions(java.util.List<android.app.RemoteAction>);
- method public deprecated void setAspectRatio(float);
- method public deprecated void setSourceRectHint(android.graphics.Rect);
- method public deprecated void setSourceRectHintInsets(android.graphics.Rect);
- method public void truncateActions(int);
field public static final android.os.Parcelable.Creator<android.app.PictureInPictureArgs> CREATOR;
}
@@ -60,10 +39,6 @@ package android.app {
method public android.app.PictureInPictureArgs.Builder setSourceRectHint(android.graphics.Rect);
}
- public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
- method public deprecated void showAsNotification(android.content.Context);
- }
-
}
package android.app.admin {
@@ -71,8 +46,6 @@ package android.app.admin {
public class DevicePolicyManager {
method public deprecated android.os.UserHandle createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle);
method public deprecated android.os.UserHandle createUser(android.content.ComponentName, java.lang.String);
- method public deprecated java.lang.String getDeviceInitializerApp();
- method public deprecated android.content.ComponentName getDeviceInitializerComponent();
}
}
@@ -267,24 +240,12 @@ package android.net {
}
-package android.net.wifi {
-
- public class WifiManager {
- method public deprecated boolean setWifiApEnabled(android.net.wifi.WifiConfiguration, boolean);
- }
-
-}
-
package android.os {
public class BatteryManager {
ctor public BatteryManager();
}
- public class Build {
- field public static final boolean PERMISSIONS_REVIEW_REQUIRED;
- }
-
public final class PowerManager {
method public void goToSleep(long);
method public deprecated void userActivity(long, boolean);
@@ -355,11 +316,8 @@ package android.provider {
field public static final java.lang.String CREATED = "created";
field public static final java.lang.String DATE = "date";
field public static final java.lang.String FAVICON = "favicon";
- field public static final java.lang.String THUMBNAIL = "thumbnail";
field public static final java.lang.String TITLE = "title";
- field public static final java.lang.String TOUCH_ICON = "touch_icon";
field public static final java.lang.String URL = "url";
- field public static final java.lang.String USER_ENTERED = "user_entered";
field public static final java.lang.String VISITS = "visits";
}
@@ -450,26 +408,6 @@ package android.provider {
}
-package android.service.notification {
-
- public abstract class NotificationListenerService extends android.app.Service {
- method public android.service.notification.StatusBarNotification[] getActiveNotifications(int);
- method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[], int);
- method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException;
- method public final void setOnNotificationPostedTrim(int);
- method public final void snoozeNotification(java.lang.String, java.lang.String);
- method public void unregisterAsSystemService() throws android.os.RemoteException;
- field public static final int TRIM_FULL = 0; // 0x0
- field public static final int TRIM_LIGHT = 1; // 0x1
- }
-
- public static class NotificationListenerService.Ranking {
- method public java.util.List<java.lang.String> getAdditionalPeople();
- method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
- }
-
-}
-
package android.speech.tts {
public abstract class UtteranceProgressListener {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index f0189c240a85..ad989dee7b55 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -414,7 +414,7 @@ public final class Pm {
try {
ApkLite baseApk = PackageParser.parseApkLite(file, 0);
PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
- null, null, null);
+ null, null);
params.sessionParams.setSize(
PackageHelper.calculateInstalledSize(pkgLite, false,
params.sessionParams.abiOverride));
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 17648b244c81..adc6467e8ade 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3795,7 +3795,6 @@ public abstract class PackageManager {
/**
* @removed
- * @hide
*/
public abstract boolean setInstantAppCookie(@Nullable byte[] cookie);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index d0964c9ff1c5..7cc02b4f1668 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -428,12 +428,9 @@ public class PackageParser {
public final boolean extractNativeLibs;
public final boolean isolatedSplits;
- public final String classLoaderName;
- public final String[] splitClassLoaderNames;
-
public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
boolean[] isFeatureSplits, String[] usesSplitNames, String[] configForSplit,
- String[] splitCodePaths, int[] splitRevisionCodes, String[] splitClassLoaderNames) {
+ String[] splitCodePaths, int[] splitRevisionCodes) {
this.packageName = baseApk.packageName;
this.versionCode = baseApk.versionCode;
this.installLocation = baseApk.installLocation;
@@ -453,9 +450,6 @@ public class PackageParser {
this.use32bitAbi = baseApk.use32bitAbi;
this.extractNativeLibs = baseApk.extractNativeLibs;
this.isolatedSplits = baseApk.isolatedSplits;
-
- this.classLoaderName = baseApk.classLoaderName;
- this.splitClassLoaderNames = splitClassLoaderNames;
}
public List<String> getAllCodePaths() {
@@ -490,14 +484,13 @@ public class PackageParser {
public final boolean use32bitAbi;
public final boolean extractNativeLibs;
public final boolean isolatedSplits;
- public final String classLoaderName;
public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit,
String configForSplit, String usesSplitName, int versionCode, int revisionCode,
int installLocation, List<VerifierInfo> verifiers, Signature[] signatures,
Certificate[][] certificates, boolean coreApp, boolean debuggable,
boolean multiArch, boolean use32bitAbi, boolean extractNativeLibs,
- boolean isolatedSplits, String classLoaderName) {
+ boolean isolatedSplits) {
this.codePath = codePath;
this.packageName = packageName;
this.splitName = splitName;
@@ -516,7 +509,6 @@ public class PackageParser {
this.use32bitAbi = use32bitAbi;
this.extractNativeLibs = extractNativeLibs;
this.isolatedSplits = isolatedSplits;
- this.classLoaderName = classLoaderName;
}
}
@@ -885,7 +877,7 @@ public class PackageParser {
final ApkLite baseApk = parseApkLite(packageFile, flags);
final String packagePath = packageFile.getAbsolutePath();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- return new PackageLite(packagePath, baseApk, null, null, null, null, null, null, null);
+ return new PackageLite(packagePath, baseApk, null, null, null, null, null, null);
}
static PackageLite parseClusterPackageLite(File packageDir, int flags)
@@ -956,7 +948,6 @@ public class PackageParser {
configForSplits = new String[size];
splitCodePaths = new String[size];
splitRevisionCodes = new int[size];
- splitClassLoaderNames = new String[size];
splitNames = apks.keySet().toArray(splitNames);
Arrays.sort(splitNames, sSplitNameComparator);
@@ -968,13 +959,12 @@ public class PackageParser {
configForSplits[i] = apk.configForSplit;
splitCodePaths[i] = apk.codePath;
splitRevisionCodes[i] = apk.revisionCode;
- splitClassLoaderNames[i] = apk.classLoaderName;
}
}
final String codePath = packageDir.getAbsolutePath();
return new PackageLite(codePath, baseApk, splitNames, isFeatureSplits, usesSplitNames,
- configForSplits, splitCodePaths, splitRevisionCodes, splitClassLoaderNames);
+ configForSplits, splitCodePaths, splitRevisionCodes);
}
/**
@@ -1239,8 +1229,7 @@ public class PackageParser {
pkg.splitPrivateFlags = new int[num];
pkg.applicationInfo.splitNames = pkg.splitNames;
pkg.applicationInfo.splitDependencies = splitDependencies;
- pkg.applicationInfo.classLoaderName = lite.classLoaderName;
- pkg.applicationInfo.splitClassLoaderNames = lite.splitClassLoaderNames;
+ pkg.applicationInfo.splitClassLoaderNames = new String[num];
for (int i = 0; i < num; i++) {
final AssetManager splitAssets = assetLoader.getSplitAssetManager(i);
@@ -1854,7 +1843,6 @@ public class PackageParser {
boolean isFeatureSplit = false;
String configForSplit = null;
String usesSplitName = null;
- String classLoaderName = null;
for (int i = 0; i < attrs.getAttributeCount(); i++) {
final String attr = attrs.getAttributeName(i);
@@ -1911,14 +1899,6 @@ public class PackageParser {
if ("extractNativeLibs".equals(attr)) {
extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
}
- if ("classLoader".equals(attr)) {
- classLoaderName = attrs.getAttributeValue(i);
- if (!ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
- throw new PackageParserException(
- PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
- "Invalid class loader name: " + classLoaderName);
- }
- }
}
} else if (TAG_USES_SPLIT.equals(parser.getName())) {
if (usesSplitName != null) {
@@ -1938,7 +1918,7 @@ public class PackageParser {
return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
configForSplit, usesSplitName, versionCode, revisionCode, installLocation,
verifiers, signatures, certificates, coreApp, debuggable, multiArch, use32bitAbi,
- extractNativeLibs, isolatedSplits, classLoaderName);
+ extractNativeLibs, isolatedSplits);
}
/**
@@ -3690,6 +3670,13 @@ public class PackageParser {
ai.uiOptions = sa.getInt(
com.android.internal.R.styleable.AndroidManifestApplication_uiOptions, 0);
+ ai.classLoaderName = sa.getString(
+ com.android.internal.R.styleable.AndroidManifestApplication_classLoader);
+ if (ai.classLoaderName != null
+ && !ClassLoaderFactory.isValidClassLoaderName(ai.classLoaderName)) {
+ outError[0] = "Invalid class loader name: " + ai.classLoaderName;
+ }
+
sa.recycle();
if (outError[0] != null) {
@@ -3939,6 +3926,16 @@ public class PackageParser {
owner.splitFlags[splitIndex] |= ApplicationInfo.FLAG_HAS_CODE;
}
+ final String classLoaderName = sa.getString(
+ com.android.internal.R.styleable.AndroidManifestApplication_classLoader);
+ if (classLoaderName == null || ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
+ owner.applicationInfo.splitClassLoaderNames[splitIndex] = classLoaderName;
+ } else {
+ outError[0] = "Invalid class loader name: " + classLoaderName;
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
final int innerDepth = parser.getDepth();
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index 5032e6a59a8b..7d301a3154f0 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -136,7 +136,6 @@ public final class SharedLibraryInfo implements Parcelable {
}
/**
- * @hide
* @removed
*/
public boolean isBuiltin() {
@@ -144,7 +143,6 @@ public final class SharedLibraryInfo implements Parcelable {
}
/**
- * @hide
* @removed
*/
public boolean isDynamic() {
@@ -152,7 +150,6 @@ public final class SharedLibraryInfo implements Parcelable {
}
/**
- * @hide
* @removed
*/
public boolean isStatic() {
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 181e4a26d9b8..f75789f5eadd 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -72,4 +72,6 @@ interface INetworkPolicyManager {
void setSubscriptionPlans(int subId, in SubscriptionPlan[] plans, String callingPackage);
void factoryReset(String subscriber);
+
+ boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork);
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 6d44330934bc..cea5715d89e7 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -3667,25 +3667,29 @@ public abstract class BatteryStats implements Parcelable {
0 /* old cpu power, keep for compatibility */);
}
- final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
- // If total cpuFreqTimes is null, then we don't need to check for screenOffCpuFreqTimes.
- if (cpuFreqTimeMs != null) {
- sb.setLength(0);
- for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
- sb.append((i == 0 ? "" : ",") + cpuFreqTimeMs[i]);
- }
- final long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
- if (screenOffCpuFreqTimeMs != null) {
- for (int i = 0; i < screenOffCpuFreqTimeMs.length; ++i) {
- sb.append("," + screenOffCpuFreqTimeMs[i]);
- }
- } else {
+ // If the cpuFreqs is null, then don't bother checking for cpu freq times.
+ if (cpuFreqs != null) {
+ final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
+ // If total cpuFreqTimes is null, then we don't need to check for
+ // screenOffCpuFreqTimes.
+ if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
+ sb.setLength(0);
for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
- sb.append(",0");
+ sb.append((i == 0 ? "" : ",") + cpuFreqTimeMs[i]);
+ }
+ final long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
+ if (screenOffCpuFreqTimeMs != null) {
+ for (int i = 0; i < screenOffCpuFreqTimeMs.length; ++i) {
+ sb.append("," + screenOffCpuFreqTimeMs[i]);
+ }
+ } else {
+ for (int i = 0; i < cpuFreqTimeMs.length; ++i) {
+ sb.append(",0");
+ }
}
+ dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA, UID_TIMES_TYPE_ALL,
+ cpuFreqTimeMs.length, sb.toString());
}
- dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA, UID_TIMES_TYPE_ALL,
- cpuFreqTimeMs.length, sb.toString());
}
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 0541a53c2473..7852125db6f0 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -757,6 +757,16 @@ public class Build {
/**
* O.
+ *
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li>{@link android.R.attr#focusable} defaults to a new state ({@code auto}) where it will
+ * inherit the value of {@link android.R.attr#clickable} unless explicitly overridden.</li>
+ * <li>A default theme-appropriate focus-state highlight will be supplied to all Views
+ * which don't provide a focus-state drawable themselves. This can be disabled by setting
+ * {@link android.R.attr#defaultFocusHighlightEnabled} to false.</li>
+ * </ul>
*/
public static final int O = 26;
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 3de217494ac5..b916b4381a5d 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -435,4 +435,6 @@ interface INetworkManagementService
int removeRoutesFromLocalNetwork(in List<RouteInfo> routes);
void setAllowOnlyVpnForUids(boolean enable, in UidRange[] uidRanges);
+
+ boolean isNetworkRestricted(int uid);
}
diff --git a/core/java/android/os/MemoryFile.java b/core/java/android/os/MemoryFile.java
index 9294c449e4d6..ff3258f806c9 100644
--- a/core/java/android/os/MemoryFile.java
+++ b/core/java/android/os/MemoryFile.java
@@ -219,6 +219,8 @@ public class MemoryFile {
* The returned file descriptor is not duplicated.
*
* @throws IOException If the memory file has been closed.
+ *
+ * @hide
*/
public FileDescriptor getFileDescriptor() throws IOException {
return mSharedMemory.getFileDescriptor();
diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java
index 459aeb087c2f..e6c7a1716941 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -60,7 +60,8 @@ public final class SharedMemory implements Parcelable, Closeable {
}
mMemoryRegistration = new MemoryRegistration(mSize);
- mCleaner = Cleaner.create(this, new Closer(mFileDescriptor, mMemoryRegistration));
+ mCleaner = Cleaner.create(mFileDescriptor,
+ new Closer(mFileDescriptor, mMemoryRegistration));
}
/**
@@ -138,6 +139,8 @@ public final class SharedMemory implements Parcelable, Closeable {
* This FileDescriptor is interoperable with the ASharedMemory NDK APIs.
*
* @return Returns the FileDescriptor associated with this object.
+ *
+ * @hide Exists only for MemoryFile interop
*/
public @NonNull FileDescriptor getFileDescriptor() {
return mFileDescriptor;
@@ -150,6 +153,8 @@ public final class SharedMemory implements Parcelable, Closeable {
* This fd is interoperable with the ASharedMemory NDK APIs.
*
* @return Returns the native fd associated with this object, or -1 if it is already closed.
+ *
+ * @hide Exposed for native ASharedMemory_dupFromJava()
*/
public int getFd() {
return mFileDescriptor.getInt$();
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 70ef0355af8c..cc1c0677441e 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1878,7 +1878,6 @@ public final class ContactsContract {
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
*
- * @hide
* @removed
*/
@Deprecated
@@ -2975,7 +2974,6 @@ public final class ContactsContract {
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
*
- * @hide
* @removed
*/
@Deprecated
@@ -3414,7 +3412,6 @@ public final class ContactsContract {
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
*
- * @hide
* @removed
*/
@Deprecated
@@ -3515,7 +3512,6 @@ public final class ContactsContract {
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
*
- * @hide
* @removed
*/
@Deprecated
@@ -3568,7 +3564,6 @@ public final class ContactsContract {
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
*
- * @hide
* @removed
*/
@Deprecated
@@ -3961,7 +3956,6 @@ public final class ContactsContract {
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
*
- * @hide
* @removed
*/
@Deprecated
@@ -4002,7 +3996,6 @@ public final class ContactsContract {
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
*
- * @hide
* @removed
*/
@Deprecated
diff --git a/core/java/android/service/autofill/CharSequenceTransformation.java b/core/java/android/service/autofill/CharSequenceTransformation.java
index dfb30b9a38c4..8ab856e686fb 100644
--- a/core/java/android/service/autofill/CharSequenceTransformation.java
+++ b/core/java/android/service/autofill/CharSequenceTransformation.java
@@ -31,6 +31,7 @@ import android.widget.TextView;
import com.android.internal.util.Preconditions;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
@@ -53,7 +54,8 @@ import java.util.regex.Pattern;
* fields (month and year) would be:
*
* <pre class="prettyprint">
- * new CharSequenceTransformation.Builder(ccExpMonthId, Pattern.compile("^(\\d\\d)$"), "Exp: $1")
+ * new CharSequenceTransformation
+ * .Builder(ccExpMonthId, Pattern.compile("^(\\d\\d)$"), "Exp: $1")
* .addField(ccExpYearId, Pattern.compile("^(\\d\\d\\d\\d)$"), " / $1");
* </pre>
*/
@@ -83,8 +85,13 @@ public final class CharSequenceTransformation extends InternalTransformation imp
return;
}
try {
+ final Matcher matcher = field.first.matcher(value);
+ if (!matcher.matches()) {
+ if (sDebug) Log.d(TAG, "match for " + field.first + " failed on id " + id);
+ return;
+ }
// replaceAll throws an exception if the subst is invalid
- final String convertedValue = field.first.matcher(value).replaceAll(field.second);
+ final String convertedValue = matcher.replaceAll(field.second);
converted.append(convertedValue);
} catch (Exception e) {
// Do not log full exception to avoid PII leaking
diff --git a/core/java/android/service/autofill/ImageTransformation.java b/core/java/android/service/autofill/ImageTransformation.java
index 36271897b97c..2151f74fbe5b 100644
--- a/core/java/android/service/autofill/ImageTransformation.java
+++ b/core/java/android/service/autofill/ImageTransformation.java
@@ -78,8 +78,7 @@ public final class ImageTransformation extends InternalTransformation implements
}
final int size = mOptions.size();
if (sDebug) {
- Log.d(TAG, size + " multiple options on id " + childViewId + " to compare against "
- + value);
+ Log.d(TAG, size + " multiple options on id " + childViewId + " to compare against");
}
for (int i = 0; i < size; i++) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index eea692aa952a..2b4015f9063e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13284,7 +13284,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// about in case nothing has focus. even if this specific view
// isn't focusable, it may contain something that is, so let
// the root view try to give this focus if nothing else does.
- if ((mParent != null)) {
+ if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
mParent.focusableViewAvailable(this);
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 611c4b8ffdae..41fc0650d739 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1063,6 +1063,10 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
+ public int getSize() {
+ return mCounts == null ? 0 : mCounts.length;
+ }
+
/**
* Clear state of this counter.
*/
@@ -10526,11 +10530,13 @@ public class BatteryStatsImpl extends BatteryStats {
return;
}
final Uid u = getUidStatsLocked(uid);
- if (u.mCpuFreqTimeMs == null) {
+ if (u.mCpuFreqTimeMs == null
+ || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) {
u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
}
u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs);
- if (u.mScreenOffCpuFreqTimeMs == null) {
+ if (u.mScreenOffCpuFreqTimeMs == null
+ || u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) {
u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
mOnBatteryScreenOffTimeBase);
}
diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java
index 0df420b417fd..b2b769ee2fec 100644
--- a/core/java/com/android/internal/os/ClassLoaderFactory.java
+++ b/core/java/com/android/internal/os/ClassLoaderFactory.java
@@ -71,7 +71,7 @@ public class ClassLoaderFactory {
String librarySearchPath, ClassLoader parent, String classloaderName) {
if (isPathClassLoaderName(classloaderName)) {
return new PathClassLoader(dexPath, librarySearchPath, parent);
- } else if (isPathClassLoaderName(classloaderName)) {
+ } else if (isDelegateLastClassLoaderName(classloaderName)) {
return new DelegateLastClassLoader(dexPath, librarySearchPath, parent);
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 1ad85410dfbf..5afd06750601 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -814,6 +814,12 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
addOption("-Ximage-compiler-option");
addOption("--compiled-classes=/system/etc/compiled-classes");
}
+
+ // If there is a dirty-image-objects file, push it.
+ if (hasFile("/system/etc/dirty-image-objects")) {
+ addOption("-Ximage-compiler-option");
+ addOption("--dirty-image-objects=/system/etc/dirty-image-objects");
+ }
}
property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 208c7761a349..b55ad214e958 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1700,7 +1700,8 @@
<permission android:name="android.permission.RECEIVE_STK_COMMANDS"
android:protectionLevel="signature|privileged" />
- <!-- Allows an application to send EMBMS download intents to apps-->
+ <!-- Allows an application to send EMBMS download intents to apps
+ @hide -->
<permission android:name="android.permission.SEND_EMBMS_INTENTS"
android:protectionLevel="signature|privileged" />
@@ -1824,10 +1825,6 @@
<permission android:name="android.permission.MANAGE_USERS"
android:protectionLevel="signature|privileged" />
- <!-- @hide Allows an application to configure the assist gesture -->
- <permission android:name="android.permission.CONFIGURE_ASSIST_GESTURE"
- android:protectionLevel="signature" />
-
<!-- @hide Allows an application to create, remove users and get the list of
users on the device. Applications holding this permission can only create restricted,
guest, managed, demo, and ephemeral users. For creating other kind of users,
diff --git a/core/res/res/values-mcc262-mnc02/strings.xml b/core/res/res/values-mcc262-mnc02/strings.xml
new file mode 100644
index 000000000000..2b8940195ee3
--- /dev/null
+++ b/core/res/res/values-mcc262-mnc02/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2017, Google Inc.
+ *
+ * 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.
+ */
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Do not translate. Template for showing mobile network operator name while WFC is active -->
+ <string-array name="wfcSpnFormats">
+ <item>%s</item>
+ <item>%s Wi-Fi Calling</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 7b26cf27f04f..733878b9882b 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -47,10 +47,6 @@
<item>@drawable/ic_clear_material</item>
<item>@drawable/ic_dialog_alert_material</item>
<item>@drawable/ic_go_search_api_material</item>
- <item>@drawable/ic_media_route_connecting_dark_material</item>
- <item>@drawable/ic_media_route_connecting_light_material</item>
- <item>@drawable/ic_media_route_dark_material</item>
- <item>@drawable/ic_media_route_light_material</item>
<item>@drawable/ic_menu_copy_material</item>
<item>@drawable/ic_menu_cut_material</item>
<item>@drawable/ic_menu_moreoverflow_material</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 961d639a8a76..95aa264639ac 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2810,9 +2810,6 @@
<!-- True if camera app should be pinned via Pinner Service -->
<bool name="config_pinnerCameraApp">false</bool>
- <!-- Component that runs demo mode when it is enabled. -->
- <string name="config_demoModePackage" translatable="false"></string>
-
<!-- Number of days preloaded file cache should be preserved on a device before it can be
deleted -->
<integer name="config_keepPreloadsMinDays">7</integer>
@@ -2997,9 +2994,11 @@
<!-- Handle volume keys directly in Window Manager without passing them to the foreground app -->
<bool name="config_handleVolumeKeysInWindowManager">false</bool>
- <!-- Volume level of in-call notification tone playback,
- relative to the overall voice call stream volume [0..100] -->
- <integer name="config_inCallNotificationVolumeRelative">67</integer>
+ <!-- Volume level of in-call notification tone playback [0..1] -->
+ <item name="config_inCallNotificationVolume" format="float" type="dimen">.25</item>
+
+ <!-- URI for in call notification sound -->
+ <string translatable="false" name="config_inCallNotificationSound">/system/media/audio/ui/InCallNotification.ogg</string>
<!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
<integer name="config_cameraLiftTriggerSensorType">-1</integer>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6042234c1354..061413c60367 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1157,7 +1157,6 @@
<java-symbol type="string" name="lockscreen_transport_pause_description" />
<java-symbol type="string" name="config_ethernet_tcp_buffers" />
<java-symbol type="string" name="config_wifi_tcp_buffers" />
- <java-symbol type="string" name="config_demoModePackage" />
<java-symbol type="string" name="demo_starting_message" />
<java-symbol type="string" name="demo_restarting_message" />
<java-symbol type="string" name="conference_call" />
@@ -3040,7 +3039,8 @@
<java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
<java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
- <java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
+ <java-symbol type="dimen" name="config_inCallNotificationVolume" />
+ <java-symbol type="string" name="config_inCallNotificationSound" />
<java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
<java-symbol type="bool" name="config_displayBlanksAfterDoze" />
<java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
diff --git a/data/sounds/effects/InCallNotification.ogg b/data/sounds/effects/InCallNotification.ogg
new file mode 100644
index 000000000000..4481ccb25614
--- /dev/null
+++ b/data/sounds/effects/InCallNotification.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/InCallNotification.ogg b/data/sounds/effects/ogg/InCallNotification.ogg
new file mode 100644
index 000000000000..4481ccb25614
--- /dev/null
+++ b/data/sounds/effects/ogg/InCallNotification.ogg
Binary files differ
diff --git a/dirty-image-objects b/dirty-image-objects
new file mode 100644
index 000000000000..9b4d199dc723
--- /dev/null
+++ b/dirty-image-objects
@@ -0,0 +1,176 @@
+#
+# 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.
+#
+#
+#
+# Dirty-image-objects file for boot image.
+#
+# Objects in this file are known dirty at runtime. Current this includes:
+# - classes with known dirty static fields.
+#
+# The image writer will bin these objects together in the image.
+#
+# This file can be generated using imgdiag with a command such as:
+# adb shell imgdiag --image-diff-pid=<app pid> --zygote-diff-pid=<zygote pid> \
+# --boot-image=/system/framework/boot.art --dump-dirty-objects
+# Then, grep for lines containing "Private dirty object" from the output.
+# This particular file was generated by dumping systemserver and systemui.
+#
+java.lang.System
+java.net.Inet4Address
+java.lang.Thread
+java.lang.Throwable
+java.util.Collections
+javax.net.ssl.SSLContext
+java.nio.charset.Charset
+java.security.Provider
+javax.net.ssl.HttpsURLConnection
+javax.net.ssl.SSLSocketFactory
+java.util.TimeZone
+java.util.Locale
+java.util.function.ToIntFunction
+sun.misc.FormattedFloatingDecimal
+java.util.stream.IntStream
+android.icu.util.TimeZone
+libcore.io.DropBox
+org.apache.harmony.luni.internal.util.TimezoneGetter
+dalvik.system.SocketTagger
+dalvik.system.CloseGuard
+java.lang.ref.FinalizerReference
+com.android.org.conscrypt.ct.CTLogStoreImpl
+com.android.org.conscrypt.SSLParametersImpl
+com.android.org.conscrypt.OpenSSLContextImpl
+com.android.org.conscrypt.SSLParametersImpl$AliasChooser
+com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
+com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
+com.android.okhttp.OkHttpClient
+com.android.okhttp.okio.SegmentPool
+com.android.okhttp.okio.AsyncTimeout
+com.android.okhttp.HttpUrl
+android.os.StrictMode
+com.android.internal.os.BinderInternal
+android.os.storage.StorageManager
+android.os.Trace
+android.app.ActivityManager
+android.media.MediaRouter
+android.os.Environment
+android.view.ThreadedRenderer
+android.media.AudioManager
+android.app.AlarmManager
+android.telephony.TelephonyManager
+android.bluetooth.BluetoothAdapter
+com.android.internal.os.SomeArgs
+android.os.LocaleList
+android.view.WindowManagerGlobal
+android.media.AudioSystem
+android.ddm.DdmHandleAppName
+android.provider.Settings
+android.view.ViewRootImpl
+android.net.ConnectivityManager
+android.app.ActivityThread
+android.os.BaseBundle
+android.util.ArraySet
+android.view.View
+android.os.ServiceManager
+android.view.ViewTreeObserver
+android.hardware.input.InputManager
+android.os.UEventObserver
+android.app.NotificationManager
+android.hardware.display.DisplayManagerGlobal
+android.os.Binder
+android.app.AppOpsManager
+android.content.ContentResolver
+android.app.backup.BackupManager
+android.util.ArrayMap
+android.os.Looper
+android.graphics.Bitmap
+android.view.textservice.TextServicesManager
+com.android.internal.inputmethod.InputMethodUtils
+android.app.QueuedWork
+android.graphics.TemporaryBuffer
+android.widget.ImageView
+android.database.sqlite.SQLiteGlobal
+android.view.autofill.Helper
+android.text.method.SingleLineTransformationMethod
+com.android.internal.os.RuntimeInit
+android.view.inputmethod.InputMethodManager
+android.hardware.SystemSensorManager
+android.database.CursorWindow
+android.text.TextUtils
+android.media.PlayerBase
+android.app.ResourcesManager
+android.os.Message
+android.view.accessibility.AccessibilityManager
+android.app.Notification
+android.provider.ContactsContract$ContactNameColumns
+android.provider.CalendarContract$EventsColumns
+android.provider.CalendarContract$CalendarColumns
+android.provider.CalendarContract$SyncColumns
+android.provider.ContactsContract$ContactsColumns
+android.content.pm.PackageManager$OnPermissionsChangedListener
+android.net.IpConfiguration$ProxySettings
+android.provider.ContactsContract$ContactOptionsColumns
+android.net.wifi.SupplicantState
+android.provider.ContactsContract$ContactStatusColumns
+android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
+android.provider.CalendarContract$CalendarSyncColumns
+android.bluetooth.BluetoothProfile$ServiceListener
+android.provider.ContactsContract$ContactCounts
+android.net.IpConfiguration$IpAssignment
+android.text.TextWatcher
+android.graphics.Bitmap$CompressFormat
+android.location.LocationListener
+sun.security.jca.Providers
+java.lang.CharSequence
+android.icu.util.ULocale
+dalvik.system.BaseDexClassLoader
+android.icu.text.BreakIterator
+libcore.io.EventLogger
+libcore.net.NetworkSecurityPolicy
+android.icu.text.UnicodeSet
+com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
+android.app.SearchManager
+android.os.Build
+android.app.ContextImpl
+android.app.WallpaperManager
+android.security.net.config.ApplicationConfig
+android.animation.LayoutTransition
+android.widget.TextView
+com.android.internal.logging.MetricsLogger
+android.renderscript.RenderScriptCacheDir
+android.os.Process
+android.os.Handler
+android.content.Context
+android.graphics.drawable.AdaptiveIconDrawable
+android.provider.FontsContract
+android.text.style.SuggestionSpan
+android.graphics.drawable.VectorDrawable$VGroup
+android.view.ViewStub
+android.text.style.MetricAffectingSpan
+android.content.SharedPreferences$OnSharedPreferenceChangeListener
+android.app.PendingIntent
+android.text.SpanWatcher
+android.widget.FrameLayout
+android.net.NetworkRequest$Type
+android.net.NetworkInfo$State
+android.graphics.drawable.GradientDrawable
+android.text.style.AlignmentSpan
+android.widget.LinearLayout
+android.text.style.CharacterStyle
+android.view.View$OnApplyWindowInsetsListener
+android.view.MenuItem
+android.text.style.ReplacementSpan
+android.graphics.drawable.Icon
+android.widget.Button
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 2fdfcd42a1e1..0700d1fb9f70 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -50,9 +50,9 @@ Caches* Caches::sInstance = nullptr;
///////////////////////////////////////////////////////////////////////////////
Caches::Caches(RenderState& renderState)
- : gradientCache(mExtensions)
+ : gradientCache(extensions())
, patchCache(renderState)
- , programCache(mExtensions)
+ , programCache(extensions())
, mRenderState(&renderState)
, mInitialized(false) {
INIT_LOGD("Creating OpenGL renderer caches");
@@ -80,7 +80,7 @@ bool Caches::init() {
}
void Caches::initExtensions() {
- if (mExtensions.hasDebugMarker()) {
+ if (extensions().hasDebugMarker()) {
eventMark = glInsertEventMarkerEXT;
startMark = glPushGroupMarkerEXT;
@@ -93,12 +93,12 @@ void Caches::initExtensions() {
}
void Caches::initConstraints() {
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ maxTextureSize = DeviceInfo::get()->maxTextureSize();
}
void Caches::initStaticProperties() {
// OpenGL ES 3.0+ specific features
- gpuPixelBuffersEnabled = mExtensions.hasPixelBufferObjects()
+ gpuPixelBuffersEnabled = extensions().hasPixelBufferObjects()
&& property_get_bool(PROPERTY_ENABLE_GPU_PIXEL_BUFFERS, true);
}
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 19063e3768cd..29eddde1e42b 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -16,6 +16,7 @@
#pragma once
+#include "DeviceInfo.h"
#include "Extensions.h"
#include "FboCache.h"
#include "GammaFontRenderer.h"
@@ -145,10 +146,6 @@ public:
// Misc
GLint maxTextureSize;
-private:
- // Declared before gradientCache and programCache which need this to initialize.
- // TODO: cleanup / move elsewhere
- Extensions mExtensions;
public:
TextureCache textureCache;
RenderBufferCache renderBufferCache;
@@ -174,7 +171,7 @@ public:
void setProgram(const ProgramDescription& description);
void setProgram(Program* program);
- const Extensions& extensions() const { return mExtensions; }
+ const Extensions& extensions() const { return DeviceInfo::get()->extensions(); }
Program& program() { return *mProgram; }
PixelBufferState& pixelBufferState() { return *mPixelBufferState; }
TextureState& textureState() { return *mTextureState; }
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index d180ba51b304..37965daf9a8d 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -16,7 +16,8 @@
#include <DeviceInfo.h>
-#include "Extensions.h"
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
#include <thread>
#include <mutex>
@@ -46,13 +47,22 @@ void DeviceInfo::initialize() {
void DeviceInfo::initialize(int maxTextureSize) {
std::call_once(sInitializedFlag, [maxTextureSize]() {
sDeviceInfo = new DeviceInfo();
+ sDeviceInfo->loadDisplayInfo();
sDeviceInfo->mMaxTextureSize = maxTextureSize;
});
}
void DeviceInfo::load() {
+ loadDisplayInfo();
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
}
+void DeviceInfo::loadDisplayInfo() {
+ sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
+ ISurfaceComposer::eDisplayIdMain));
+ status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &mDisplayInfo);
+ LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
+}
+
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index aff84b02d85a..5bd7b14b156d 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -16,7 +16,10 @@
#ifndef DEVICEINFO_H
#define DEVICEINFO_H
+#include <ui/DisplayInfo.h>
+
#include "utils/Macros.h"
+#include "Extensions.h"
namespace android {
namespace uirenderer {
@@ -35,14 +38,24 @@ public:
static void initialize(int maxTextureSize);
int maxTextureSize() const { return mMaxTextureSize; }
+ const DisplayInfo& displayInfo() const { return mDisplayInfo; }
+ const Extensions& extensions() const { return mExtensions; }
+
+ static uint32_t multiplyByResolution(uint32_t in) {
+ auto di = DeviceInfo::get()->displayInfo();
+ return di.w * di.h * in;
+ }
private:
DeviceInfo() {}
~DeviceInfo() {}
void load();
+ void loadDisplayInfo();
int mMaxTextureSize;
+ DisplayInfo mDisplayInfo;
+ Extensions mExtensions;
};
} /* namespace uirenderer */
diff --git a/libs/hwui/FboCache.cpp b/libs/hwui/FboCache.cpp
index b2181b60054f..a39e49f82eb0 100644
--- a/libs/hwui/FboCache.cpp
+++ b/libs/hwui/FboCache.cpp
@@ -28,7 +28,7 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
FboCache::FboCache()
- : mMaxSize(Properties::fboCacheSize) {}
+ : mMaxSize(0) {}
FboCache::~FboCache() {
clear();
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index ee99018fb652..bc4181075319 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -32,7 +32,6 @@
#include "utils/Timing.h"
#include <algorithm>
-#include <cutils/properties.h>
#include <RenderScript.h>
#include <SkGlyph.h>
#include <SkUtils.h>
@@ -99,22 +98,14 @@ FontRenderer::FontRenderer(const uint8_t* gammaTable)
INIT_LOGD("Creating FontRenderer");
}
- mSmallCacheWidth = property_get_int32(PROPERTY_TEXT_SMALL_CACHE_WIDTH,
- DEFAULT_TEXT_SMALL_CACHE_WIDTH);
- mSmallCacheHeight = property_get_int32(PROPERTY_TEXT_SMALL_CACHE_HEIGHT,
- DEFAULT_TEXT_SMALL_CACHE_HEIGHT);
+ auto deviceInfo = DeviceInfo::get();
+ int maxTextureSize = deviceInfo->maxTextureSize();
- mLargeCacheWidth = property_get_int32(PROPERTY_TEXT_LARGE_CACHE_WIDTH,
- DEFAULT_TEXT_LARGE_CACHE_WIDTH);
- mLargeCacheHeight = property_get_int32(PROPERTY_TEXT_LARGE_CACHE_HEIGHT,
- DEFAULT_TEXT_LARGE_CACHE_HEIGHT);
-
- uint32_t maxTextureSize = (uint32_t) Caches::getInstance().maxTextureSize;
-
- mSmallCacheWidth = std::min(mSmallCacheWidth, maxTextureSize);
- mSmallCacheHeight = std::min(mSmallCacheHeight, maxTextureSize);
- mLargeCacheWidth = std::min(mLargeCacheWidth, maxTextureSize);
- mLargeCacheHeight = std::min(mLargeCacheHeight, maxTextureSize);
+ // TODO: Most devices are hardcoded with this configuration, does it need to be dynamic?
+ mSmallCacheWidth = std::min(1024, maxTextureSize);
+ mSmallCacheHeight = std::min(1024, maxTextureSize);
+ mLargeCacheWidth = std::min(2048, maxTextureSize);
+ mLargeCacheHeight = std::min(1024, maxTextureSize);
if (sLogFontRendererCreate) {
INIT_LOGD(" Text cache sizes, in pixels: %i x %i, %i x %i, %i x %i, %i x %i",
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index d4d0c997be11..20262349dda4 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -20,6 +20,7 @@
#include "Debug.h"
#include "GradientCache.h"
#include "Properties.h"
+#include "DeviceInfo.h"
#include <cutils/properties.h>
@@ -62,14 +63,14 @@ int GradientCacheEntry::compare(const GradientCacheEntry& lhs, const GradientCac
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
-GradientCache::GradientCache(Extensions& extensions)
+GradientCache::GradientCache(const Extensions& extensions)
: mCache(LruCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity)
, mSize(0)
- , mMaxSize(Properties::gradientCacheSize)
+ , mMaxSize(MB(1))
, mUseFloatTexture(extensions.hasFloatTextures())
, mHasNpot(extensions.hasNPot())
, mHasLinearBlending(extensions.hasLinearBlending()) {
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+ mMaxTextureSize = DeviceInfo::get()->maxTextureSize();
mCache.setOnEntryRemovedListener(this);
}
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index f299a40e994f..d95589c514eb 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -105,7 +105,7 @@ inline hash_t hash_type(const GradientCacheEntry& entry) {
*/
class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
public:
- explicit GradientCache(Extensions& extensions);
+ explicit GradientCache(const Extensions& extensions);
~GradientCache();
/**
diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp
index 983c17e92266..78c7eb9ad809 100644
--- a/libs/hwui/PatchCache.cpp
+++ b/libs/hwui/PatchCache.cpp
@@ -32,7 +32,7 @@ namespace uirenderer {
PatchCache::PatchCache(RenderState& renderState)
: mRenderState(renderState)
- , mMaxSize(Properties::patchCacheSize)
+ , mMaxSize(KB(128))
, mSize(0)
, mCache(LruCache<PatchDescription, Patch*>::kUnlimitedCapacity)
, mMeshBuffer(0)
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index cc96de71df82..8d4ae1b6622a 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -38,6 +38,8 @@
namespace android {
namespace uirenderer {
+static constexpr size_t PATH_CACHE_COUNT_LIMIT = 256;
+
template <class T>
static bool compareWidthHeight(const T& lhs, const T& rhs) {
return (lhs.mWidth == rhs.mWidth) && (lhs.mHeight == rhs.mHeight);
@@ -179,13 +181,9 @@ static sk_sp<Bitmap> drawPath(const SkPath* path, const SkPaint* paint, PathText
PathCache::PathCache()
: mCache(LruCache<PathDescription, PathTexture*>::kUnlimitedCapacity)
, mSize(0)
- , mMaxSize(Properties::pathCacheSize) {
+ , mMaxSize(DeviceInfo::multiplyByResolution(4)) {
mCache.setOnEntryRemovedListener(this);
-
- GLint maxTextureSize;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
- mMaxTextureSize = maxTextureSize;
-
+ mMaxTextureSize = DeviceInfo::get()->maxTextureSize();
mDebugEnabled = Properties::debugLevel & kDebugCaches;
}
@@ -259,12 +257,7 @@ void PathCache::purgeCache(uint32_t width, uint32_t height) {
}
void PathCache::trim() {
- // 25 is just an arbitrary lower bound to ensure we aren't in weird edge cases
- // of things like a cap of 0 or 1 as that's going to break things.
- // It does not represent a reasonable minimum value
- static_assert(DEFAULT_PATH_TEXTURE_CAP > 25, "Path cache texture cap is too small");
-
- while (mSize > mMaxSize || mCache.size() > DEFAULT_PATH_TEXTURE_CAP) {
+ while (mSize > mMaxSize || mCache.size() > PATH_CACHE_COUNT_LIMIT) {
LOG_ALWAYS_FATAL_IF(!mCache.size(), "Inconsistent mSize! Ran out of items to remove!"
" mSize = %u, mMaxSize = %u", mSize, mMaxSize);
mCache.removeOldest();
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 8cc0aa7b414c..b767046f1a4f 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -505,7 +505,7 @@ const char* gBlendOps[18] = {
// Constructors/destructors
///////////////////////////////////////////////////////////////////////////////
-ProgramCache::ProgramCache(Extensions& extensions)
+ProgramCache::ProgramCache(const Extensions& extensions)
: mHasES3(extensions.getMajorGlVersion() >= 3)
, mHasLinearBlending(extensions.hasLinearBlending()) {
}
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index cedd854bb48b..ee76f22f35d4 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -40,7 +40,7 @@ namespace uirenderer {
*/
class ProgramCache {
public:
- explicit ProgramCache(Extensions& extensions);
+ explicit ProgramCache(const Extensions& extensions);
~ProgramCache();
Program* get(const ProgramDescription& description);
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index b5872485b136..acc75393ebcf 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -16,6 +16,7 @@
#include "Properties.h"
#include "Debug.h"
+#include "DeviceInfo.h"
#include <algorithm>
#include <cstdlib>
@@ -36,20 +37,6 @@ bool Properties::skipEmptyFrames = true;
bool Properties::useBufferAge = true;
bool Properties::enablePartialUpdates = true;
-float Properties::textGamma = DEFAULT_TEXT_GAMMA;
-
-int Properties::fboCacheSize = DEFAULT_FBO_CACHE_SIZE;
-int Properties::gradientCacheSize = MB(DEFAULT_GRADIENT_CACHE_SIZE);
-int Properties::layerPoolSize = MB(DEFAULT_LAYER_CACHE_SIZE);
-int Properties::patchCacheSize = KB(DEFAULT_PATCH_CACHE_SIZE);
-int Properties::pathCacheSize = MB(DEFAULT_PATH_CACHE_SIZE);
-int Properties::renderBufferCacheSize = MB(DEFAULT_RENDER_BUFFER_CACHE_SIZE);
-int Properties::tessellationCacheSize = MB(DEFAULT_VERTEX_CACHE_SIZE);
-int Properties::textDropShadowCacheSize = MB(DEFAULT_DROP_SHADOW_CACHE_SIZE);
-int Properties::textureCacheSize = MB(DEFAULT_TEXTURE_CACHE_SIZE);
-
-float Properties::textureCacheFlushRate = DEFAULT_TEXTURE_CACHE_FLUSH_RATE;
-
DebugLevel Properties::debugLevel = kDebugDisabled;
OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
StencilClipDebug Properties::debugStencilClip = StencilClipDebug::Hide;
@@ -80,15 +67,6 @@ static int property_get_int(const char* key, int defaultValue) {
return defaultValue;
}
-static float property_get_float(const char* key, float defaultValue) {
- char buf[PROPERTY_VALUE_MAX] = {'\0',};
-
- if (property_get(key, buf, "") > 0) {
- return atof(buf);
- }
- return defaultValue;
-}
-
bool Properties::load() {
char property[PROPERTY_VALUE_MAX];
bool prevDebugLayersUpdates = debugLayersUpdates;
@@ -147,20 +125,6 @@ bool Properties::load() {
useBufferAge = property_get_bool(PROPERTY_USE_BUFFER_AGE, true);
enablePartialUpdates = property_get_bool(PROPERTY_ENABLE_PARTIAL_UPDATES, true);
- textGamma = property_get_float(PROPERTY_TEXT_GAMMA, DEFAULT_TEXT_GAMMA);
-
- fboCacheSize = property_get_int(PROPERTY_FBO_CACHE_SIZE, DEFAULT_FBO_CACHE_SIZE);
- gradientCacheSize = MB(property_get_float(PROPERTY_GRADIENT_CACHE_SIZE, DEFAULT_GRADIENT_CACHE_SIZE));
- layerPoolSize = MB(property_get_float(PROPERTY_LAYER_CACHE_SIZE, DEFAULT_LAYER_CACHE_SIZE));
- patchCacheSize = KB(property_get_float(PROPERTY_PATCH_CACHE_SIZE, DEFAULT_PATCH_CACHE_SIZE));
- pathCacheSize = MB(property_get_float(PROPERTY_PATH_CACHE_SIZE, DEFAULT_PATH_CACHE_SIZE));
- renderBufferCacheSize = MB(property_get_float(PROPERTY_RENDER_BUFFER_CACHE_SIZE, DEFAULT_RENDER_BUFFER_CACHE_SIZE));
- tessellationCacheSize = MB(property_get_float(PROPERTY_VERTEX_CACHE_SIZE, DEFAULT_VERTEX_CACHE_SIZE));
- textDropShadowCacheSize = MB(property_get_float(PROPERTY_DROP_SHADOW_CACHE_SIZE, DEFAULT_DROP_SHADOW_CACHE_SIZE));
- textureCacheSize = MB(property_get_float(PROPERTY_TEXTURE_CACHE_SIZE, DEFAULT_TEXTURE_CACHE_SIZE));
- textureCacheFlushRate = std::max(0.0f, std::min(1.0f,
- property_get_float(PROPERTY_TEXTURE_CACHE_FLUSH_RATE, DEFAULT_TEXTURE_CACHE_FLUSH_RATE)));
-
filterOutTestOverhead = property_get_bool(PROPERTY_FILTER_TEST_OVERHEAD, false);
return (prevDebugLayersUpdates != debugLayersUpdates)
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 91b4a2d440e2..47ae9e912127 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -153,79 +153,16 @@ enum DebugLevel {
#define PROPERTY_FILTER_TEST_OVERHEAD "debug.hwui.filter_test_overhead"
/**
- * Allows to set rendering pipeline mode to OpenGL (default), Skia OpenGL
- * or Vulkan.
- */
-#define PROPERTY_RENDERER "debug.hwui.renderer"
-
-///////////////////////////////////////////////////////////////////////////////
-// Runtime configuration properties
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Used to enable/disable scissor optimization. The accepted values are
- * "true" and "false". The default value is "false".
- *
- * When scissor optimization is enabled, libhwui will attempt to
- * minimize the use of scissor by selectively enabling and disabling the
- * GL scissor test.
- * When the optimization is disabled, OpenGLRenderer will keep the GL
- * scissor test enabled and change the scissor rect as needed.
- * Some GPUs (for instance the SGX 540) perform better when changing
- * the scissor rect often than when enabling/disabling the scissor test
- * often.
- */
-#define PROPERTY_DISABLE_SCISSOR_OPTIMIZATION "ro.hwui.disable_scissor_opt"
-
-/**
* Indicates whether PBOs can be used to back pixel buffers.
* Accepted values are "true" and "false". Default is true.
*/
-#define PROPERTY_ENABLE_GPU_PIXEL_BUFFERS "ro.hwui.use_gpu_pixel_buffers"
-
-// These properties are defined in mega-bytes
-#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
-#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
-#define PROPERTY_RENDER_BUFFER_CACHE_SIZE "ro.hwui.r_buffer_cache_size"
-#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
-#define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
-#define PROPERTY_VERTEX_CACHE_SIZE "ro.hwui.vertex_cache_size"
-#define PROPERTY_PATCH_CACHE_SIZE "ro.hwui.patch_cache_size"
-#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
-#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
-
-// These properties are defined in percentage (range 0..1)
-#define PROPERTY_TEXTURE_CACHE_FLUSH_RATE "ro.hwui.texture_cache_flushrate"
-
-// These properties are defined in pixels
-#define PROPERTY_TEXT_SMALL_CACHE_WIDTH "ro.hwui.text_small_cache_width"
-#define PROPERTY_TEXT_SMALL_CACHE_HEIGHT "ro.hwui.text_small_cache_height"
-#define PROPERTY_TEXT_LARGE_CACHE_WIDTH "ro.hwui.text_large_cache_width"
-#define PROPERTY_TEXT_LARGE_CACHE_HEIGHT "ro.hwui.text_large_cache_height"
-
-// Gamma (>= 1.0, <= 3.0)
-#define PROPERTY_TEXT_GAMMA "hwui.text_gamma"
-
-///////////////////////////////////////////////////////////////////////////////
-// Default property values
-///////////////////////////////////////////////////////////////////////////////
-
-#define DEFAULT_TEXTURE_CACHE_SIZE 24.0f
-#define DEFAULT_LAYER_CACHE_SIZE 16.0f
-#define DEFAULT_RENDER_BUFFER_CACHE_SIZE 2.0f
-#define DEFAULT_PATH_CACHE_SIZE 4.0f
-#define DEFAULT_VERTEX_CACHE_SIZE 1.0f
-#define DEFAULT_PATCH_CACHE_SIZE 128.0f // in kB
-#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
-#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
-#define DEFAULT_FBO_CACHE_SIZE 0
-
-#define DEFAULT_TEXTURE_CACHE_FLUSH_RATE 0.6f
+#define PROPERTY_ENABLE_GPU_PIXEL_BUFFERS "debug.hwui.use_gpu_pixel_buffers"
-#define DEFAULT_TEXT_GAMMA 1.45f // Match design tools
-
-// cap to 256 to limite paths in the path cache
-#define DEFAULT_PATH_TEXTURE_CAP 256
+/**
+ * Allows to set rendering pipeline mode to OpenGL (default), Skia OpenGL
+ * or Vulkan.
+ */
+#define PROPERTY_RENDERER "debug.hwui.renderer"
///////////////////////////////////////////////////////////////////////////////
// Misc
@@ -279,18 +216,8 @@ public:
static bool useBufferAge;
static bool enablePartialUpdates;
- static float textGamma;
-
- static int fboCacheSize;
- static int gradientCacheSize;
- static int layerPoolSize;
- static int patchCacheSize;
- static int pathCacheSize;
- static int renderBufferCacheSize;
- static int tessellationCacheSize;
- static int textDropShadowCacheSize;
- static int textureCacheSize;
- static float textureCacheFlushRate;
+ // TODO: Move somewhere else?
+ static constexpr float textGamma = 1.45f;
static DebugLevel debugLevel;
static OverdrawColorSet overdrawColorSet;
diff --git a/libs/hwui/RenderBufferCache.cpp b/libs/hwui/RenderBufferCache.cpp
index 1ac57cdbac0c..2f8ddfe6d660 100644
--- a/libs/hwui/RenderBufferCache.cpp
+++ b/libs/hwui/RenderBufferCache.cpp
@@ -17,6 +17,7 @@
#include "Debug.h"
#include "Properties.h"
#include "RenderBufferCache.h"
+#include "DeviceInfo.h"
#include <utils/Log.h>
@@ -36,13 +37,20 @@ namespace uirenderer {
#define RENDER_BUFFER_LOGD(...)
#endif
+static uint32_t calculateRboCacheSize() {
+ // TODO: Do we need to use extensions().has4BitStencil() here?
+ // The tuning guide recommends it, but all real devices are configured
+ // with a larger cache than necessary by 4x, so keep the 2x for now regardless
+ return DeviceInfo::multiplyByResolution(2);
+}
+
///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
RenderBufferCache::RenderBufferCache()
: mSize(0)
- , mMaxSize(Properties::renderBufferCacheSize) {}
+ , mMaxSize(calculateRboCacheSize()) {}
RenderBufferCache::~RenderBufferCache() {
clear();
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 91e7ac39af90..01582ce8f007 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -290,7 +290,7 @@ public:
///////////////////////////////////////////////////////////////////////////////
TessellationCache::TessellationCache()
- : mMaxSize(Properties::tessellationCacheSize)
+ : mMaxSize(MB(1))
, mCache(LruCache<Description, Buffer*>::kUnlimitedCapacity)
, mShadowCache(LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*>::kUnlimitedCapacity) {
mCache.setOnEntryRemovedListener(&mBufferRemovedListener);
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index e1f0b2a20172..c521892c69df 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -94,7 +94,7 @@ int ShadowText::compare(const ShadowText& lhs, const ShadowText& rhs) {
///////////////////////////////////////////////////////////////////////////////
TextDropShadowCache::TextDropShadowCache()
- : TextDropShadowCache(Properties::textDropShadowCacheSize) {}
+ : TextDropShadowCache(DeviceInfo::multiplyByResolution(2)) {}
TextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize)
: mCache(LruCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity)
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 710cdd9286e8..6fe3606a7576 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -24,6 +24,7 @@
#include "Properties.h"
#include "utils/TraceUtils.h"
#include "hwui/Bitmap.h"
+#include "DeviceInfo.h"
namespace android {
namespace uirenderer {
@@ -35,13 +36,10 @@ namespace uirenderer {
TextureCache::TextureCache()
: mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity)
, mSize(0)
- , mMaxSize(Properties::textureCacheSize)
- , mFlushRate(Properties::textureCacheFlushRate) {
+ , mMaxSize(DeviceInfo::multiplyByResolution(4 * 6)) // 6 screen-sized RGBA_8888 bitmaps
+ , mFlushRate(.4f) {
mCache.setOnEntryRemovedListener(this);
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
- INIT_LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize);
-
+ mMaxTextureSize = DeviceInfo::get()->maxTextureSize();
mDebugEnabled = Properties::debugLevel & kDebugCaches;
}
diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h
index 07e8b34ac66f..d4b4ff949f5a 100644
--- a/libs/hwui/font/FontUtil.h
+++ b/libs/hwui/font/FontUtil.h
@@ -25,11 +25,6 @@
// Defines
///////////////////////////////////////////////////////////////////////////////
-#define DEFAULT_TEXT_SMALL_CACHE_WIDTH 1024
-#define DEFAULT_TEXT_SMALL_CACHE_HEIGHT 512
-#define DEFAULT_TEXT_LARGE_CACHE_WIDTH 2048
-#define DEFAULT_TEXT_LARGE_CACHE_HEIGHT 512
-
#ifdef TEXTURE_BORDER_SIZE
#if TEXTURE_BORDER_SIZE != 1
#error TEXTURE_BORDER_SIZE other than 1 is not currently supported
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index 2dfa6d4dc839..ea292d678c67 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -17,7 +17,6 @@
#include "OffscreenBufferPool.h"
#include "Caches.h"
-#include "Properties.h"
#include "renderstate/RenderState.h"
#include "utils/FatVector.h"
#include "utils/TraceUtils.h"
@@ -118,7 +117,8 @@ OffscreenBuffer::~OffscreenBuffer() {
///////////////////////////////////////////////////////////////////////////////
OffscreenBufferPool::OffscreenBufferPool()
- : mMaxSize(Properties::layerPoolSize) {
+ // 4 screen-sized RGBA_8888 textures
+ : mMaxSize(DeviceInfo::multiplyByResolution(4 * 4)) {
}
OffscreenBufferPool::~OffscreenBufferPool() {
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 2c92924cc12c..ededffb0f4bb 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -53,6 +53,11 @@ void RenderState::onGLContextCreated() {
mScissor = new Scissor();
mStencil = new Stencil();
+ // Deferred because creation needs GL context for texture limits
+ if (!mLayerPool) {
+ mLayerPool = new OffscreenBufferPool();
+ }
+
// This is delayed because the first access of Caches makes GL calls
if (!mCaches) {
mCaches = &Caches::createInstance(*this);
@@ -67,7 +72,7 @@ static void layerLostGlContext(Layer* layer) {
}
void RenderState::onGLContextDestroyed() {
- mLayerPool.clear();
+ mLayerPool->clear();
// TODO: reset all cached state in state objects
std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext);
@@ -100,7 +105,7 @@ static void layerDestroyedVkContext(Layer* layer) {
}
void RenderState::onVkContextDestroyed() {
- mLayerPool.clear();
+ mLayerPool->clear();
std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerDestroyedVkContext);
GpuMemoryTracker::onGpuContextDestroyed();
}
@@ -116,10 +121,10 @@ void RenderState::flush(Caches::FlushMode mode) {
case Caches::FlushMode::Moderate:
// fall through
case Caches::FlushMode::Layers:
- mLayerPool.clear();
+ if (mLayerPool) mLayerPool->clear();
break;
}
- mCaches->flush(mode);
+ if (mCaches) mCaches->flush(mode);
}
void RenderState::onBitmapDestroyed(uint32_t pixelRefId) {
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index 4b7a86580621..df81e864a0b5 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -113,7 +113,7 @@ public:
Scissor& scissor() { return *mScissor; }
Stencil& stencil() { return *mStencil; }
- OffscreenBufferPool& layerPool() { return mLayerPool; }
+ OffscreenBufferPool& layerPool() { return *mLayerPool; }
GrContext* getGrContext() const;
@@ -136,7 +136,7 @@ private:
Scissor* mScissor = nullptr;
Stencil* mStencil = nullptr;
- OffscreenBufferPool mLayerPool;
+ OffscreenBufferPool* mLayerPool = nullptr;
std::set<Layer*> mActiveLayers;
std::set<DeferredLayerUpdater*> mActiveLayerUpdaters;
diff --git a/libs/hwui/renderstate/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp
index d25ad514e892..f59442196af1 100644
--- a/libs/hwui/renderstate/Stencil.cpp
+++ b/libs/hwui/renderstate/Stencil.cpp
@@ -47,7 +47,7 @@ uint8_t Stencil::getStencilSize() {
*/
GLenum Stencil::getLayerStencilFormat() {
#if !DEBUG_STENCIL
- const Extensions& extensions = Caches::getInstance().extensions();
+ const Extensions& extensions = DeviceInfo::get()->extensions();
if (extensions.has4BitStencil()) {
return GL_STENCIL_INDEX4_OES;
}
diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
index 919852f6b2d7..308fef303740 100644
--- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
@@ -74,8 +74,8 @@ RENDERTHREAD_TEST(OffscreenBufferPool, construct) {
OffscreenBufferPool pool;
EXPECT_EQ(0u, pool.getCount()) << "pool must be created empty";
EXPECT_EQ(0u, pool.getSize()) << "pool must be created empty";
- EXPECT_EQ((uint32_t) Properties::layerPoolSize, pool.getMaxSize())
- << "pool must read size from Properties";
+ // TODO: Does this really make sense as a test?
+ EXPECT_EQ(DeviceInfo::multiplyByResolution(4 * 4), pool.getMaxSize());
}
RENDERTHREAD_OPENGL_PIPELINE_TEST(OffscreenBufferPool, getPutClear) {
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 9538e1d5fa74..6b329f8ec694 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.Rect;
@@ -680,7 +681,8 @@ public class TvView extends ViewGroup {
// Other app may have shown its own main TvView.
// Set main again to regain main session.
synchronized (sMainTvViewLock) {
- if (hasFocus && this == sMainTvView.get() && mSession != null) {
+ if (hasFocus && this == sMainTvView.get() && mSession != null
+ && checkChangeHdmiCecActiveSourcePermission()) {
mSession.setMain();
}
}
@@ -848,6 +850,12 @@ public class TvView extends ViewGroup {
return frame;
}
+ private boolean checkChangeHdmiCecActiveSourcePermission() {
+ return getContext().checkSelfPermission(
+ android.Manifest.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
/**
* Callback used to receive time shift position changes.
*/
@@ -1080,7 +1088,8 @@ public class TvView extends ViewGroup {
mPendingAppPrivateCommands.clear();
synchronized (sMainTvViewLock) {
- if (hasWindowFocus() && TvView.this == sMainTvView.get()) {
+ if (hasWindowFocus() && TvView.this == sMainTvView.get()
+ && checkChangeHdmiCecActiveSourcePermission()) {
mSession.setMain();
}
}
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index c82a1f6a646a..bbd27839d551 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -198,6 +198,7 @@ LIBANDROID {
ASharedMemory_create; # introduced=26
ASharedMemory_getSize; # introduced=26
ASharedMemory_setProt; # introduced=26
+ ASharedMemory_dupFromJava; # introduced=27
AStorageManager_delete;
AStorageManager_getMountedObbPath;
AStorageManager_isObbMounted;
diff --git a/native/android/sharedmem.cpp b/native/android/sharedmem.cpp
index 9d029dfad41a..757aaecab40d 100644
--- a/native/android/sharedmem.cpp
+++ b/native/android/sharedmem.cpp
@@ -14,10 +14,36 @@
* limitations under the License.
*/
+#include <jni.h>
+
#include <android/sharedmem.h>
+#include <android/sharedmem_jni.h>
#include <cutils/ashmem.h>
+#include <log/log.h>
#include <utils/Errors.h>
+#include <mutex>
+#include <unistd.h>
+
+static struct {
+ jclass clazz;
+ jmethodID getFd;
+} sSharedMemory;
+
+static void jniInit(JNIEnv* env) {
+ static std::once_flag sJniInitialized;
+ std::call_once(sJniInitialized, [](JNIEnv* env) {
+ jclass clazz = env->FindClass("android/os/SharedMemory");
+ LOG_ALWAYS_FATAL_IF(clazz == nullptr, "Failed to find android.os.SharedMemory");
+ sSharedMemory.clazz = (jclass) env->NewGlobalRef(clazz);
+ LOG_ALWAYS_FATAL_IF(sSharedMemory.clazz == nullptr,
+ "Failed to create global ref of android.os.SharedMemory");
+ sSharedMemory.getFd = env->GetMethodID(sSharedMemory.clazz, "getFd", "()I");
+ LOG_ALWAYS_FATAL_IF(sSharedMemory.getFd == nullptr,
+ "Failed to find method SharedMemory#getFd()");
+ }, env);
+}
+
int ASharedMemory_create(const char *name, size_t size) {
if (size == 0) {
return android::BAD_VALUE;
@@ -32,3 +58,20 @@ size_t ASharedMemory_getSize(int fd) {
int ASharedMemory_setProt(int fd, int prot) {
return ashmem_set_prot_region(fd, prot);
}
+
+int ASharedMemory_dupFromJava(JNIEnv* env, jobject javaSharedMemory) {
+ if (env == nullptr || javaSharedMemory == nullptr) {
+ return -1;
+ }
+ jniInit(env);
+ if (!env->IsInstanceOf(javaSharedMemory, sSharedMemory.clazz)) {
+ ALOGW("ASharedMemory_dupFromJava called with object "
+ "that's not an instanceof android.os.SharedMemory");
+ return -1;
+ }
+ int fd = env->CallIntMethod(javaSharedMemory, sSharedMemory.getFd);
+ if (fd != -1) {
+ fd = dup(fd);
+ }
+ return fd;
+}
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 906786596422..d668a4161224 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1152,7 +1152,7 @@
<string name="monitoring_description_vpn_settings_separator">" "</string>
<!-- Monitoring dialog: Link to open the VPN settings page [CHAR LIMIT=60] -->
- <string name="monitoring_description_vpn_settings">Open VPN Settings</string>
+ <string name="monitoring_description_vpn_settings">Open VPN settings</string>
<!-- Monitoring dialog: Space that separates the CA certs body text and the "Open trusted credentials" link that follows it. [CHAR LIMIT=5] -->
<string name="monitoring_description_ca_cert_settings_separator">" "</string>
@@ -1987,8 +1987,10 @@
<!-- SysUI Tuner: App subheading for shortcut selection [CHAR LIMIT=60] -->
<string name="tuner_app"><xliff:g id="app">%1$s</xliff:g> app</string>
- <!-- Title for the notification channel containing important alerts like low battery. [CHAR LIMIT=NONE] -->
+ <!-- Title for the notification channel containing important alerts. [CHAR LIMIT=NONE] -->
<string name="notification_channel_alerts">Alerts</string>
+ <!-- Title for the notification channel for battery warnings (i.e. < 15%). [CHAR LIMIT=NONE] -->
+ <string name="notification_channel_battery">Battery</string>
<!-- Title for the notification channel dedicated to screenshot progress. [CHAR LIMIT=NONE] -->
<string name="notification_channel_screenshot">Screenshots</string>
<!-- Title for the notification channel for miscellaneous notices. [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 32775fe9d5c1..669594b86e54 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -646,13 +646,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
return mStrongAuthTracker;
}
- public void reportSuccessfulStrongAuthUnlockAttempt() {
- if (mFpm != null) {
- byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
- mFpm.resetTimeout(token);
- }
- }
-
private void notifyStrongAuthStateChanged(int userId) {
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d132e761c591..4733008c06c3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -560,9 +560,6 @@ public class KeyguardViewMediator extends SystemUI {
}
tryKeyguardDone();
- if (strongAuth) {
- mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
- }
}
@Override
@@ -591,9 +588,6 @@ public class KeyguardViewMediator extends SystemUI {
mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
KEYGUARD_DONE_PENDING_TIMEOUT_MS);
- if (strongAuth) {
- mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
- }
Trace.endSection();
}
@@ -1288,7 +1282,6 @@ public class KeyguardViewMediator extends SystemUI {
// Without this, settings is not enabled until the lock screen first appears
setShowingLocked(false);
hideLocked();
- mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
return;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 6b3daa306103..e76276d3ea5c 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -17,6 +17,7 @@
package com.android.systemui.power;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -40,6 +41,7 @@ import android.support.annotation.VisibleForTesting;
import android.util.Slog;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
@@ -173,8 +175,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private void showWarningNotification() {
final int textRes = R.string.battery_low_percent_format;
final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0);
+
final Notification.Builder nb =
- new Notification.Builder(mContext, NotificationChannels.ALERTS)
+ new Notification.Builder(mContext, NotificationChannels.BATTERY)
.setSmallIcon(R.drawable.ic_power_low)
// Bump the notification when the bucket dropped.
.setWhen(mBucketDroppedNegativeTimeMs)
@@ -191,10 +194,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
nb.addAction(0,
mContext.getString(R.string.battery_saver_start_action),
pendingBroadcast(ACTION_START_SAVER));
- if (mPlaySound) {
- attachLowBatterySound(nb);
- mPlaySound = false;
- }
+ nb.setOnlyAlertOnce(!mPlaySound);
+ mPlaySound = false;
SystemUI.overrideNotificationAppName(mContext, nb);
final Notification n = nb.build();
mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL);
@@ -335,43 +336,12 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
public void showLowBatteryWarning(boolean playSound) {
Slog.i(TAG,
"show low battery warning: level=" + mBatteryLevel
- + " [" + mBucket + "] playSound=" + playSound);
+ + " [" + mBucket + "] playSound=" + playSound);
mPlaySound = playSound;
mWarning = true;
updateNotification();
}
- private void attachLowBatterySound(Notification.Builder b) {
- final ContentResolver cr = mContext.getContentResolver();
-
- final int silenceAfter = Settings.Global.getInt(cr,
- Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
- final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
- if (silenceAfter > 0
- && mScreenOffTime > 0
- && offTime > silenceAfter) {
- Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
- + "ms): not waking up the user with low battery sound");
- return;
- }
-
- if (DEBUG) {
- Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
- }
-
- if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
- final String soundPath = Settings.Global.getString(cr,
- Settings.Global.LOW_BATTERY_SOUND);
- if (soundPath != null) {
- final Uri soundUri = Uri.parse("file://" + soundPath);
- if (soundUri != null) {
- b.setSound(soundUri, AUDIO_ATTRIBUTES);
- if (DEBUG) Slog.d(TAG, "playing sound " + soundUri);
- }
- }
- }
- }
-
@Override
public void dismissInvalidChargerWarning() {
dismissInvalidChargerNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index a9139993c137..28172b7534d3 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -231,6 +231,7 @@ public class PowerUI extends SystemUI {
&& (bucket < oldBucket || oldPlugged)
&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
&& bucket < 0) {
+
// only play SFX when the dialog comes up or the bucket changes
final boolean playSound = bucket != oldBucket || oldPlugged;
mWarnings.showLowBatteryWarning(playSound);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 3ce1465cfd8a..e574c01dd077 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -320,7 +320,7 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic
}
private String getPositiveButton() {
- return mContext.getString(R.string.quick_settings_done);
+ return mContext.getString(R.string.ok);
}
protected CharSequence getManagementMessage(boolean isDeviceManaged,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 9b0179dc4552..378dad76a28c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -49,6 +49,8 @@ public class SystemUIDialog extends AlertDialog {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle(getClass().getSimpleName());
getWindow().setAttributes(attrs);
+
+ registerDismissListener(this);
}
public void setShowForAllUsers(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index ae8afe4dcad7..87bc0e67f7be 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -19,6 +19,10 @@ import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.media.AudioAttributes;
+import android.net.Uri;
+import android.provider.Settings;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
@@ -31,11 +35,21 @@ public class NotificationChannels extends SystemUI {
public static String GENERAL = "GEN";
public static String STORAGE = "DSK";
public static String TVPIP = "TPP";
+ public static String BATTERY = "BAT";
@VisibleForTesting
static void createAll(Context context) {
-
final NotificationManager nm = context.getSystemService(NotificationManager.class);
+ NotificationChannel batteryChannel = new NotificationChannel(BATTERY,
+ context.getString(R.string.notification_channel_battery),
+ NotificationManager.IMPORTANCE_MAX);
+ final String soundPath = Settings.Global.getString(context.getContentResolver(),
+ Settings.Global.LOW_BATTERY_SOUND);
+ batteryChannel.setSound(Uri.parse("file://" + soundPath), new AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+ .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT)
+ .build());
+
nm.createNotificationChannels(Arrays.asList(
new NotificationChannel(
ALERTS,
@@ -54,8 +68,10 @@ public class NotificationChannels extends SystemUI {
context.getString(R.string.notification_channel_storage),
isTv(context)
? NotificationManager.IMPORTANCE_DEFAULT
- : NotificationManager.IMPORTANCE_LOW)
- ));
+ : NotificationManager.IMPORTANCE_LOW),
+ batteryChannel
+ ));
+
if (isTv(context)) {
// TV specific notification channel for TV PIP controls.
// Importance should be {@link NotificationManager#IMPORTANCE_MAX} to have the highest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index eb59a341ef0f..ac37d1e24c80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -36,6 +36,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.NotificationChannels;
import org.junit.Before;
import org.junit.Test;
@@ -108,23 +109,13 @@ public class PowerNotificationWarningsTest extends SysuiTestCase {
}
@Test
- public void testShowLowBatteryNotification_Silent() {
- mPowerNotificationWarnings.showLowBatteryWarning(false);
- ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class);
- verify(mMockNotificationManager)
- .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW),
- captor.capture(), any());
- assertEquals(null, captor.getValue().sound);
- }
-
- @Test
- public void testShowLowBatteryNotification_Sound() {
+ public void testShowLowBatteryNotification_BatteryChannel() {
mPowerNotificationWarnings.showLowBatteryWarning(true);
ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class);
verify(mMockNotificationManager)
.notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW),
captor.capture(), any());
- assertNotEqual(null, captor.getValue().sound);
+ assertTrue(captor.getValue().getChannelId() == NotificationChannels.BATTERY);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
new file mode 100644
index 000000000000..dcd531dc9eb7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.phone;
+
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class SystemUIDialogTest extends SysuiTestCase {
+
+ private SystemUIDialog mDialog;
+
+ Context mContextSpy;
+
+ @Before
+ public void setup() {
+ mContextSpy = spy(mContext);
+ mDialog = new SystemUIDialog(mContextSpy);
+ }
+
+ @Test
+ public void testRegisterReceiver() {
+ final ArgumentCaptor<IntentFilter> intentFilterCaptor =
+ ArgumentCaptor.forClass(IntentFilter.class);
+
+ verify(mContextSpy).registerReceiverAsUser(any(), any(),
+ intentFilterCaptor.capture(), any(), any());
+
+ assertTrue(intentFilterCaptor.getValue().hasAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
index f67296d9905a..04bdc04a64d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
@@ -56,7 +56,8 @@ public class ChannelsTest extends SysuiTestCase {
NotificationChannels.ALERTS,
NotificationChannels.SCREENSHOTS,
NotificationChannels.STORAGE,
- NotificationChannels.GENERAL
+ NotificationChannels.GENERAL,
+ NotificationChannels.BATTERY
));
NotificationChannels.createAll(mContext);
ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 7959e392d500..ac4423dbba6b 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -2647,6 +2647,42 @@ public class NetworkManagementService extends INetworkManagementService.Stub
return failures;
}
+ @Override
+ public boolean isNetworkRestricted(int uid) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ return isNetworkRestrictedInternal(uid);
+ }
+
+ private boolean isNetworkRestrictedInternal(int uid) {
+ synchronized (mRulesLock) {
+ if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
+ && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
+ return true;
+ }
+ if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
+ && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
+ return true;
+ }
+ if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
+ && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
+ return true;
+ }
+ if (mUidRejectOnMetered.get(uid)) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
+ + " in the background");
+ return true;
+ }
+ if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
+ return true;
+ }
+ return false;
+ }
+ }
+
private void setFirewallChainState(int chain, boolean state) {
synchronized (mRulesLock) {
mFirewallChainStates.put(chain, state);
@@ -2663,33 +2699,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
class LocalService extends NetworkManagementInternal {
@Override
public boolean isNetworkRestrictedForUid(int uid) {
- synchronized (mRulesLock) {
- if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
- && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
- return true;
- }
- if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
- && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
- return true;
- }
- if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
- && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
- return true;
- }
- if (mUidRejectOnMetered.get(uid)) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
- + " in the background");
- return true;
- }
- if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
- if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
- return true;
- }
- return false;
- }
+ return isNetworkRestrictedInternal(uid);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 7a19cc3c2c20..4a9b98d7be00 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -2012,7 +2012,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
public boolean okToShowLocked() {
return (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0
|| (mStackSupervisor.isCurrentProfileLocked(userId)
- && !service.mUserController.isUserStoppingOrShuttingDownLocked(userId));
+ && service.mUserController.isUserRunningLocked(userId, 0 /* flags */));
}
/**
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index ceae82f1a9ac..9c8ba5a15b95 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1447,15 +1447,6 @@ final class UserController {
return mStartedUserArray;
}
- boolean isUserStoppingOrShuttingDownLocked(int userId) {
- UserState state = getStartedUserStateLocked(userId);
- if (state == null) {
- return false;
- }
- return state.state == UserState.STATE_STOPPING
- || state.state == UserState.STATE_SHUTDOWN;
- }
-
boolean isUserRunningLocked(int userId, int flags) {
UserState state = getStartedUserStateLocked(userId);
if (state == null) {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 855b9d0a8dcb..b1c165ef048d 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -1081,18 +1081,19 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
final IFingerprintServiceReceiver receiver, final int flags,
final String opPackageName) {
final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
final int callingUserId = UserHandle.getCallingUserId();
- final int pid = Binder.getCallingPid();
final boolean restricted = isRestricted();
+
+ if (!canUseFingerprint(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
+ callingUserId)) {
+ if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
+ return;
+ }
+
mHandler.post(new Runnable() {
@Override
public void run() {
- if (!canUseFingerprint(opPackageName, true /* foregroundOnly */,
- callingUid, pid, callingUserId)) {
- if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName);
- return;
- }
-
MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0);
// Get performance stats object for this user.
@@ -1113,29 +1114,31 @@ public class FingerprintService extends SystemService implements IHwBinder.Death
@Override // Binder call
public void cancelAuthentication(final IBinder token, final String opPackageName) {
- final int uid = Binder.getCallingUid();
- final int pid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
final int callingUserId = UserHandle.getCallingUserId();
+
+ if (!canUseFingerprint(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
+ callingUserId)) {
+ if (DEBUG) Slog.v(TAG, "cancelAuthentication(): reject " + opPackageName);
+ return;
+ }
+
mHandler.post(new Runnable() {
@Override
public void run() {
- if (!canUseFingerprint(opPackageName, true /* foregroundOnly */, uid, pid,
- callingUserId)) {
- if (DEBUG) Slog.v(TAG, "cancelAuthentication(): reject " + opPackageName);
- } else {
- ClientMonitor client = mCurrentClient;
- if (client instanceof AuthenticationClient) {
- if (client.getToken() == token) {
- if (DEBUG) Slog.v(TAG, "stop client " + client.getOwnerString());
- client.stop(client.getToken() == token);
- } else {
- if (DEBUG) Slog.v(TAG, "can't stop client "
- + client.getOwnerString() + " since tokens don't match");
- }
- } else if (client != null) {
- if (DEBUG) Slog.v(TAG, "can't cancel non-authenticating client "
- + client.getOwnerString());
+ ClientMonitor client = mCurrentClient;
+ if (client instanceof AuthenticationClient) {
+ if (client.getToken() == token) {
+ if (DEBUG) Slog.v(TAG, "stop client " + client.getOwnerString());
+ client.stop(client.getToken() == token);
+ } else {
+ if (DEBUG) Slog.v(TAG, "can't stop client "
+ + client.getOwnerString() + " since tokens don't match");
}
+ } else if (client != null) {
+ if (DEBUG) Slog.v(TAG, "can't cancel non-authenticating client "
+ + client.getOwnerString());
}
}
});
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 2f166e932275..c672949781fb 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -25,6 +25,7 @@ import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_EN
import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled;
+import static com.android.internal.widget.LockPatternUtils.userOwnsFrpCredential;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -560,6 +561,7 @@ public class LockSettingsService extends ILockSettings.Stub {
mDeviceProvisionedObserver.onSystemReady();
// TODO: maybe skip this for split system user mode.
mStorage.prefetchUser(UserHandle.USER_SYSTEM);
+ mStrongAuth.systemReady();
}
private void migrateOldData() {
@@ -2360,6 +2362,7 @@ public class LockSettingsService extends ILockSettings.Stub {
if (isProvisioned()) {
Slog.i(TAG, "Reporting device setup complete to IGateKeeperService");
reportDeviceSetupComplete();
+ clearFrpCredentialIfOwnerNotSecure();
}
}
}
@@ -2387,6 +2390,23 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+ /**
+ * Clears the FRP credential if the user that controls it does not have a secure
+ * lockscreen.
+ */
+ private void clearFrpCredentialIfOwnerNotSecure() {
+ List<UserInfo> users = mUserManager.getUsers();
+ for (UserInfo user : users) {
+ if (userOwnsFrpCredential(user)) {
+ if (!isUserSecure(user.id)) {
+ mStorage.writePersistentDataBlock(PersistentData.TYPE_NONE, user.id,
+ 0, null);
+ }
+ return;
+ }
+ }
+ }
+
private void updateRegistration() {
boolean register = !isProvisioned();
if (register == mRegistered) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
index 096615313f94..542b929d85f5 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -27,6 +27,7 @@ import android.app.AlarmManager.OnAlarmListener;
import android.app.admin.DevicePolicyManager;
import android.app.trust.IStrongAuthTracker;
import android.content.Context;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Binder;
import android.os.DeadObjectException;
import android.os.Handler;
@@ -64,6 +65,7 @@ public class LockSettingsStrongAuth {
private final Context mContext;
private AlarmManager mAlarmManager;
+ private FingerprintManager mFingerprintManager;
public LockSettingsStrongAuth(Context context) {
mContext = context;
@@ -71,6 +73,10 @@ public class LockSettingsStrongAuth {
mAlarmManager = context.getSystemService(AlarmManager.class);
}
+ public void systemReady() {
+ mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
+ }
+
private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
@@ -188,6 +194,11 @@ public class LockSettingsStrongAuth {
}
public void reportSuccessfulStrongAuthUnlock(int userId) {
+ if (mFingerprintManager != null) {
+ byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
+ mFingerprintManager.resetTimeout(token);
+ }
+
final int argNotUsed = 0;
mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index aabb24573084..0072ba4f2631 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -4315,6 +4315,47 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ @Override
+ public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
+ mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+ return isUidNetworkingBlockedInternal(uid, isNetworkMetered);
+ }
+
+ private boolean isUidNetworkingBlockedInternal(int uid, boolean isNetworkMetered) {
+ final int uidRules;
+ final boolean isBackgroundRestricted;
+ synchronized (mUidRulesFirstLock) {
+ uidRules = mUidRules.get(uid, RULE_NONE);
+ isBackgroundRestricted = mRestrictBackground;
+ }
+ if (hasRule(uidRules, RULE_REJECT_ALL)) {
+ if (LOGV) logUidStatus(uid, "blocked by power restrictions");
+ return true;
+ }
+ if (!isNetworkMetered) {
+ if (LOGV) logUidStatus(uid, "allowed on unmetered network");
+ return false;
+ }
+ if (hasRule(uidRules, RULE_REJECT_METERED)) {
+ if (LOGV) logUidStatus(uid, "blacklisted on metered network");
+ return true;
+ }
+ if (hasRule(uidRules, RULE_ALLOW_METERED)) {
+ if (LOGV) logUidStatus(uid, "whitelisted on metered network");
+ return false;
+ }
+ if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
+ if (LOGV) logUidStatus(uid, "temporary whitelisted on metered network");
+ return false;
+ }
+ if (isBackgroundRestricted) {
+ if (LOGV) logUidStatus(uid, "blocked when background is restricted");
+ return true;
+ }
+ if (LOGV) logUidStatus(uid, "allowed by default");
+ return false;
+ }
+
private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
@Override
@@ -4352,42 +4393,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
*/
@Override
public boolean isUidNetworkingBlocked(int uid, String ifname) {
- final int uidRules;
- final boolean isBackgroundRestricted;
final boolean isNetworkMetered;
- synchronized (mUidRulesFirstLock) {
- uidRules = mUidRules.get(uid, RULE_NONE);
- isBackgroundRestricted = mRestrictBackground;
- synchronized (mNetworkPoliciesSecondLock) {
- isNetworkMetered = mMeteredIfaces.contains(ifname);
- }
- }
- if (hasRule(uidRules, RULE_REJECT_ALL)) {
- if (LOGV) logUidStatus(uid, "blocked by power restrictions");
- return true;
- }
- if (!isNetworkMetered) {
- if (LOGV) logUidStatus(uid, "allowed on unmetered network");
- return false;
- }
- if (hasRule(uidRules, RULE_REJECT_METERED)) {
- if (LOGV) logUidStatus(uid, "blacklisted on metered network");
- return true;
- }
- if (hasRule(uidRules, RULE_ALLOW_METERED)) {
- if (LOGV) logUidStatus(uid, "whitelisted on metered network");
- return false;
- }
- if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
- if (LOGV) logUidStatus(uid, "temporary whitelisted on metered network");
- return false;
- }
- if (isBackgroundRestricted) {
- if (LOGV) logUidStatus(uid, "blocked when background is restricted");
- return true;
+ synchronized (mNetworkPoliciesSecondLock) {
+ isNetworkMetered = mMeteredIfaces.contains(ifname);
}
- if (LOGV) logUidStatus(uid, "allowed by default");
- return false;
+ return isUidNetworkingBlockedInternal(uid, isNetworkMetered);
}
}
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 57c558cddb54..ce805aadec77 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -38,14 +38,14 @@ public class GroupHelper {
private final Callback mCallback;
// Map of user : <Map of package : notification keys>. Only contains notifications that are not
- // groupd by the app (aka no group or sort key).
+ // grouped by the app (aka no group or sort key).
Map<Integer, Map<String, LinkedHashSet<String>>> mUngroupedNotifications = new HashMap<>();
public GroupHelper(Callback callback) {;
mCallback = callback;
}
- public void onNotificationPosted(StatusBarNotification sbn) {
+ public void onNotificationPosted(StatusBarNotification sbn, boolean autogroupSummaryExists) {
if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
try {
List<String> notificationsToGroup = new ArrayList<>();
@@ -68,7 +68,8 @@ public class GroupHelper {
notificationsForPackage.add(sbn.getKey());
ungroupedNotificationsByUser.put(sbn.getPackageName(), notificationsForPackage);
- if (notificationsForPackage.size() >= AUTOGROUP_AT_COUNT) {
+ if (notificationsForPackage.size() >= AUTOGROUP_AT_COUNT
+ || autogroupSummaryExists) {
notificationsToGroup.addAll(notificationsForPackage);
}
}
@@ -120,6 +121,7 @@ public class GroupHelper {
// If the status change of this notification has brought the number of loose
// notifications to zero, remove the summary and un-autogroup.
if (notificationsForPackage.size() == 0) {
+ ungroupedNotificationsByUser.remove(sbn.getPackageName());
removeSummary = true;
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index abf391e1780a..c8d8e03bce87 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -93,10 +93,10 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
import android.media.IRingtonePlayer;
-import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -187,13 +187,13 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -304,12 +304,12 @@ public class NotificationManagerService extends SystemService {
// for enabling and disabling notification pulse behavior
private boolean mScreenOn = true;
- private boolean mInCall = false;
+ protected boolean mInCall = false;
private boolean mNotificationPulseEnabled;
- // for generating notification tones in-call
- private ToneGenerator mInCallToneGenerator;
- private final Object mInCallToneGeneratorLock = new Object();
+ private Uri mInCallNotificationUri;
+ private AudioAttributes mInCallNotificationAudioAttributes;
+ private float mInCallNotificationVolume;
// used as a mutex for access to all active notifications & listeners
final Object mNotificationLock = new Object();
@@ -795,6 +795,15 @@ public class NotificationManagerService extends SystemService {
updateLightsLocked();
}
+ protected final BroadcastReceiver mLocaleChangeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+ mZenModeHelper.updateDefaultZenRules();
+ }
+ }
+ };
+
private final BroadcastReceiver mRestoreReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -938,30 +947,6 @@ public class NotificationManagerService extends SystemService {
mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
updateNotificationPulse();
- synchronized (mInCallToneGeneratorLock) {
- if (mInCall) {
- if (mInCallToneGenerator == null) {
- int relativeToneVolume = getContext().getResources().getInteger(
- R.integer.config_inCallNotificationVolumeRelative);
- if (relativeToneVolume < ToneGenerator.MIN_VOLUME
- || relativeToneVolume > ToneGenerator.MAX_VOLUME) {
- relativeToneVolume = ToneGenerator.MAX_VOLUME;
- }
- try {
- mInCallToneGenerator = new ToneGenerator(
- AudioManager.STREAM_VOICE_CALL, relativeToneVolume);
- } catch (RuntimeException e) {
- Log.e(TAG, "Error creating local tone generator: " + e);
- mInCallToneGenerator = null;
- }
- }
- } else {
- if (mInCallToneGenerator != null) {
- mInCallToneGenerator.release();
- mInCallToneGenerator = null;
- }
- }
- }
} else if (action.equals(Intent.ACTION_USER_STOPPED)) {
int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (userHandle >= 0) {
@@ -1056,7 +1041,7 @@ public class NotificationManagerService extends SystemService {
}
private SettingsObserver mSettingsObserver;
- private ZenModeHelper mZenModeHelper;
+ protected ZenModeHelper mZenModeHelper;
static long[] getLongArray(Resources r, int resid, int maxlen, long[] def) {
int[] ar = r.getIntArray(resid);
@@ -1268,6 +1253,15 @@ public class NotificationManagerService extends SystemService {
VIBRATE_PATTERN_MAXLEN,
DEFAULT_VIBRATE_PATTERN);
+ mInCallNotificationUri = Uri.parse("file://" +
+ resources.getString(R.string.config_inCallNotificationSound));
+ mInCallNotificationAudioAttributes = new AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+ .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
+ .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
+ .build();
+ mInCallNotificationVolume = resources.getFloat(R.dimen.config_inCallNotificationVolume);
+
mUseAttentionLight = resources.getBoolean(R.bool.config_useAttentionLight);
// Don't start allowing notifications until the setup wizard has run once.
@@ -1364,6 +1358,9 @@ public class NotificationManagerService extends SystemService {
IntentFilter settingsRestoredFilter = new IntentFilter(Intent.ACTION_SETTING_RESTORED);
getContext().registerReceiver(mRestoreReceiver, settingsRestoredFilter);
+ IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
+ getContext().registerReceiver(mLocaleChangeReceiver, localeChangedFilter);
+
publishBinderService(Context.NOTIFICATION_SERVICE, mService);
publishLocalService(NotificationManagerInternal.class, mInternalService);
}
@@ -2039,9 +2036,7 @@ public class NotificationManagerService extends SystemService {
private StatusBarNotification sanitizeSbn(String pkg, int userId,
StatusBarNotification sbn) {
- if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId
- && (sbn.getNotification().flags
- & Notification.FLAG_AUTOGROUP_SUMMARY) == 0) {
+ if (sbn.getPackageName().equals(pkg) && sbn.getUserId() == userId) {
// We could pass back a cloneLight() but clients might get confused and
// try to send this thing back to notify() again, which would not work
// very well.
@@ -3049,6 +3044,12 @@ public class NotificationManagerService extends SystemService {
}
}
+ @GuardedBy("mNotificationLock")
+ private boolean hasAutoGroupSummaryLocked(StatusBarNotification sbn) {
+ ArrayMap<String, String> summaries = mAutobundledSummaries.get(sbn.getUserId());
+ return summaries != null && summaries.containsKey(sbn.getPackageName());
+ }
+
// Posts a 'fake' summary for a package that has exceeded the solo-notification limit.
private void createAutoGroupSummary(int userId, String pkg, String triggeringKey) {
NotificationRecord summaryRecord = null;
@@ -3824,7 +3825,8 @@ public class NotificationManagerService extends SystemService {
mHandler.post(new Runnable() {
@Override
public void run() {
- mGroupHelper.onNotificationPosted(n);
+ mGroupHelper.onNotificationPosted(
+ n, hasAutoGroupSummaryLocked(n));
}
});
}
@@ -4140,21 +4142,21 @@ public class NotificationManagerService extends SystemService {
mUserProfiles.isCurrentProfile(record.getUserId()));
}
- private void playInCallNotification() {
+ protected void playInCallNotification() {
new Thread() {
@Override
public void run() {
- // If toneGenerator creation fails, just continue the call
- // without playing the notification sound.
+ final long identity = Binder.clearCallingIdentity();
try {
- synchronized (mInCallToneGeneratorLock) {
- if (mInCallToneGenerator != null) {
- // limit this tone to 1 second; BEEP2 should in fact be much shorter
- mInCallToneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP2, 1000);
- }
+ final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+ if (player != null) {
+ player.play(new Binder(), mInCallNotificationUri,
+ mInCallNotificationAudioAttributes,
+ mInCallNotificationVolume, false);
}
- } catch (RuntimeException e) {
- Log.w(TAG, "Exception from ToneGenerator: " + e);
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
}.start();
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 15e32ff6469e..1a0b878613f4 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -16,11 +16,6 @@
package com.android.server.notification;
-import static android.media.AudioAttributes.USAGE_NOTIFICATION;
-import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
-import static android.media.AudioAttributes.USAGE_UNKNOWN;
-import static android.media.AudioAttributes.USAGE_VIRTUAL_SOURCE;
-
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
@@ -52,7 +47,6 @@ import android.os.UserHandle;
import android.provider.Settings.Global;
import android.service.notification.Condition;
import android.service.notification.ConditionProviderService;
-import android.service.notification.NotificationServiceDumpProto;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.EventInfo;
import android.service.notification.ZenModeConfig.ScheduleInfo;
@@ -60,6 +54,7 @@ import android.service.notification.ZenModeConfig.ZenRule;
import android.service.notification.ZenModeProto;
import android.util.AndroidRuntimeException;
import android.util.Log;
+import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
@@ -93,7 +88,7 @@ public class ZenModeHelper {
private final H mHandler;
private final SettingsObserver mSettingsObserver;
private final AppOpsManager mAppOps;
- private final ZenModeConfig mDefaultConfig;
+ protected ZenModeConfig mDefaultConfig;
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
private final ZenModeFiltering mFiltering;
private final RingerModeDelegate mRingerModeDelegate = new RingerModeDelegate();
@@ -102,11 +97,16 @@ public class ZenModeHelper {
private final Metrics mMetrics = new Metrics();
private final ConditionProviders.Config mServiceConfig;
+ protected final ArrayList<String> mDefaultRuleIds = new ArrayList<>();
+ private final String EVENTS_DEFAULT_RULE = "EVENTS_DEFAULT_RULE";
+ private final String SCHEDULED_DEFAULT_RULE_1 = "SCHEDULED_DEFAULT_RULE_1";
+ private final String SCHEDULED_DEFAULT_RULE_2 = "SCHEDULED_DEFAULT_RULE_2";
+
private int mZenMode;
private int mUser = UserHandle.USER_SYSTEM;
- private ZenModeConfig mConfig;
+ protected ZenModeConfig mConfig;
private AudioManagerInternal mAudioManager;
- private PackageManager mPm;
+ protected PackageManager mPm;
private long mSuppressedEffects;
public static final long SUPPRESSED_EFFECT_NOTIFICATIONS = 1;
@@ -114,21 +114,33 @@ public class ZenModeHelper {
public static final long SUPPRESSED_EFFECT_ALL = SUPPRESSED_EFFECT_CALLS
| SUPPRESSED_EFFECT_NOTIFICATIONS;
+ protected String mDefaultRuleWeeknightsName;
+ protected String mDefaultRuleEventsName;
+ protected String mDefaultRuleWeekendsName;
+
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
mContext = context;
mHandler = new H(looper);
addCallback(mMetrics);
mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- mDefaultConfig = readDefaultConfig(context.getResources());
- appendDefaultScheduleRules(mDefaultConfig);
- appendDefaultEventRules(mDefaultConfig);
+
+ mDefaultConfig = new ZenModeConfig();
+ mDefaultRuleWeeknightsName = mContext.getResources()
+ .getString(R.string.zen_mode_default_weeknights_name);
+ mDefaultRuleWeekendsName = mContext.getResources()
+ .getString(R.string.zen_mode_default_weekends_name);
+ mDefaultRuleEventsName = mContext.getResources()
+ .getString(R.string.zen_mode_default_events_name);
+ setDefaultZenRules(mContext);
mConfig = mDefaultConfig;
mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
+
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
mFiltering = new ZenModeFiltering(mContext);
mConditions = new ZenModeConditions(this, conditionProviders);
mServiceConfig = conditionProviders.getConfig();
+
}
public Looper getLooper() {
@@ -412,6 +424,54 @@ public class ZenModeHelper {
}
}
+ public void setDefaultZenRules(Context context) {
+ mDefaultConfig = readDefaultConfig(context.getResources());
+
+ mDefaultRuleIds.add(EVENTS_DEFAULT_RULE);
+ mDefaultRuleIds.add(SCHEDULED_DEFAULT_RULE_1);
+ mDefaultRuleIds.add(SCHEDULED_DEFAULT_RULE_2);
+
+ appendDefaultRules(mDefaultConfig);
+ }
+
+ private void appendDefaultRules (ZenModeConfig config) {
+ appendDefaultScheduleRules(config);
+ appendDefaultEventRules(config);
+ }
+
+ // Checks zen rule properties are the same (doesn't check creation time, name nor enabled)
+ // used to check if default rules were customized or not
+ private boolean ruleValuesEqual(AutomaticZenRule rule, ZenRule defaultRule) {
+ if (rule == null || defaultRule == null) {
+ return false;
+ }
+ return rule.getInterruptionFilter() ==
+ NotificationManager.zenModeToInterruptionFilter(defaultRule.zenMode)
+ && rule.getConditionId().equals(defaultRule.conditionId)
+ && rule.getOwner().equals(defaultRule.component);
+ }
+
+ protected void updateDefaultZenRules() {
+ ZenModeConfig configDefaultRules = new ZenModeConfig();
+ appendDefaultRules(configDefaultRules); // "new" localized default rules
+ for (String ruleId : mDefaultRuleIds) {
+ AutomaticZenRule currRule = getAutomaticZenRule(ruleId);
+ ZenRule defaultRule = configDefaultRules.automaticRules.get(ruleId);
+ // if default rule wasn't customized, use localized name instead of previous
+ if (ruleValuesEqual(currRule, defaultRule) &&
+ !defaultRule.name.equals(currRule.getName())) {
+ if (canManageAutomaticZenRule(defaultRule)) {
+ if (DEBUG) Slog.d(TAG, "Locale change - updating default zen rule name "
+ + "from " + currRule.getName() + " to " + defaultRule.name);
+ // update default rule (if locale changed, name of rule will change)
+ AutomaticZenRule defaultAutoRule = createAutomaticZenRule(defaultRule);
+ updateAutomaticZenRule(ruleId, defaultAutoRule,
+ "locale changed");
+ }
+ }
+ }
+ }
+
private boolean isSystemRule(AutomaticZenRule rule) {
return ZenModeConfig.SYSTEM_AUTHORITY.equals(rule.getOwner().getPackageName());
}
@@ -453,7 +513,7 @@ public class ZenModeHelper {
automaticZenRule.getInterruptionFilter(), Global.ZEN_MODE_OFF);
}
- private AutomaticZenRule createAutomaticZenRule(ZenRule rule) {
+ protected AutomaticZenRule createAutomaticZenRule(ZenRule rule) {
return new AutomaticZenRule(rule.name, rule.component, rule.conditionId,
NotificationManager.zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
rule.creationTime);
@@ -853,12 +913,11 @@ public class ZenModeHelper {
weeknights.endHour = 7;
final ZenRule rule1 = new ZenRule();
rule1.enabled = false;
- rule1.name = mContext.getResources()
- .getString(R.string.zen_mode_default_weeknights_name);
+ rule1.name = mDefaultRuleWeeknightsName;
rule1.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
rule1.zenMode = Global.ZEN_MODE_ALARMS;
rule1.component = ScheduleConditionProvider.COMPONENT;
- rule1.id = ZenModeConfig.newRuleId();
+ rule1.id = SCHEDULED_DEFAULT_RULE_1;
rule1.creationTime = System.currentTimeMillis();
config.automaticRules.put(rule1.id, rule1);
@@ -869,12 +928,11 @@ public class ZenModeHelper {
weekends.endHour = 10;
final ZenRule rule2 = new ZenRule();
rule2.enabled = false;
- rule2.name = mContext.getResources()
- .getString(R.string.zen_mode_default_weekends_name);
+ rule2.name = mDefaultRuleWeekendsName;
rule2.conditionId = ZenModeConfig.toScheduleConditionId(weekends);
rule2.zenMode = Global.ZEN_MODE_ALARMS;
rule2.component = ScheduleConditionProvider.COMPONENT;
- rule2.id = ZenModeConfig.newRuleId();
+ rule2.id = SCHEDULED_DEFAULT_RULE_2;
rule2.creationTime = System.currentTimeMillis();
config.automaticRules.put(rule2.id, rule2);
}
@@ -887,11 +945,11 @@ public class ZenModeHelper {
events.reply = EventInfo.REPLY_YES_OR_MAYBE;
final ZenRule rule = new ZenRule();
rule.enabled = false;
- rule.name = mContext.getResources().getString(R.string.zen_mode_default_events_name);
+ rule.name = mDefaultRuleEventsName;
rule.conditionId = ZenModeConfig.toEventConditionId(events);
rule.zenMode = Global.ZEN_MODE_ALARMS;
rule.component = EventConditionProvider.COMPONENT;
- rule.id = ZenModeConfig.newRuleId();
+ rule.id = EVENTS_DEFAULT_RULE;
rule.creationTime = System.currentTimeMillis();
config.automaticRules.put(rule.id, rule);
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d492590a9bae..082dd2badd1c 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1153,7 +1153,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// This is kind of hacky; we're creating a half-parsed package that is
// straddled between the inherited and staged APKs.
final PackageLite pkg = new PackageLite(null, baseApk, null, null, null, null,
- splitPaths.toArray(new String[splitPaths.size()]), null, null);
+ splitPaths.toArray(new String[splitPaths.size()]), null);
final boolean isForwardLocked =
(params.installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index faeb05b9d82f..46e21dbc98bd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -175,7 +175,7 @@ class PackageManagerShellCommand extends ShellCommand {
try {
ApkLite baseApk = PackageParser.parseApkLite(file, 0);
PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
- null, null, null);
+ null, null);
params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
pkgLite, false, params.sessionParams.abiOverride));
} catch (PackageParserException | IOException e) {
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 835603a9228b..529ac3a192ae 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -537,6 +537,21 @@ public class BuzzBeepBlinkTest extends NotificationTestCase {
}
@Test
+ public void testInCallNotification() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mRingtonePlayer);
+
+ mService.mInCall = true;
+ mService.buzzBeepBlinkLocked(r);
+
+ //verify(mService, times(1)).playInCallNotification();
+ verifyNeverBeep(); // doesn't play normal beep
+ }
+
+ @Test
public void testNoDemoteSoundToVibrateIfVibrateGiven() throws Exception {
NotificationRecord r = getBuzzyBeepyNotification();
assertTrue(r.getSound() != null);
diff --git a/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java b/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
index 8dd177921022..f75c648f3c3e 100644
--- a/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
@@ -15,6 +15,9 @@
*/
package com.android.server.notification;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -29,18 +32,16 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import android.app.AlarmManager;
import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import java.util.ArrayList;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -77,7 +78,8 @@ public class GroupHelperTest extends NotificationTestCase {
public void testNoGroup_postingUnderLimit() throws Exception {
final String pkg = "package";
for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+ false);
}
verify(mCallback, never()).addAutoGroupSummary(
eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
@@ -91,10 +93,11 @@ public class GroupHelperTest extends NotificationTestCase {
final String pkg = "package";
final String pkg2 = "package2";
for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+ false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg2, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM));
+ getSbn(pkg2, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
verify(mCallback, never()).addAutoGroupSummary(
eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
@@ -106,10 +109,12 @@ public class GroupHelperTest extends NotificationTestCase {
public void testNoGroup_multiUser() throws Exception {
final String pkg = "package";
for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+ false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.ALL));
+ getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.ALL),
+ false);
verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
@@ -120,10 +125,12 @@ public class GroupHelperTest extends NotificationTestCase {
public void testNoGroup_someAreGrouped() throws Exception {
final String pkg = "package";
for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ mGroupHelper.onNotificationPosted(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"));
+ getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"),
+ false);
verify(mCallback, never()).addAutoGroupSummary(
eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
@@ -136,7 +143,8 @@ public class GroupHelperTest extends NotificationTestCase {
public void testPostingOverLimit() throws Exception {
final String pkg = "package";
for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
- mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM));
+ mGroupHelper.onNotificationPosted(
+ getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
@@ -151,7 +159,7 @@ public class GroupHelperTest extends NotificationTestCase {
for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn);
+ mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
@@ -178,7 +186,7 @@ public class GroupHelperTest extends NotificationTestCase {
for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
- mGroupHelper.onNotificationPosted(sbn);
+ mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
@@ -190,7 +198,7 @@ public class GroupHelperTest extends NotificationTestCase {
for (i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 2; i++) {
final StatusBarNotification sbn =
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
- mGroupHelper.onNotificationPosted(sbn);
+ mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
@@ -199,9 +207,48 @@ public class GroupHelperTest extends NotificationTestCase {
for (; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn =
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
- mGroupHelper.onNotificationPosted(sbn);
+ mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(2)).removeAutoGroup(anyString());
verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
}
+
+ @Test
+ public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled()
+ throws Exception {
+ final String pkg = "package";
+ List<StatusBarNotification> posted = new ArrayList<>();
+ for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+ posted.add(sbn);
+ mGroupHelper.onNotificationPosted(sbn, false);
+ }
+ verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
+ verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ Mockito.reset(mCallback);
+
+ for (int i = posted.size() - 2; i >= 0; i--) {
+ mGroupHelper.onNotificationRemoved(posted.remove(i));
+ }
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ Mockito.reset(mCallback);
+
+ // only one child remains
+ Map<String, LinkedHashSet<String>> ungroupedForUser =
+ mGroupHelper.mUngroupedNotifications.get(UserHandle.USER_SYSTEM);
+ assertNotNull(ungroupedForUser);
+ assertEquals(1, ungroupedForUser.get(pkg).size());
+
+ // Add new notification; it should be autogrouped even though the total count is
+ // < AUTOGROUP_AT_COUNT
+ final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
+ posted.add(sbn);
+ mGroupHelper.onNotificationPosted(sbn, true);
+ verify(mCallback, times(posted.size())).addAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroup(anyString());
+ verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+ }
}
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 09af1e2fd7d4..04b42f1ee312 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -48,6 +48,7 @@ import android.app.NotificationManager;
import android.companion.ICompanionDeviceManager;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -60,7 +61,6 @@ import android.os.UserHandle;
import android.provider.Settings.Secure;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
-import android.service.notification.ZenModeConfig;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -1339,7 +1339,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
runnable.run();
waitForIdle();
- verify(mGroupHelper, times(1)).onNotificationPosted(any());
+ verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
}
@Test
@@ -1355,7 +1355,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
runnable.run();
waitForIdle();
- verify(mGroupHelper, times(1)).onNotificationPosted(any());
+ verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
}
@Test
@@ -1371,7 +1371,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
runnable.run();
waitForIdle();
- verify(mGroupHelper, never()).onNotificationPosted(any());
+ verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean());
}
@Test
@@ -1550,4 +1550,14 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mAssistants, times(2)).migrateToXml();
}
+
+ @Test
+ public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception {
+ ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
+ mNotificationManagerService.mZenModeHelper = mZenModeHelper;
+ mNotificationManagerService.mLocaleChangeReceiver.onReceive(mContext,
+ new Intent(Intent.ACTION_LOCALE_CHANGED));
+
+ verify(mZenModeHelper, times(1)).updateDefaultZenRules();
+ }
}
diff --git a/services/tests/servicestests/res/raw/conntestapp b/services/tests/servicestests/res/raw/conntestapp
index 6093303658b5..e99316446f7e 100644
--- a/services/tests/servicestests/res/raw/conntestapp
+++ b/services/tests/servicestests/res/raw/conntestapp
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
index f02cf5183e2f..5b4c10f11af8 100644
--- a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
@@ -20,7 +20,6 @@ import static android.util.DebugUtils.valueToString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -37,8 +36,6 @@ import android.content.IntentSender;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Bundle;
@@ -101,19 +98,16 @@ public class ConnOnActivityStartTest {
private static final long WAIT_FOR_INSTALL_TIMEOUT_MS = 2000; // 2 sec
- private static final long NETWORK_CHECK_TIMEOUT_MS = 6000; // 6 sec
+ private static final long NETWORK_CHECK_TIMEOUT_MS = 4000; // 4 sec
private static final long SCREEN_ON_DELAY_MS = 500; // 0.5 sec
- private static final String NETWORK_STATUS_SEPARATOR = "\\|";
-
private static final int REPEAT_TEST_COUNT = 5;
private static Context mContext;
private static UiDevice mUiDevice;
private static int mTestPkgUid;
private static BatteryManager mBatteryManager;
- private static ConnectivityManager mConnectivityManager;
@BeforeClass
public static void setUpOnce() throws Exception {
@@ -126,8 +120,6 @@ public class ConnOnActivityStartTest {
mTestPkgUid = mContext.getPackageManager().getPackageUid(TEST_PKG, 0);
mBatteryManager = (BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE);
- mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
}
@AfterClass
@@ -144,9 +136,6 @@ public class ConnOnActivityStartTest {
@Test
public void testStartActivity_batterySaver() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
setBatterySaverMode(true);
try {
testConnOnActivityStart("testStartActivity_batterySaver");
@@ -157,9 +146,6 @@ public class ConnOnActivityStartTest {
@Test
public void testStartActivity_dataSaver() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
setDataSaverMode(true);
try {
testConnOnActivityStart("testStartActivity_dataSaver");
@@ -170,9 +156,6 @@ public class ConnOnActivityStartTest {
@Test
public void testStartActivity_dozeMode() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
setDozeMode(true);
try {
testConnOnActivityStart("testStartActivity_dozeMode");
@@ -183,9 +166,6 @@ public class ConnOnActivityStartTest {
@Test
public void testStartActivity_appStandby() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
try{
turnBatteryOff();
setAppIdle(true);
@@ -200,9 +180,6 @@ public class ConnOnActivityStartTest {
@Test
public void testStartActivity_backgroundRestrict() throws Exception {
- if (!isNetworkAvailable()) {
- fail("Device doesn't have network connectivity");
- }
updateRestrictBackgroundBlacklist(true);
try {
testConnOnActivityStart("testStartActivity_backgroundRestrict");
@@ -347,11 +324,6 @@ public class ConnOnActivityStartTest {
+ maxTries + " attempts. Last result: '" + result + "'");
}
- private boolean isNetworkAvailable() throws Exception {
- final NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
- return networkInfo != null && networkInfo.isConnected();
- }
-
private void startActivityAndCheckNetworkAccess() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final Intent launchIntent = new Intent().setComponent(
@@ -361,15 +333,15 @@ public class ConnOnActivityStartTest {
extras.putBinder(EXTRA_NETWORK_STATE_OBSERVER, new INetworkStateObserver.Stub() {
@Override
public void onNetworkStateChecked(String resultData) {
- errors[0] = checkForAvailability(resultData);
+ errors[0] = resultData;
latch.countDown();
}
});
launchIntent.putExtras(extras);
mContext.startActivity(launchIntent);
if (latch.await(NETWORK_CHECK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
- if (!errors[0].isEmpty()) {
- fail("Network not available for test app " + mTestPkgUid);
+ if (errors[0] != null) {
+ fail("Network not available for test app " + mTestPkgUid + ". " + errors[0]);
}
} else {
fail("Timed out waiting for network availability status from test app " + mTestPkgUid);
@@ -381,43 +353,6 @@ public class ConnOnActivityStartTest {
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(finishIntent);
}
-
- private String checkForAvailability(String resultData) {
- if (resultData == null) {
- assertNotNull("Network status from app2 is null, Uid: " + mTestPkgUid, resultData);
- }
- // Network status format is described on MyBroadcastReceiver.checkNetworkStatus()
- final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR);
- assertEquals("Wrong network status: " + resultData + ", Uid: " + mTestPkgUid,
- 5, parts.length); // Sanity check
- final NetworkInfo.State state = parts[0].equals("null")
- ? null : NetworkInfo.State.valueOf(parts[0]);
- final NetworkInfo.DetailedState detailedState = parts[1].equals("null")
- ? null : NetworkInfo.DetailedState.valueOf(parts[1]);
- final boolean connected = Boolean.valueOf(parts[2]);
- final String connectionCheckDetails = parts[3];
- final String networkInfo = parts[4];
-
- final StringBuilder errors = new StringBuilder();
- final NetworkInfo.State expectedState = NetworkInfo.State.CONNECTED;
- final NetworkInfo.DetailedState expectedDetailedState = NetworkInfo.DetailedState.CONNECTED;
-
- if (true != connected) {
- errors.append(String.format("External site connection failed: expected %s, got %s\n",
- true, connected));
- }
- if (expectedState != state || expectedDetailedState != detailedState) {
- errors.append(String.format("Connection state mismatch: expected %s/%s, got %s/%s\n",
- expectedState, expectedDetailedState, state, detailedState));
- }
-
- if (errors.length() > 0) {
- errors.append("\tnetworkInfo: " + networkInfo + "\n");
- errors.append("\tconnectionCheckDetails: " + connectionCheckDetails + "\n");
- }
- return errors.toString();
- }
-
private static void installAppAndAssertInstalled() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final int[] result = {PackageInstaller.STATUS_SUCCESS};
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/Android.mk b/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
index 02afe83efb99..030a709b0215 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
+++ b/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
@@ -17,7 +17,6 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
LOCAL_STATIC_JAVA_LIBRARIES := servicestests-aidl
LOCAL_SRC_FILES := $(call all-subdir-java-files)
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml b/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml
index 0da3562c9afa..66714109a761 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml
+++ b/services/tests/servicestests/test-apps/ConnTestApp/AndroidManifest.xml
@@ -17,8 +17,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.servicestests.apps.conntestapp">
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+ <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<application>
<activity android:name=".ConnTestActivity"
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java b/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
index 11ebfca67ad4..c5c7add29f93 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
+++ b/services/tests/servicestests/test-apps/ConnTestApp/src/com/android/servicestests/apps/conntestapp/ConnTestActivity.java
@@ -21,19 +21,17 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
+import android.net.INetworkPolicyManager;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.INetworkManagementService;
+import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import com.android.servicestests.aidl.INetworkStateObserver;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
public class ConnTestActivity extends Activity {
private static final String TAG = ConnTestActivity.class.getSimpleName();
@@ -41,10 +39,6 @@ public class ConnTestActivity extends Activity {
private static final String ACTION_FINISH_ACTIVITY = TEST_PKG + ".FINISH";
private static final String EXTRA_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
- private static final int NETWORK_TIMEOUT_MS = 5 * 1000;
-
- private static final String NETWORK_STATUS_TEMPLATE = "%s|%s|%s|%s|%s";
-
private BroadcastReceiver finishCommandReceiver = null;
@Override
@@ -84,7 +78,7 @@ public class ConnTestActivity extends Activity {
if (observer != null) {
AsyncTask.execute(() -> {
try {
- observer.onNetworkStateChecked(checkNetworkStatus(ConnTestActivity.this));
+ observer.onNetworkStateChecked(checkNetworkStatus());
} catch (RemoteException e) {
Log.e(TAG, "Error occured while notifying the observer: " + e);
}
@@ -93,78 +87,25 @@ public class ConnTestActivity extends Activity {
}
/**
- * Checks whether the network is available and return a string which can then be send as a
- * result data for the ordered broadcast.
- *
- * <p>
- * The string has the following format:
- *
- * <p><pre><code>
- * NetinfoState|NetinfoDetailedState|RealConnectionCheck|RealConnectionCheckDetails|Netinfo
- * </code></pre>
- *
- * <p>Where:
- *
- * <ul>
- * <li>{@code NetinfoState}: enum value of {@link NetworkInfo.State}.
- * <li>{@code NetinfoDetailedState}: enum value of {@link NetworkInfo.DetailedState}.
- * <li>{@code RealConnectionCheck}: boolean value of a real connection check (i.e., an attempt
- * to access an external website.
- * <li>{@code RealConnectionCheckDetails}: if HTTP output core or exception string of the real
- * connection attempt
- * <li>{@code Netinfo}: string representation of the {@link NetworkInfo}.
- * </ul>
+ * Checks whether the network is restricted.
*
- * For example, if the connection was established fine, the result would be something like:
- * <p><pre><code>
- * CONNECTED|CONNECTED|true|200|[type: WIFI[], state: CONNECTED/CONNECTED, reason: ...]
- * </code></pre>
+ * @return null if network is not restricted, otherwise an error message.
*/
- private String checkNetworkStatus(Context context) {
- final ConnectivityManager cm =
- (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- final String address = "http://example.com";
- final NetworkInfo networkInfo = cm.getActiveNetworkInfo();
- Log.d(TAG, "Running checkNetworkStatus() on thread "
- + Thread.currentThread().getName() + " for UID " + getUid(context)
- + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address);
- boolean checkStatus = false;
- String checkDetails = "N/A";
+ private String checkNetworkStatus() {
+ final INetworkManagementService nms = INetworkManagementService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
+ final INetworkPolicyManager npms = INetworkPolicyManager.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
try {
- final URL url = new URL(address);
- final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setReadTimeout(NETWORK_TIMEOUT_MS);
- conn.setConnectTimeout(NETWORK_TIMEOUT_MS / 2);
- conn.setRequestMethod("GET");
- conn.setDoInput(true);
- conn.connect();
- final int response = conn.getResponseCode();
- checkStatus = true;
- checkDetails = "HTTP response for " + address + ": " + response;
- } catch (Exception e) {
- checkStatus = false;
- checkDetails = "Exception getting " + address + ": " + e;
- }
- Log.d(TAG, checkDetails);
- final String state, detailedState;
- if (networkInfo != null) {
- state = networkInfo.getState().name();
- detailedState = networkInfo.getDetailedState().name();
- } else {
- state = detailedState = "null";
- }
- final String status = String.format(NETWORK_STATUS_TEMPLATE, state, detailedState,
- Boolean.valueOf(checkStatus), checkDetails, networkInfo);
- Log.d(TAG, "Offering " + status);
- return status;
- }
-
- private int getUid(Context context) {
- final String packageName = context.getPackageName();
- try {
- return context.getPackageManager().getPackageUid(packageName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- throw new IllegalStateException("Could not get UID for " + packageName, e);
+ final boolean restrictedByFwRules = nms.isNetworkRestricted(Process.myUid());
+ final boolean restrictedByUidRules = npms.isUidNetworkingBlocked(Process.myUid(), true);
+ if (restrictedByFwRules || restrictedByUidRules) {
+ return "Network is restricted by fwRules: " + restrictedByFwRules
+ + " and uidRules: " + restrictedByUidRules;
+ }
+ return null;
+ } catch (RemoteException e) {
+ return "Error talking to system server: " + e;
}
}
} \ No newline at end of file