expose some sync control methods
- ActiveSyncInfo
- ContentResolver.addStatusChangeListener
- SYNC_OBSERVER_TYPE_SETTINGS
- SYNC_OBSERVER_TYPE_PENDING
- SYNC_OBSERVER_TYPE_ACTIVE
- make the ContentService resilient to nulls passed in to the
status change listener registration and unregistration calls
bug http://b/issue?id=2337197
diff --git a/api/current.xml b/api/current.xml
index 394a68a..815b9ff 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -30038,6 +30038,48 @@
>
</field>
</class>
+<class name="ActiveSyncInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getAccount"
+ return="android.accounts.Account"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getAuthority"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStartTime"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
<class name="ActivityNotFoundException"
extends="java.lang.RuntimeException"
abstract="false"
@@ -32073,6 +32115,17 @@
<parameter name="selectionArgs" type="java.lang.String[]">
</parameter>
</method>
+<method name="getActiveSync"
+ return="android.content.ActiveSyncInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getIsSyncable"
return="int"
abstract="false"
@@ -32679,6 +32732,39 @@
visibility="public"
>
</field>
+<field name="SYNC_OBSERVER_TYPE_ACTIVE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SYNC_OBSERVER_TYPE_PENDING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SYNC_OBSERVER_TYPE_SETTINGS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="ContentUris"
extends="java.lang.Object"
diff --git a/core/java/android/content/ActiveSyncInfo.java b/core/java/android/content/ActiveSyncInfo.java
index 209dffa..1255304 100644
--- a/core/java/android/content/ActiveSyncInfo.java
+++ b/core/java/android/content/ActiveSyncInfo.java
@@ -20,13 +20,50 @@
import android.os.Parcel;
import android.os.Parcelable.Creator;
-/** @hide */
+/**
+ * Information about the sync operation that is currently underway.
+ */
public class ActiveSyncInfo {
- public final int authorityId;
- public final Account account;
- public final String authority;
- public final long startTime;
-
+ /** @hide */
+ private final int authorityId;
+ /** @hide */
+ private final Account account;
+ /** @hide */
+ private final String authority;
+ /** @hide */
+ private final long startTime;
+
+ /**
+ * Get the {@link Account} that is currently being synced.
+ * @return the account
+ */
+ public Account getAccount() {
+ return new Account(account.name, account.type);
+ }
+
+ /** @hide */
+ public int getAuthorityId() {
+ return authorityId;
+ }
+
+ /**
+ * Get the authority of the provider that is currently being synced.
+ * @return the authority
+ */
+ public String getAuthority() {
+ return authority;
+ }
+
+ /**
+ * Get the start time of the current sync operation. This is represented in elapsed real time.
+ * See {@link android.os.SystemClock#elapsedRealtime()}.
+ * @return the start time in milliseconds since boot
+ */
+ public long getStartTime() {
+ return startTime;
+ }
+
+ /** @hide */
ActiveSyncInfo(int authorityId, Account account, String authority,
long startTime) {
this.authorityId = authorityId;
@@ -34,11 +71,13 @@
this.authority = authority;
this.startTime = startTime;
}
-
+
+ /** @hide */
public int describeContents() {
return 0;
}
+ /** @hide */
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(authorityId);
account.writeToParcel(parcel, 0);
@@ -46,13 +85,15 @@
parcel.writeLong(startTime);
}
+ /** @hide */
ActiveSyncInfo(Parcel parcel) {
authorityId = parcel.readInt();
account = new Account(parcel);
authority = parcel.readString();
startTime = parcel.readLong();
}
-
+
+ /** @hide */
public static final Creator<ActiveSyncInfo> CREATOR = new Creator<ActiveSyncInfo>() {
public ActiveSyncInfo createFromParcel(Parcel in) {
return new ActiveSyncInfo(in);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 29f388a..1b0ef34 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -156,11 +156,8 @@
/** @hide */
public static final int SYNC_ERROR_INTERNAL = 8;
- /** @hide */
public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0;
- /** @hide */
public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1;
- /** @hide */
public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2;
/** @hide */
public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3;
@@ -1183,7 +1180,6 @@
/**
* If a sync is active returns the information about it, otherwise returns false.
* @return the ActiveSyncInfo for the currently active sync or null if one is not active.
- * @hide
*/
public static ActiveSyncInfo getActiveSync() {
try {
@@ -1222,7 +1218,24 @@
}
}
+ /**
+ * Request notifications when the different aspects of the SyncManager change. The
+ * different items that can be requested are:
+ * <ul>
+ * <li> {@link #SYNC_OBSERVER_TYPE_PENDING}
+ * <li> {@link #SYNC_OBSERVER_TYPE_ACTIVE}
+ * <li> {@link #SYNC_OBSERVER_TYPE_SETTINGS}
+ * </ul>
+ * The caller can set one or more of the status types in the mask for any
+ * given listener registration.
+ * @param mask the status change types that will cause the callback to be invoked
+ * @param callback observer to be invoked when the status changes
+ * @return a handle that can be used to remove the listener at a later time
+ */
public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("you passed in a null callback");
+ }
try {
ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() {
public void onStatusChanged(int which) throws RemoteException {
@@ -1236,7 +1249,14 @@
}
}
+ /**
+ * Remove a previously registered status change listener.
+ * @param handle the handle that was returned by {@link #addStatusChangeListener}
+ */
public static void removeStatusChangeListener(Object handle) {
+ if (handle == null) {
+ throw new IllegalArgumentException("you passed in a null handle");
+ }
try {
getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle);
} catch (RemoteException e) {
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index e0dfab5..b5a78fa 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -437,7 +437,7 @@
long identityToken = clearCallingIdentity();
try {
SyncManager syncManager = getSyncManager();
- if (syncManager != null) {
+ if (syncManager != null && callback != null) {
syncManager.getSyncStorageEngine().addStatusChangeListener(mask, callback);
}
} finally {
@@ -449,7 +449,7 @@
long identityToken = clearCallingIdentity();
try {
SyncManager syncManager = getSyncManager();
- if (syncManager != null) {
+ if (syncManager != null && callback != null) {
syncManager.getSyncStorageEngine().removeStatusChangeListener(callback);
}
} finally {
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 317e5a9..393bbba 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -982,8 +982,8 @@
ActiveSyncInfo active = mSyncStorageEngine.getActiveSync();
if (active != null) {
SyncStorageEngine.AuthorityInfo authority
- = mSyncStorageEngine.getAuthority(active.authorityId);
- final long durationInSeconds = (now - active.startTime) / 1000;
+ = mSyncStorageEngine.getAuthority(active.getAuthorityId());
+ final long durationInSeconds = (now - active.getStartTime()) / 1000;
pw.print("Active sync: ");
pw.print(authority != null ? authority.account : "<no account>");
pw.print(" ");
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 5aad3af..240da72 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -664,7 +664,7 @@
}
if (mActiveSync != null) {
- AuthorityInfo ainfo = getAuthority(mActiveSync.authorityId);
+ AuthorityInfo ainfo = getAuthority(mActiveSync.getAuthorityId());
if (ainfo != null && ainfo.account.equals(account)
&& ainfo.authority.equals(authority)) {
return true;