Merge "Logging improvements when NetworkCapabilities change"
diff --git a/api/current.txt b/api/current.txt
index 9c2aba7..739e7f2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37821,6 +37821,14 @@
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.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 05b1a42..0aa5d58 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -40992,6 +40992,15 @@
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.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 1d9a2d8..93c9768 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -37920,6 +37920,14 @@
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.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 4ff6657..1bf9733 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 @@
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 @@
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 1c5aa60..50f27ed 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_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 @@
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 @@
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());
- break;
- case 's': // Report system image rules version
- pw.println("System rules version: "
- + rulesState.getSystemRulesVersion());
- break;
- case 'c': // Report current installation state
- pw.println("Current install state: "
- + distroStatusToString(rulesState.getDistroStatus()));
- 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 'p': {
+ // Report operation in progress
+ String value = "Unknown";
+ if (rulesState != null) {
+ value = Boolean.toString(rulesState.isOperationInProgress());
}
+ pw.println("Operation in progress: " + value);
break;
- case 'o': // Report staged operation type
- int stagedOperationType = rulesState.getStagedOperationType();
- pw.println("Staged operation: "
- + stagedOperationToString(stagedOperationType));
+ }
+ case 's': {
+ // Report system image rules version
+ String value = "Unknown";
+ if (rulesState != null) {
+ value = rulesState.getSystemRulesVersion();
+ }
+ pw.println("System rules version: " + value);
break;
- case 't':
+ }
+ 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
+ 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
+ String value = "Unknown";
+ if (rulesState != null) {
+ int stagedOperationType = rulesState.getStagedOperationType();
+ value = stagedOperationToString(stagedOperationType);
+ }
+ pw.println("Staged operation: " + value);
+ break;
+ }
+ 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 50e4502..14abaad 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 99ad00b..1a1d31e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -241,15 +241,6 @@
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 @@
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 911f83f..d69562c 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 @@
/**
* 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 @@
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 1b87393..b8e1c49 100644
--- a/telephony/java/android/telephony/mbms/FileInfo.java
+++ b/telephony/java/android/telephony/mbms/FileInfo.java
@@ -61,6 +61,10 @@
}
};
+ /**
+ * @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 6646dc8..8afe4d3 100644
--- a/telephony/java/android/telephony/mbms/FileServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/FileServiceInfo.java
@@ -32,6 +32,7 @@
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 8888119..f51563a 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* 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 @@
/**
* Indicates the errors that are applicable only to the file-download use-case
+ * TODO: unhide
+ * @hide
*/
public static class DownloadErrors {
/**
@@ -127,9 +128,7 @@
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 2e91be9..f67d6e4 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 @@
* @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 @@
* 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 f9ad44c..e1ccd43 100644
--- a/telephony/java/android/telephony/mbms/ServiceInfo.java
+++ b/telephony/java/android/telephony/mbms/ServiceInfo.java
@@ -30,43 +30,21 @@
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;
+ 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;
- /**
- * 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;
-
-
+ /** @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 @@
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 @@
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 c49f8a9..42c78c3 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.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 @@
/**
* 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 cab9c23..6a1ff9c 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 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 @@
*/
@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 @@
* 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 @@
* 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 @@
* {@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 77ce3bb..58df24d 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.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 @@
}
};
- 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 585d5b9..b2200c3 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 @@
* @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 @@
* @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 400d041..0000000
--- 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 f201bc7..911347c 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.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 @@
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());
+ }
}