diff options
19 files changed, 659 insertions, 612 deletions
diff --git a/api/current.txt b/api/current.txt index 9c2aba7e2a95..739e7f250939 100644 --- a/api/current.txt +++ b/api/current.txt @@ -37821,6 +37821,14 @@ package android.telephony { field public static final int STATUS_UNKNOWN_ERROR = 4; // 0x4 } + public class MbmsStreamingManager { + method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, int) throws android.telephony.mbms.MbmsException; + method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback) throws android.telephony.mbms.MbmsException; + method public void dispose(); + method public void getStreamingServices(java.util.List<java.lang.String>) throws android.telephony.mbms.MbmsException; + method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback) throws android.telephony.mbms.MbmsException; + } + public class NeighboringCellInfo implements android.os.Parcelable { ctor public deprecated NeighboringCellInfo(); ctor public deprecated NeighboringCellInfo(int, int); @@ -38433,6 +38441,95 @@ package android.telephony.gsm { } +package android.telephony.mbms { + + public class MbmsException extends java.lang.Exception { + method public int getErrorCode(); + field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3 + field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2 + field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1 + field public static final int SUCCESS = 0; // 0x0 + } + + public static class MbmsException.GeneralErrors { + ctor public MbmsException.GeneralErrors(); + field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf + field public static final int ERROR_IN_E911 = 204; // 0xcc + field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9 + field public static final int ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE = 203; // 0xcb + field public static final int ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE = 205; // 0xcd + field public static final int ERROR_OUT_OF_MEMORY = 202; // 0xca + field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce + } + + public static class MbmsException.InitializationErrors { + ctor public MbmsException.InitializationErrors(); + field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66 + field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65 + field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67 + } + + public static class MbmsException.StreamingErrors { + ctor public MbmsException.StreamingErrors(); + field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d + field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f + field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e + } + + public class MbmsStreamingManagerCallback extends android.os.Binder { + ctor public MbmsStreamingManagerCallback(); + method public void error(int, java.lang.String) throws android.os.RemoteException; + method public void middlewareReady() throws android.os.RemoteException; + method public void streamingServicesUpdated(java.util.List<android.telephony.mbms.StreamingServiceInfo>) throws android.os.RemoteException; + } + + public class ServiceInfo implements android.os.Parcelable { + method public int describeContents(); + method public java.lang.String getClassName(); + method public java.util.List<java.util.Locale> getLocales(); + method public java.util.Map<java.util.Locale, java.lang.String> getNames(); + method public java.lang.String getServiceId(); + method public java.util.Date getSessionEndTime(); + method public java.util.Date getSessionStartTime(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.mbms.ServiceInfo> CREATOR; + } + + public class StreamingService { + method public void dispose() throws android.telephony.mbms.MbmsException; + method public android.telephony.mbms.StreamingServiceInfo getInfo(); + method public android.net.Uri getPlaybackUri() throws android.telephony.mbms.MbmsException; + method public void stopStreaming() throws android.telephony.mbms.MbmsException; + field public static final int BROADCAST_METHOD = 1; // 0x1 + field public static final int REASON_BY_USER_REQUEST = 1; // 0x1 + field public static final int REASON_END_OF_SESSION = 2; // 0x2 + field public static final int REASON_FREQUENCY_CONFLICT = 3; // 0x3 + field public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 5; // 0x5 + field public static final int REASON_NONE = 0; // 0x0 + field public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; // 0x5 + field public static final int REASON_OUT_OF_MEMORY = 4; // 0x4 + field public static final int STATE_STALLED = 3; // 0x3 + field public static final int STATE_STARTED = 2; // 0x2 + field public static final int STATE_STOPPED = 1; // 0x1 + field public static final int UNICAST_METHOD = 2; // 0x2 + } + + public class StreamingServiceCallback extends android.os.Binder { + ctor public StreamingServiceCallback(); + method public void broadcastSignalStrengthUpdated(int) throws android.os.RemoteException; + method public void error(int, java.lang.String) throws android.os.RemoteException; + method public void mediaDescriptionUpdated() throws android.os.RemoteException; + method public void streamMethodUpdated(int) throws android.os.RemoteException; + method public void streamStateUpdated(int, int) throws android.os.RemoteException; + field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff + } + + public class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable { + field public static final android.os.Parcelable.Creator<android.telephony.mbms.StreamingServiceInfo> CREATOR; + } + +} + package android.test { public abstract deprecated class ActivityInstrumentationTestCase<T extends android.app.Activity> extends android.test.ActivityTestCase { diff --git a/api/system-current.txt b/api/system-current.txt index 05b1a4214812..0aa5d582d027 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -40992,6 +40992,15 @@ package android.telephony { field public static final int STATUS_UNKNOWN_ERROR = 4; // 0x4 } + public class MbmsStreamingManager { + method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, int) throws android.telephony.mbms.MbmsException; + method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback) throws android.telephony.mbms.MbmsException; + method public void dispose(); + method public void getStreamingServices(java.util.List<java.lang.String>) throws android.telephony.mbms.MbmsException; + method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback) throws android.telephony.mbms.MbmsException; + field public static final java.lang.String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; + } + public class NeighboringCellInfo implements android.os.Parcelable { ctor public deprecated NeighboringCellInfo(); ctor public deprecated NeighboringCellInfo(int, int); @@ -41687,6 +41696,111 @@ package android.telephony.ims { } +package android.telephony.mbms { + + public class MbmsException extends java.lang.Exception { + method public int getErrorCode(); + field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3 + field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2 + field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1 + field public static final int SUCCESS = 0; // 0x0 + } + + public static class MbmsException.GeneralErrors { + ctor public MbmsException.GeneralErrors(); + field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf + field public static final int ERROR_IN_E911 = 204; // 0xcc + field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9 + field public static final int ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE = 203; // 0xcb + field public static final int ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE = 205; // 0xcd + field public static final int ERROR_OUT_OF_MEMORY = 202; // 0xca + field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce + } + + public static class MbmsException.InitializationErrors { + ctor public MbmsException.InitializationErrors(); + field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66 + field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65 + field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67 + } + + public static class MbmsException.StreamingErrors { + ctor public MbmsException.StreamingErrors(); + field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d + field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f + field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e + } + + public class MbmsStreamingManagerCallback extends android.os.Binder { + ctor public MbmsStreamingManagerCallback(); + method public void error(int, java.lang.String) throws android.os.RemoteException; + method public void middlewareReady() throws android.os.RemoteException; + method public void streamingServicesUpdated(java.util.List<android.telephony.mbms.StreamingServiceInfo>) throws android.os.RemoteException; + } + + public class ServiceInfo implements android.os.Parcelable { + method public int describeContents(); + method public java.lang.String getClassName(); + method public java.util.List<java.util.Locale> getLocales(); + method public java.util.Map<java.util.Locale, java.lang.String> getNames(); + method public java.lang.String getServiceId(); + method public java.util.Date getSessionEndTime(); + method public java.util.Date getSessionStartTime(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.mbms.ServiceInfo> CREATOR; + } + + public class StreamingService { + method public void dispose() throws android.telephony.mbms.MbmsException; + method public android.telephony.mbms.StreamingServiceInfo getInfo(); + method public android.net.Uri getPlaybackUri() throws android.telephony.mbms.MbmsException; + method public void stopStreaming() throws android.telephony.mbms.MbmsException; + field public static final int BROADCAST_METHOD = 1; // 0x1 + field public static final int REASON_BY_USER_REQUEST = 1; // 0x1 + field public static final int REASON_END_OF_SESSION = 2; // 0x2 + field public static final int REASON_FREQUENCY_CONFLICT = 3; // 0x3 + field public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 5; // 0x5 + field public static final int REASON_NONE = 0; // 0x0 + field public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; // 0x5 + field public static final int REASON_OUT_OF_MEMORY = 4; // 0x4 + field public static final int STATE_STALLED = 3; // 0x3 + field public static final int STATE_STARTED = 2; // 0x2 + field public static final int STATE_STOPPED = 1; // 0x1 + field public static final int UNICAST_METHOD = 2; // 0x2 + } + + public class StreamingServiceCallback extends android.os.Binder { + ctor public StreamingServiceCallback(); + method public void broadcastSignalStrengthUpdated(int) throws android.os.RemoteException; + method public void error(int, java.lang.String) throws android.os.RemoteException; + method public void mediaDescriptionUpdated() throws android.os.RemoteException; + method public void streamMethodUpdated(int) throws android.os.RemoteException; + method public void streamStateUpdated(int, int) throws android.os.RemoteException; + field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff + } + + public class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable { + ctor public StreamingServiceInfo(java.util.Map<java.util.Locale, java.lang.String>, java.lang.String, java.util.List<java.util.Locale>, java.lang.String, java.util.Date, java.util.Date); + field public static final android.os.Parcelable.Creator<android.telephony.mbms.StreamingServiceInfo> CREATOR; + } + +} + +package android.telephony.mbms.vendor { + + public class MbmsStreamingServiceBase extends android.os.Binder { + ctor public MbmsStreamingServiceBase(); + method public void dispose(int) throws android.os.RemoteException; + method public void disposeStream(int, java.lang.String) throws android.os.RemoteException; + method public android.net.Uri getPlaybackUri(int, java.lang.String) throws android.os.RemoteException; + method public int getStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException; + method public int initialize(android.telephony.mbms.MbmsStreamingManagerCallback, int) throws android.os.RemoteException; + method public int startStreaming(int, java.lang.String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException; + method public void stopStreaming(int, java.lang.String) throws android.os.RemoteException; + } + +} + package android.test { public abstract deprecated class ActivityInstrumentationTestCase<T extends android.app.Activity> extends android.test.ActivityTestCase { diff --git a/api/test-current.txt b/api/test-current.txt index 1d9a2d841f18..93c9768bc2b6 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -37920,6 +37920,14 @@ package android.telephony { field public static final int STATUS_UNKNOWN_ERROR = 4; // 0x4 } + public class MbmsStreamingManager { + method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback, int) throws android.telephony.mbms.MbmsException; + method public static android.telephony.MbmsStreamingManager create(android.content.Context, android.telephony.mbms.MbmsStreamingManagerCallback) throws android.telephony.mbms.MbmsException; + method public void dispose(); + method public void getStreamingServices(java.util.List<java.lang.String>) throws android.telephony.mbms.MbmsException; + method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback) throws android.telephony.mbms.MbmsException; + } + public class NeighboringCellInfo implements android.os.Parcelable { ctor public deprecated NeighboringCellInfo(); ctor public deprecated NeighboringCellInfo(int, int); @@ -38532,6 +38540,95 @@ package android.telephony.gsm { } +package android.telephony.mbms { + + public class MbmsException extends java.lang.Exception { + method public int getErrorCode(); + field public static final int ERROR_MIDDLEWARE_LOST = 3; // 0x3 + field public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; // 0x2 + field public static final int ERROR_NO_UNIQUE_MIDDLEWARE = 1; // 0x1 + field public static final int SUCCESS = 0; // 0x0 + } + + public static class MbmsException.GeneralErrors { + ctor public MbmsException.GeneralErrors(); + field public static final int ERROR_CARRIER_CHANGE_NOT_ALLOWED = 207; // 0xcf + field public static final int ERROR_IN_E911 = 204; // 0xcc + field public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; // 0xc9 + field public static final int ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE = 203; // 0xcb + field public static final int ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE = 205; // 0xcd + field public static final int ERROR_OUT_OF_MEMORY = 202; // 0xca + field public static final int ERROR_UNABLE_TO_READ_SIM = 206; // 0xce + } + + public static class MbmsException.InitializationErrors { + ctor public MbmsException.InitializationErrors(); + field public static final int ERROR_APP_PERMISSIONS_NOT_GRANTED = 102; // 0x66 + field public static final int ERROR_DUPLICATE_INITIALIZE = 101; // 0x65 + field public static final int ERROR_UNABLE_TO_INITIALIZE = 103; // 0x67 + } + + public static class MbmsException.StreamingErrors { + ctor public MbmsException.StreamingErrors(); + field public static final int ERROR_CONCURRENT_SERVICE_LIMIT_REACHED = 301; // 0x12d + field public static final int ERROR_DUPLICATE_START_STREAM = 303; // 0x12f + field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e + } + + public class MbmsStreamingManagerCallback extends android.os.Binder { + ctor public MbmsStreamingManagerCallback(); + method public void error(int, java.lang.String) throws android.os.RemoteException; + method public void middlewareReady() throws android.os.RemoteException; + method public void streamingServicesUpdated(java.util.List<android.telephony.mbms.StreamingServiceInfo>) throws android.os.RemoteException; + } + + public class ServiceInfo implements android.os.Parcelable { + method public int describeContents(); + method public java.lang.String getClassName(); + method public java.util.List<java.util.Locale> getLocales(); + method public java.util.Map<java.util.Locale, java.lang.String> getNames(); + method public java.lang.String getServiceId(); + method public java.util.Date getSessionEndTime(); + method public java.util.Date getSessionStartTime(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.mbms.ServiceInfo> CREATOR; + } + + public class StreamingService { + method public void dispose() throws android.telephony.mbms.MbmsException; + method public android.telephony.mbms.StreamingServiceInfo getInfo(); + method public android.net.Uri getPlaybackUri() throws android.telephony.mbms.MbmsException; + method public void stopStreaming() throws android.telephony.mbms.MbmsException; + field public static final int BROADCAST_METHOD = 1; // 0x1 + field public static final int REASON_BY_USER_REQUEST = 1; // 0x1 + field public static final int REASON_END_OF_SESSION = 2; // 0x2 + field public static final int REASON_FREQUENCY_CONFLICT = 3; // 0x3 + field public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 5; // 0x5 + field public static final int REASON_NONE = 0; // 0x0 + field public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; // 0x5 + field public static final int REASON_OUT_OF_MEMORY = 4; // 0x4 + field public static final int STATE_STALLED = 3; // 0x3 + field public static final int STATE_STARTED = 2; // 0x2 + field public static final int STATE_STOPPED = 1; // 0x1 + field public static final int UNICAST_METHOD = 2; // 0x2 + } + + public class StreamingServiceCallback extends android.os.Binder { + ctor public StreamingServiceCallback(); + method public void broadcastSignalStrengthUpdated(int) throws android.os.RemoteException; + method public void error(int, java.lang.String) throws android.os.RemoteException; + method public void mediaDescriptionUpdated() throws android.os.RemoteException; + method public void streamMethodUpdated(int) throws android.os.RemoteException; + method public void streamStateUpdated(int, int) throws android.os.RemoteException; + field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff + } + + public class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable { + field public static final android.os.Parcelable.Creator<android.telephony.mbms.StreamingServiceInfo> CREATOR; + } + +} + package android.test { public abstract deprecated class ActivityInstrumentationTestCase<T extends android.app.Activity> extends android.test.ActivityTestCase { diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java index 4ff665787c45..1bf9733a1182 100644 --- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java +++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java @@ -140,6 +140,18 @@ public class NetworkNotificationManager { extraInfo = null; } + // Clear any previous notification with lower priority, otherwise return. http://b/63676954. + // A new SIGN_IN notification with a new intent should override any existing one. + final int previousEventId = mNotificationTypeMap.get(id); + final NotificationType previousNotifyType = NotificationType.getFromId(previousEventId); + if (priority(previousNotifyType) > priority(notifyType)) { + Slog.d(TAG, String.format( + "ignoring notification %s for network %s with existing notification %s", + notifyType, id, previousNotifyType)); + return; + } + clearNotification(id); + if (DBG) { Slog.d(TAG, String.format( "showNotification tag=%s event=%s transport=%s extraInfo=%s highPrioriy=%s", @@ -270,4 +282,22 @@ public class NetworkNotificationManager { NotificationType t = NotificationType.getFromId(eventId); return (t != null) ? t.name() : "UNKNOWN"; } + + private static int priority(NotificationType t) { + if (t == null) { + return 0; + } + switch (t) { + case SIGN_IN: + return 4; + case NO_INTERNET: + return 3; + case NETWORK_SWITCH: + return 2; + case LOST_INTERNET: + return 1; + default: + return 0; + } + } } diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java index 1c5aa600580a..50f27ed67a36 100644 --- a/services/core/java/com/android/server/timezone/RulesManagerService.java +++ b/services/core/java/com/android/server/timezone/RulesManagerService.java @@ -57,7 +57,6 @@ import static android.app.timezone.RulesState.STAGED_OPERATION_NONE; import static android.app.timezone.RulesState.STAGED_OPERATION_UNINSTALL; import static android.app.timezone.RulesState.STAGED_OPERATION_UNKNOWN; -// TODO(nfuller) Check error handling best practices in the system server. public final class RulesManagerService extends IRulesManager.Stub { private static final String TAG = "timezone.RulesManagerService"; @@ -336,7 +335,7 @@ public final class RulesManagerService extends IRulesManager.Stub { private final CheckToken mCheckToken; private final ICallback mCallback; - public UninstallRunnable(CheckToken checkToken, ICallback callback) { + UninstallRunnable(CheckToken checkToken, ICallback callback) { mCheckToken = checkToken; mCallback = callback; } @@ -401,54 +400,85 @@ public final class RulesManagerService extends IRulesManager.Stub { if ("-format_state".equals(args[0]) && args[1] != null) { for (char c : args[1].toCharArray()) { switch (c) { - case 'p': // Report operation in progress - pw.println("Operation in progress: " - + rulesState.isOperationInProgress()); + case 'p': { + // Report operation in progress + String value = "Unknown"; + if (rulesState != null) { + value = Boolean.toString(rulesState.isOperationInProgress()); + } + pw.println("Operation in progress: " + value); break; - case 's': // Report system image rules version - pw.println("System rules version: " - + rulesState.getSystemRulesVersion()); + } + case 's': { + // Report system image rules version + String value = "Unknown"; + if (rulesState != null) { + value = rulesState.getSystemRulesVersion(); + } + pw.println("System rules version: " + value); break; - case 'c': // Report current installation state - pw.println("Current install state: " - + distroStatusToString(rulesState.getDistroStatus())); + } + case 'c': { + // Report current installation state + String value = "Unknown"; + if (rulesState != null) { + value = distroStatusToString(rulesState.getDistroStatus()); + } + pw.println("Current install state: " + value); break; - case 'i': // Report currently installed version - DistroRulesVersion installedRulesVersion = - rulesState.getInstalledDistroRulesVersion(); - pw.print("Installed rules version: "); - if (installedRulesVersion == null) { - pw.println("<None>"); - } else { - pw.println(installedRulesVersion.toDumpString()); + } + case 'i': { + // Report currently installed version + String value = "Unknown"; + if (rulesState != null) { + DistroRulesVersion installedRulesVersion = + rulesState.getInstalledDistroRulesVersion(); + if (installedRulesVersion == null) { + value = "<None>"; + } else { + value = installedRulesVersion.toDumpString(); + } } + pw.println("Installed rules version: " + value); break; - case 'o': // Report staged operation type - int stagedOperationType = rulesState.getStagedOperationType(); - pw.println("Staged operation: " - + stagedOperationToString(stagedOperationType)); + } + case 'o': { + // Report staged operation type + String value = "Unknown"; + if (rulesState != null) { + int stagedOperationType = rulesState.getStagedOperationType(); + value = stagedOperationToString(stagedOperationType); + } + pw.println("Staged operation: " + value); break; - case 't': + } + case 't': { // Report staged version (i.e. the one that will be installed next boot // if the staged operation is an install). - pw.print("Staged rules version: "); - DistroRulesVersion stagedDistroRulesVersion = - rulesState.getStagedDistroRulesVersion(); - if (stagedDistroRulesVersion == null) { - pw.println("<None>"); - } else { - pw.println(stagedDistroRulesVersion.toDumpString()); + String value = "Unknown"; + if (rulesState != null) { + DistroRulesVersion stagedDistroRulesVersion = + rulesState.getStagedDistroRulesVersion(); + if (stagedDistroRulesVersion == null) { + value = "<None>"; + } else { + value = stagedDistroRulesVersion.toDumpString(); + } } + pw.println("Staged rules version: " + value); break; - case 'a': + } + case 'a': { // Report the active rules version (i.e. the rules in use by the current // process). pw.println("Active rules version (ICU, libcore): " + ICU.getTZDataVersion() + "," + ZoneInfoDB.getInstance().getVersion()); break; - default: + } + default: { pw.println("Unknown option: " + c); + } } } return; diff --git a/services/core/jni/com_android_server_am_ActivityManagerService.cpp b/services/core/jni/com_android_server_am_ActivityManagerService.cpp index 50e4502a9a3a..14abaad025be 100644 --- a/services/core/jni/com_android_server_am_ActivityManagerService.cpp +++ b/services/core/jni/com_android_server_am_ActivityManagerService.cpp @@ -20,8 +20,8 @@ #include <android_runtime/AndroidRuntime.h> #include <jni.h> -#include <ScopedLocalRef.h> -#include <ScopedPrimitiveArray.h> +#include <nativehelper/ScopedLocalRef.h> +#include <nativehelper/ScopedPrimitiveArray.h> #include <cutils/log.h> #include <utils/misc.h> diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 99ad00b65d18..1a1d31e6ed6a 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -241,15 +241,6 @@ public final class SystemServer { SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } - // - // Default the timezone property to GMT if not set. - // - String timezoneProperty = SystemProperties.get("persist.sys.timezone"); - if (timezoneProperty == null || timezoneProperty.isEmpty()) { - Slog.w(TAG, "Timezone not set; setting to GMT."); - SystemProperties.set("persist.sys.timezone", "GMT"); - } - // If the system has "persist.sys.language" and friends set, replace them with // "persist.sys.locale". Note that the default locale at this point is calculated // using the "-Duser.locale" command line flag. That flag is usually populated by @@ -965,8 +956,13 @@ public final class SystemServer { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } - if (!disableNonCoreServices && context.getResources().getBoolean( - R.bool.config_enableUpdateableTimeZoneRules)) { + // timezone.RulesManagerService will prevent a device starting up if the chain of trust + // required for safe time zone updates might be broken. RuleManagerService cannot do + // this check when mOnlyCore == true, so we don't enable the service in this case. + final boolean startRulesManagerService = + !mOnlyCore && context.getResources().getBoolean( + R.bool.config_enableUpdateableTimeZoneRules); + if (startRulesManagerService) { traceBeginAndSlog("StartTimeZoneRulesManagerService"); mSystemServiceManager.startService(TIME_ZONE_RULES_MANAGER_SERVICE_CLASS); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); diff --git a/telephony/java/android/telephony/MbmsStreamingManager.java b/telephony/java/android/telephony/MbmsStreamingManager.java index 911f83f0d8f1..d69562cb903e 100644 --- a/telephony/java/android/telephony/MbmsStreamingManager.java +++ b/telephony/java/android/telephony/MbmsStreamingManager.java @@ -16,6 +16,8 @@ package android.telephony; +import android.annotation.SdkConstant; +import android.annotation.SystemApi; import android.content.ComponentName; import android.content.Context; import android.content.ServiceConnection; @@ -37,10 +39,17 @@ import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; /** * This class provides functionality for streaming media over MBMS. - * @hide */ public class MbmsStreamingManager { private static final String LOG_TAG = "MbmsStreamingManager"; + + /** + * Service action which must be handled by the middleware implementing the MBMS streaming + * interface. + * @hide + */ + @SystemApi + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; @@ -203,13 +212,23 @@ public class MbmsStreamingManager { return; } catch (RuntimeException e) { Log.e(LOG_TAG, "Runtime exception during initialization"); - mCallbackToApp.error( - MbmsException.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); + try { + mCallbackToApp.error( + MbmsException.InitializationErrors + .ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + } catch (RemoteException e1) { + // ignore + } return; } if (result != MbmsException.SUCCESS) { - mCallbackToApp.error(result, "Error returned during initialization"); + try { + mCallbackToApp.error( + result, "Error returned during initialization"); + } catch (RemoteException e) { + // ignore + } return; } mService.set(streamingService); diff --git a/telephony/java/android/telephony/mbms/FileInfo.java b/telephony/java/android/telephony/mbms/FileInfo.java index 1b873938a3f2..b8e1c49f6b4a 100644 --- a/telephony/java/android/telephony/mbms/FileInfo.java +++ b/telephony/java/android/telephony/mbms/FileInfo.java @@ -61,6 +61,10 @@ public class FileInfo implements Parcelable { } }; + /** + * @hide + * TODO: systemapi + */ public FileInfo(Uri uri, String mimeType, long size, byte[] md5Hash) { this.uri = uri; this.mimeType = mimeType; diff --git a/telephony/java/android/telephony/mbms/FileServiceInfo.java b/telephony/java/android/telephony/mbms/FileServiceInfo.java index 6646dc8a56df..8afe4d3c5230 100644 --- a/telephony/java/android/telephony/mbms/FileServiceInfo.java +++ b/telephony/java/android/telephony/mbms/FileServiceInfo.java @@ -32,6 +32,7 @@ import java.util.Map; public class FileServiceInfo extends ServiceInfo implements Parcelable { private final List<FileInfo> files; + /** @hide TODO: systemapi */ public FileServiceInfo(Map<Locale, String> newNames, String newClassName, List<Locale> newLocales, String newServiceId, Date start, Date end, List<FileInfo> newFiles) { diff --git a/telephony/java/android/telephony/mbms/MbmsException.java b/telephony/java/android/telephony/mbms/MbmsException.java index 8888119f90e6..f51563a1cccb 100644 --- a/telephony/java/android/telephony/mbms/MbmsException.java +++ b/telephony/java/android/telephony/mbms/MbmsException.java @@ -16,7 +16,6 @@ package android.telephony.mbms; -/** @hide */ public class MbmsException extends Exception { /** Indicates that the operation was successful. */ public static final int SUCCESS = 0; @@ -31,7 +30,7 @@ public class MbmsException extends Exception { /** * Indicates that the app attempted to perform an operation on an instance of - * {@link android.telephony.MbmsDownloadManager} or + * TODO: link android.telephony.MbmsDownloadManager or * {@link android.telephony.MbmsStreamingManager} without being bound to the middleware. */ public static final int ERROR_MIDDLEWARE_NOT_BOUND = 2; @@ -47,7 +46,7 @@ public class MbmsException extends Exception { /** * Indicates that the app tried to create more than one instance each of * {@link android.telephony.MbmsStreamingManager} or - * {@link android.telephony.MbmsDownloadManager}. + * TODO: link android.telephony.MbmsDownloadManager */ public static final int ERROR_DUPLICATE_INITIALIZE = 101; /** Indicates that the app is not authorized to access media via MBMS.*/ @@ -64,7 +63,7 @@ public class MbmsException extends Exception { /** * Indicates that the app attempted to perform an operation before receiving notification * that the middleware is ready via {@link MbmsStreamingManagerCallback#middlewareReady()} - * or {@link MbmsDownloadManagerCallback#middlewareReady()}. + * or TODO: link MbmsDownloadManagerCallback#middlewareReady */ public static final int ERROR_MIDDLEWARE_NOT_YET_READY = 201; /** @@ -113,6 +112,8 @@ public class MbmsException extends Exception { /** * Indicates the errors that are applicable only to the file-download use-case + * TODO: unhide + * @hide */ public static class DownloadErrors { /** @@ -127,9 +128,7 @@ public class MbmsException extends Exception { private final int mErrorCode; - /** @hide - * TODO: future systemapi - */ + /** @hide */ public MbmsException(int errorCode) { super(); mErrorCode = errorCode; diff --git a/telephony/java/android/telephony/mbms/MbmsStreamingManagerCallback.java b/telephony/java/android/telephony/mbms/MbmsStreamingManagerCallback.java index 2e91be9acaf7..f67d6e4b96c3 100644 --- a/telephony/java/android/telephony/mbms/MbmsStreamingManagerCallback.java +++ b/telephony/java/android/telephony/mbms/MbmsStreamingManagerCallback.java @@ -16,20 +16,24 @@ package android.telephony.mbms; +import android.content.Context; +import android.os.RemoteException; + import java.util.List; /** - * A Parcelable class with Cell-Broadcast service information. - * @hide + * A callback class that is used to receive information from the middleware on MBMS streaming + * services. An instance of this object should be passed into + * {@link android.telephony.MbmsStreamingManager#create(Context, MbmsStreamingManagerCallback)}. */ public class MbmsStreamingManagerCallback extends IMbmsStreamingManagerCallback.Stub { - - public final static int ERROR_CARRIER_NOT_SUPPORTED = 1; - public final static int ERROR_UNABLE_TO_INITIALIZE = 2; - public final static int ERROR_UNABLE_TO_ALLOCATE_MEMORY = 3; - - - public void error(int errorCode, String message) { + /** + * Called by the middleware when it has detected an error condition. The possible error codes + * are listed in {@link MbmsException}. + * @param errorCode The error code. + * @param message A human-readable message generated by the middleware for debugging purposes. + */ + public void error(int errorCode, String message) throws RemoteException { // default implementation empty } @@ -45,7 +49,8 @@ public class MbmsStreamingManagerCallback extends IMbmsStreamingManagerCallback. * @param services a List of StreamingServiceInfos * */ - public void streamingServicesUpdated(List<StreamingServiceInfo> services) { + public void streamingServicesUpdated(List<StreamingServiceInfo> services) + throws RemoteException { // default implementation empty } @@ -58,7 +63,7 @@ public class MbmsStreamingManagerCallback extends IMbmsStreamingManagerCallback. * or {@link MbmsException.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY} */ @Override - public void middlewareReady() { + public void middlewareReady() throws RemoteException { // default implementation empty } } diff --git a/telephony/java/android/telephony/mbms/ServiceInfo.java b/telephony/java/android/telephony/mbms/ServiceInfo.java index f9ad44c63118..e1ccd439fa41 100644 --- a/telephony/java/android/telephony/mbms/ServiceInfo.java +++ b/telephony/java/android/telephony/mbms/ServiceInfo.java @@ -30,43 +30,21 @@ import java.util.Objects; import java.util.Set; /** - * A Parcelable class with Cell-Broadcast service information. - * @hide + * Describes a cell-broadcast service. This class should not be instantiated directly -- use + * {@link StreamingServiceInfo} or FileServiceInfo TODO: add link once that's unhidden */ public class ServiceInfo implements Parcelable { // arbitrary limit on the number of locale -> name pairs we support final static int MAP_LIMIT = 1000; - /** - * User displayable names listed by language. Unmodifiable. - */ - final Map<Locale, String> names; - - /** - * The class name for this service - used to catagorize and filter - */ - final String className; - - /** - * The languages available for this service content - */ - final List<Locale> locales; - - /** - * The carrier's identifier for the service. - */ - final String serviceId; - - /** - * The start time indicating when this service will be available. - */ - final Date sessionStartTime; - - /** - * The end time indicating when this sesion stops being available. - */ - final Date sessionEndTime; + private final Map<Locale, String> names; + private final String className; + private final List<Locale> locales; + private final String serviceId; + private final Date sessionStartTime; + private final Date sessionEndTime; + /** @hide */ public ServiceInfo(Map<Locale, String> newNames, String newClassName, List<Locale> newLocales, String newServiceId, Date start, Date end) { if (newNames == null || newNames.isEmpty() || TextUtils.isEmpty(newClassName) @@ -89,20 +67,21 @@ public class ServiceInfo implements Parcelable { sessionEndTime = (Date)end.clone(); } - public static final Parcelable.Creator<FileServiceInfo> CREATOR = - new Parcelable.Creator<FileServiceInfo>() { + public static final Parcelable.Creator<ServiceInfo> CREATOR = + new Parcelable.Creator<ServiceInfo>() { @Override - public FileServiceInfo createFromParcel(Parcel source) { - return new FileServiceInfo(source); + public ServiceInfo createFromParcel(Parcel source) { + return new ServiceInfo(source); } @Override - public FileServiceInfo[] newArray(int size) { - return new FileServiceInfo[size]; + public ServiceInfo[] newArray(int size) { + return new ServiceInfo[size]; } }; - ServiceInfo(Parcel in) { + /** @hide */ + protected ServiceInfo(Parcel in) { int mapCount = in.readInt(); if (mapCount > MAP_LIMIT || mapCount < 0) { throw new RuntimeException("bad map length" + mapCount); @@ -152,26 +131,44 @@ public class ServiceInfo implements Parcelable { return 0; } + /** + * User displayable names listed by language. Do not modify the map returned from this method. + */ public Map<Locale, String> getNames() { return names; } + /** + * The class name for this service - used to categorize and filter + */ public String getClassName() { return className; } + /** + * The languages available for this service content + */ public List<Locale> getLocales() { return locales; } + /** + * The carrier's identifier for the service. + */ public String getServiceId() { return serviceId; } + /** + * The start time indicating when this service will be available. + */ public Date getSessionStartTime() { return sessionStartTime; } + /** + * The end time indicating when this session stops being available. + */ public Date getSessionEndTime() { return sessionEndTime; } diff --git a/telephony/java/android/telephony/mbms/StreamingService.java b/telephony/java/android/telephony/mbms/StreamingService.java index c49f8a980cbb..42c78c31c2cb 100644 --- a/telephony/java/android/telephony/mbms/StreamingService.java +++ b/telephony/java/android/telephony/mbms/StreamingService.java @@ -26,7 +26,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * @hide + * Class used to represent a single MBMS stream. After a stream has been started with + * {@link android.telephony.MbmsStreamingManager#startStreaming(StreamingServiceInfo, + * StreamingServiceCallback)}, + * this class is used to hold information about the stream and control it. */ public class StreamingService { private static final String LOG_TAG = "MbmsStreamingService"; @@ -60,7 +63,8 @@ public class StreamingService { /** * State changed due to a call to {@link #stopStreaming()} or - * {@link android.telephony.MbmsStreamingManager#startStreaming(StreamingServiceInfo, StreamingServiceCallback)} + * {@link android.telephony.MbmsStreamingManager#startStreaming(StreamingServiceInfo, + * StreamingServiceCallback)} */ public static final int REASON_BY_USER_REQUEST = 1; diff --git a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java index cab9c23499ea..6a1ff9c2d1d7 100644 --- a/telephony/java/android/telephony/mbms/StreamingServiceCallback.java +++ b/telephony/java/android/telephony/mbms/StreamingServiceCallback.java @@ -16,9 +16,11 @@ package android.telephony.mbms; +import android.os.RemoteException; + /** - * A Callback class for use when the application is actively streaming content. - * @hide + * A callback class for use when the application is actively streaming content. The middleware + * will provide updates on the status of the stream via this callback. */ public class StreamingServiceCallback extends IStreamingServiceCallback.Stub { @@ -31,8 +33,14 @@ public class StreamingServiceCallback extends IStreamingServiceCallback.Stub { */ public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; + /** + * Called by the middleware when it has detected an error condition in this stream. The + * possible error codes are listed in {@link MbmsException}. + * @param errorCode The error code. + * @param message A human-readable message generated by the middleware for debugging purposes. + */ @Override - public void error(int errorCode, String message) { + public void error(int errorCode, String message) throws RemoteException { // default implementation empty } @@ -44,7 +52,7 @@ public class StreamingServiceCallback extends IStreamingServiceCallback.Stub { */ @Override public void streamStateUpdated(@StreamingService.StreamingState int state, - @StreamingService.StreamingStateChangeReason int reason) { + @StreamingService.StreamingStateChangeReason int reason) throws RemoteException { // default implementation empty } @@ -59,7 +67,7 @@ public class StreamingServiceCallback extends IStreamingServiceCallback.Stub { * when parameters have changed to account for time drift. */ @Override - public void mediaDescriptionUpdated() { + public void mediaDescriptionUpdated() throws RemoteException { // default implementation empty } @@ -74,7 +82,7 @@ public class StreamingServiceCallback extends IStreamingServiceCallback.Stub { * for this service due to timing, geography or popularity. */ @Override - public void broadcastSignalStrengthUpdated(int signalStrength) { + public void broadcastSignalStrengthUpdated(int signalStrength) throws RemoteException { // default implementation empty } @@ -95,7 +103,7 @@ public class StreamingServiceCallback extends IStreamingServiceCallback.Stub { * {@link StreamingService#UNICAST_METHOD} */ @Override - public void streamMethodUpdated(int methodType) { + public void streamMethodUpdated(int methodType) throws RemoteException { // default implementation empty } } diff --git a/telephony/java/android/telephony/mbms/StreamingServiceInfo.java b/telephony/java/android/telephony/mbms/StreamingServiceInfo.java index 77ce3bbd696e..58df24d882de 100644 --- a/telephony/java/android/telephony/mbms/StreamingServiceInfo.java +++ b/telephony/java/android/telephony/mbms/StreamingServiceInfo.java @@ -16,6 +16,7 @@ package android.telephony.mbms; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -25,15 +26,24 @@ import java.util.Locale; import java.util.Map; /** - * A Parcelable class Cell-Broadcast media stream information. - * This may not have any more info than ServiceInfo, but kept for completeness. - * @hide + * Describes a single MBMS streaming service. */ public class StreamingServiceInfo extends ServiceInfo implements Parcelable { - public StreamingServiceInfo(Map<Locale, String> newNames, String newClassName, - List<Locale> newLocales, String newServiceId, Date start, Date end) { - super(newNames, newClassName, newLocales, newServiceId, start, end); + /** + * @param names User displayable names listed by language. + * @param className The class name for this service - used by frontend apps to categorize and + * filter. + * @param locales The languages available for this service content. + * @param serviceId The carrier's identifier for the service. + * @param start The start time indicating when this service will be available. + * @param end The end time indicating when this session stops being available. + * @hide + */ + @SystemApi + public StreamingServiceInfo(Map<Locale, String> names, String className, + List<Locale> locales, String serviceId, Date start, Date end) { + super(names, className, locales, serviceId, start, end); } public static final Parcelable.Creator<StreamingServiceInfo> CREATOR = @@ -49,7 +59,7 @@ public class StreamingServiceInfo extends ServiceInfo implements Parcelable { } }; - StreamingServiceInfo(Parcel in) { + private StreamingServiceInfo(Parcel in) { super(in); } diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java index 585d5b9610b7..b2200c300262 100644 --- a/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java +++ b/telephony/java/android/telephony/mbms/vendor/MbmsStreamingServiceBase.java @@ -17,18 +17,23 @@ package android.telephony.mbms.vendor; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.net.Uri; import android.os.RemoteException; import android.telephony.mbms.IMbmsStreamingManagerCallback; import android.telephony.mbms.IStreamingServiceCallback; import android.telephony.mbms.MbmsException; +import android.telephony.mbms.MbmsStreamingManagerCallback; +import android.telephony.mbms.StreamingService; +import android.telephony.mbms.StreamingServiceCallback; +import android.telephony.mbms.StreamingServiceInfo; import java.util.List; /** * @hide - * TODO: future systemapi */ +@SystemApi public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { /** * Initialize streaming service for this app and subId, registering the listener. @@ -44,13 +49,39 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { * @param listener The callback to use to communicate with the app. * @param subscriptionId The subscription ID to use. */ - @Override - public int initialize(IMbmsStreamingManagerCallback listener, int subscriptionId) + public int initialize(MbmsStreamingManagerCallback listener, int subscriptionId) throws RemoteException { return 0; } /** + * Actual AIDL implementation that hides the callback AIDL from the middleware. + * @hide + */ + @Override + public final int initialize(IMbmsStreamingManagerCallback listener, int subscriptionId) + throws RemoteException { + return initialize(new MbmsStreamingManagerCallback() { + @Override + public void error(int errorCode, String message) throws RemoteException { + listener.error(errorCode, message); + } + + @Override + public void streamingServicesUpdated(List<StreamingServiceInfo> services) throws + RemoteException { + listener.streamingServicesUpdated(services); + } + + @Override + public void middlewareReady() throws RemoteException { + listener.middlewareReady(); + } + }, subscriptionId); + } + + + /** * Registers serviceClasses of interest with the appName/subId key. * Starts async fetching data on streaming services of matching classes to be reported * later via {@link IMbmsStreamingManagerCallback#streamingServicesUpdated(List)} @@ -85,10 +116,47 @@ public class MbmsStreamingServiceBase extends IMbmsStreamingService.Stub { * @param listener The listener object on which the app wishes to receive updates. * @return Any error in {@link android.telephony.mbms.MbmsException.GeneralErrors} */ + public int startStreaming(int subscriptionId, String serviceId, + StreamingServiceCallback listener) throws RemoteException { + return 0; + } + + /** + * Actual AIDL implementation of startStreaming that hides the callback AIDL from the + * middleware. + * @hide + */ @Override public int startStreaming(int subscriptionId, String serviceId, IStreamingServiceCallback listener) throws RemoteException { - return 0; + return startStreaming(subscriptionId, serviceId, new StreamingServiceCallback() { + @Override + public void error(int errorCode, String message) throws RemoteException { + listener.error(errorCode, message); + } + + @Override + public void streamStateUpdated(@StreamingService.StreamingState int state, + @StreamingService.StreamingStateChangeReason int reason) + throws RemoteException { + listener.streamStateUpdated(state, reason); + } + + @Override + public void mediaDescriptionUpdated() throws RemoteException { + listener.mediaDescriptionUpdated(); + } + + @Override + public void broadcastSignalStrengthUpdated(int signalStrength) throws RemoteException { + listener.broadcastSignalStrengthUpdated(signalStrength); + } + + @Override + public void streamMethodUpdated(int methodType) throws RemoteException { + listener.streamMethodUpdated(methodType); + } + }); } /** diff --git a/tests/CoreTests/android/core/HeapTest.java b/tests/CoreTests/android/core/HeapTest.java deleted file mode 100644 index 400d0412c58e..000000000000 --- a/tests/CoreTests/android/core/HeapTest.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.core; - -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; -import android.test.suitebuilder.annotation.Suppress; -import dalvik.system.VMRuntime; -import junit.framework.TestCase; - -import java.lang.ref.PhantomReference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; -import java.util.LinkedList; -import java.util.Random; - - -public class HeapTest extends TestCase { - - private static final String TAG = "HeapTest"; - - /** - * Returns a WeakReference to an object that has no - * other references. This is done in a separate method - * to ensure that the Object's address isn't sitting in - * a stale local register. - */ - private WeakReference<Object> newRef() { - return new WeakReference<Object>(new Object()); - } - - private static void makeRefs(Object objects[], SoftReference<Object> refs[]) { - for (int i = 0; i < objects.length; i++) { - objects[i] = (Object) new byte[8 * 1024]; - refs[i] = new SoftReference<Object>(objects[i]); - } - } - - private static <T> int checkRefs(SoftReference<T> refs[], int last) { - int i; - int numCleared = 0; - for (i = 0; i < refs.length; i++) { - Object o = refs[i].get(); - if (o == null) { - numCleared++; - } - } - if (numCleared != last) { - Log.i(TAG, "****** " + numCleared + "/" + i + " cleared ******"); - } - return numCleared; - } - - private static void clearRefs(Object objects[], int skip) { - for (int i = 0; i < objects.length; i += skip) { - objects[i] = null; - } - } - - private static void clearRefs(Object objects[]) { - clearRefs(objects, 1); - } - - private static <T> void checkRefs(T objects[], SoftReference<T> refs[]) { - boolean ok = true; - - for (int i = 0; i < objects.length; i++) { - if (refs[i].get() != objects[i]) { - ok = false; - } - } - if (!ok) { - throw new RuntimeException("Test failed: soft refs not cleared"); - } - } - - @MediumTest - public void testGcSoftRefs() throws Exception { - final int NUM_REFS = 128; - - Object objects[] = new Object[NUM_REFS]; - SoftReference<Object> refs[] = new SoftReference[objects.length]; - - /* Create a bunch of objects and a parallel array - * of SoftReferences. - */ - makeRefs(objects, refs); - Runtime.getRuntime().gc(); - - /* Let go of some of the hard references to the objects so that - * the references can be cleared. - */ - clearRefs(objects, 3); - - /* Collect all softly-reachable objects. - */ - VMRuntime.getRuntime().gcSoftReferences(); - Runtime.getRuntime().runFinalization(); - - /* Make sure that the objects were collected. - */ - checkRefs(objects, refs); - - /* Remove more hard references and re-check. - */ - clearRefs(objects, 2); - VMRuntime.getRuntime().gcSoftReferences(); - Runtime.getRuntime().runFinalization(); - checkRefs(objects, refs); - - /* Remove the rest of the references and re-check. - */ - /* Remove more hard references and re-check. - */ - clearRefs(objects); - VMRuntime.getRuntime().gcSoftReferences(); - Runtime.getRuntime().runFinalization(); - checkRefs(objects, refs); - } - - public void xxtestSoftRefPartialClean() throws Exception { - final int NUM_REFS = 128; - - Object objects[] = new Object[NUM_REFS]; - SoftReference<Object> refs[] = new SoftReference[objects.length]; - - /* Create a bunch of objects and a parallel array - * of SoftReferences. - */ - makeRefs(objects, refs); - Runtime.getRuntime().gc(); - - /* Let go of the hard references to the objects so that - * the references can be cleared. - */ - clearRefs(objects); - - /* Start creating a bunch of temporary and permanent objects - * to drive GC. - */ - final int NUM_OBJECTS = 64 * 1024; - Object junk[] = new Object[NUM_OBJECTS]; - Random random = new Random(); - - int i = 0; - int mod = 0; - int totalSize = 0; - int cleared = -1; - while (i < junk.length && totalSize < 8 * 1024 * 1024) { - int r = random.nextInt(64 * 1024) + 128; - Object o = (Object) new byte[r]; - if (++mod % 16 == 0) { - junk[i++] = o; - totalSize += r * 4; - } - cleared = checkRefs(refs, cleared); - } - } - - private static void makeRefs(Object objects[], WeakReference<Object> refs[]) { - for (int i = 0; i < objects.length; i++) { - objects[i] = new Object(); - refs[i] = new WeakReference<Object>(objects[i]); - } - } - - private static <T> void checkRefs(T objects[], WeakReference<T> refs[]) { - boolean ok = true; - - for (int i = 0; i < objects.length; i++) { - if (refs[i].get() != objects[i]) { - ok = false; - } - } - if (!ok) { - throw new RuntimeException("Test failed: " + - "weak refs not cleared"); - } - } - - @MediumTest - public void testWeakRefs() throws Exception { - final int NUM_REFS = 16; - - Object objects[] = new Object[NUM_REFS]; - WeakReference<Object> refs[] = new WeakReference[objects.length]; - - /* Create a bunch of objects and a parallel array - * of WeakReferences. - */ - makeRefs(objects, refs); - Runtime.getRuntime().gc(); - checkRefs(objects, refs); - - /* Clear out every other strong reference. - */ - for (int i = 0; i < objects.length; i += 2) { - objects[i] = null; - } - Runtime.getRuntime().gc(); - checkRefs(objects, refs); - - /* Clear out the rest of them. - */ - for (int i = 0; i < objects.length; i++) { - objects[i] = null; - } - Runtime.getRuntime().gc(); - checkRefs(objects, refs); - } - - private static void makeRefs(Object objects[], PhantomReference<Object> refs[], - ReferenceQueue<Object> queue) { - for (int i = 0; i < objects.length; i++) { - objects[i] = new Object(); - refs[i] = new PhantomReference<Object>(objects[i], queue); - } - } - - static <T> void checkRefs(T objects[], PhantomReference<T> refs[], - ReferenceQueue<T> queue) { - boolean ok = true; - - /* Make sure that the reference that should be on - * the queue are marked as enqueued. Once we - * pull them off the queue, they will no longer - * be marked as enqueued. - */ - for (int i = 0; i < objects.length; i++) { - if (objects[i] == null && refs[i] != null) { - if (!refs[i].isEnqueued()) { - ok = false; - } - } - } - if (!ok) { - throw new RuntimeException("Test failed: " + - "phantom refs not marked as enqueued"); - } - - /* Make sure that all of the references on the queue - * are supposed to be there. - */ - PhantomReference<T> ref; - while ((ref = (PhantomReference<T>) queue.poll()) != null) { - /* Find the list index that corresponds to this reference. - */ - int i; - for (i = 0; i < objects.length; i++) { - if (refs[i] == ref) { - break; - } - } - if (i == objects.length) { - throw new RuntimeException("Test failed: " + - "unexpected ref on queue"); - } - if (objects[i] != null) { - throw new RuntimeException("Test failed: " + - "reference enqueued for strongly-reachable " + - "object"); - } - refs[i] = null; - - /* TODO: clear doesn't do much, since we're losing the - * strong ref to the ref object anyway. move the ref - * into another list. - */ - ref.clear(); - } - - /* We've visited all of the enqueued references. - * Make sure that there aren't any other references - * that should have been enqueued. - * - * NOTE: there is a race condition here; this assumes - * that the VM has serviced all outstanding reference - * enqueue() calls. - */ - for (int i = 0; i < objects.length; i++) { - if (objects[i] == null && refs[i] != null) { -// System.out.println("HeapTest/PhantomRefs: refs[" + i + -// "] should be enqueued"); - ok = false; - } - } - if (!ok) { - throw new RuntimeException("Test failed: " + - "phantom refs not enqueued"); - } - } - - @MediumTest - public void testPhantomRefs() throws Exception { - final int NUM_REFS = 16; - - Object objects[] = new Object[NUM_REFS]; - PhantomReference<Object> refs[] = new PhantomReference[objects.length]; - ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); - - /* Create a bunch of objects and a parallel array - * of PhantomReferences. - */ - makeRefs(objects, refs, queue); - Runtime.getRuntime().gc(); - checkRefs(objects, refs, queue); - - /* Clear out every other strong reference. - */ - for (int i = 0; i < objects.length; i += 2) { - objects[i] = null; - } - // System.out.println("HeapTest/PhantomRefs: cleared evens"); - Runtime.getRuntime().gc(); - Runtime.getRuntime().runFinalization(); - checkRefs(objects, refs, queue); - - /* Clear out the rest of them. - */ - for (int i = 0; i < objects.length; i++) { - objects[i] = null; - } - // System.out.println("HeapTest/PhantomRefs: cleared all"); - Runtime.getRuntime().gc(); - Runtime.getRuntime().runFinalization(); - checkRefs(objects, refs, queue); - } - - private static int sNumFinalized = 0; - private static final Object sLock = new Object(); - - private static class FinalizableObject { - protected void finalize() { - // System.out.println("gc from finalize()"); - Runtime.getRuntime().gc(); - synchronized (sLock) { - sNumFinalized++; - } - } - } - - private static void makeRefs(FinalizableObject objects[], - WeakReference<FinalizableObject> refs[]) { - for (int i = 0; i < objects.length; i++) { - objects[i] = new FinalizableObject(); - refs[i] = new WeakReference<FinalizableObject>(objects[i]); - } - } - - @LargeTest - public void testWeakRefsAndFinalizers() throws Exception { - final int NUM_REFS = 16; - - FinalizableObject objects[] = new FinalizableObject[NUM_REFS]; - WeakReference<FinalizableObject> refs[] = new WeakReference[objects.length]; - int numCleared; - - /* Create a bunch of objects and a parallel array - * of WeakReferences. - */ - makeRefs(objects, refs); - Runtime.getRuntime().gc(); - checkRefs(objects, refs); - - /* Clear out every other strong reference. - */ - sNumFinalized = 0; - numCleared = 0; - for (int i = 0; i < objects.length; i += 2) { - objects[i] = null; - numCleared++; - } - // System.out.println("HeapTest/WeakRefsAndFinalizers: cleared evens"); - Runtime.getRuntime().gc(); - Runtime.getRuntime().runFinalization(); - checkRefs(objects, refs); - if (sNumFinalized != numCleared) { - throw new RuntimeException("Test failed: " + - "expected " + numCleared + " finalizations, saw " + - sNumFinalized); - } - - /* Clear out the rest of them. - */ - sNumFinalized = 0; - numCleared = 0; - for (int i = 0; i < objects.length; i++) { - if (objects[i] != null) { - objects[i] = null; - numCleared++; - } - } - // System.out.println("HeapTest/WeakRefsAndFinalizers: cleared all"); - Runtime.getRuntime().gc(); - Runtime.getRuntime().runFinalization(); - checkRefs(objects, refs); - if (sNumFinalized != numCleared) { - throw new RuntimeException("Test failed: " + - "expected " + numCleared + " finalizations, saw " + - sNumFinalized); - } - } - - // TODO: flaky test - //@MediumTest - public void testOomeLarge() throws Exception { - /* Just shy of the typical max heap size so that it will actually - * try to allocate it instead of short-circuiting. - */ - final int SIXTEEN_MB = (16 * 1024 * 1024 - 32); - - Boolean sawEx = false; - byte a[]; - - try { - a = new byte[SIXTEEN_MB]; - } catch (OutOfMemoryError oom) { - //Log.i(TAG, "HeapTest/OomeLarge caught " + oom); - sawEx = true; - } - - if (!sawEx) { - throw new RuntimeException("Test failed: " + - "OutOfMemoryError not thrown"); - } - } - - //See bug 1308253 for reasons. - @Suppress - public void disableTestOomeSmall() throws Exception { - final int SIXTEEN_MB = (16 * 1024 * 1024); - final int LINK_SIZE = 6 * 4; // estimated size of a LinkedList's node - - Boolean sawEx = false; - - LinkedList<Object> list = new LinkedList<Object>(); - - /* Allocate progressively smaller objects to fill up the entire heap. - */ - int objSize = 1 * 1024 * 1024; - while (objSize >= LINK_SIZE) { - try { - for (int i = 0; i < SIXTEEN_MB / objSize; i++) { - list.add((Object)new byte[objSize]); - } - } catch (OutOfMemoryError oom) { - sawEx = true; - } - - if (!sawEx) { - throw new RuntimeException("Test failed: " + - "OutOfMemoryError not thrown while filling heap"); - } - sawEx = false; - - objSize = (objSize * 4) / 5; - } - } -} diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java index f201bc7a7d3c..911347c13478 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java @@ -16,6 +16,16 @@ package com.android.server.connectivity; +import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.app.Notification; import android.app.NotificationManager; import android.content.Context; @@ -37,15 +47,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import static com.android.server.connectivity.NetworkNotificationManager.NotificationType.*; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - public class NetworkNotificationManagerTest extends TestCase { static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities(); @@ -140,4 +141,47 @@ public class NetworkNotificationManagerTest extends TestCase { verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any()); } + + @SmallTest + public void testDuplicatedNotificationsNoInternetThenSignIn() { + final int id = 101; + final String tag = NetworkNotificationManager.tagFor(id); + + // Show first NO_INTERNET + mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false); + verify(mNotificationManager, times(1)) + .notifyAsUser(eq(tag), eq(NO_INTERNET.eventId), any(), any()); + + // Captive portal detection triggers SIGN_IN a bit later, clearing the previous NO_INTERNET + mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false); + verify(mNotificationManager, times(1)) + .cancelAsUser(eq(tag), eq(NO_INTERNET.eventId), any()); + verify(mNotificationManager, times(1)) + .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any()); + + // Network disconnects + mManager.clearNotification(id); + verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any()); + } + + @SmallTest + public void testDuplicatedNotificationsSignInThenNoInternet() { + final int id = 101; + final String tag = NetworkNotificationManager.tagFor(id); + + // Show first SIGN_IN + mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false); + verify(mNotificationManager, times(1)) + .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any()); + reset(mNotificationManager); + + // NO_INTERNET arrives after, but is ignored. + mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false); + verify(mNotificationManager, never()).cancelAsUser(any(), anyInt(), any()); + verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any()); + + // Network disconnects + mManager.clearNotification(id); + verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any()); + } } |