make syncadapter set whether the account is syncable
This commit is contained in:
@@ -8391,6 +8391,17 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="userVisible"
|
||||||
|
type="int"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value="16843408"
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
<field name="value"
|
<field name="value"
|
||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
@@ -8758,7 +8769,7 @@
|
|||||||
type="int"
|
type="int"
|
||||||
transient="false"
|
transient="false"
|
||||||
volatile="false"
|
volatile="false"
|
||||||
value="16843408"
|
value="16843409"
|
||||||
static="true"
|
static="true"
|
||||||
final="true"
|
final="true"
|
||||||
deprecated="not deprecated"
|
deprecated="not deprecated"
|
||||||
@@ -27586,6 +27597,17 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="SYNC_EXTRAS_INITIALIZE"
|
||||||
|
type="java.lang.String"
|
||||||
|
transient="false"
|
||||||
|
volatile="false"
|
||||||
|
value=""initialize""
|
||||||
|
static="true"
|
||||||
|
final="true"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
</field>
|
||||||
<field name="SYNC_EXTRAS_MANUAL"
|
<field name="SYNC_EXTRAS_MANUAL"
|
||||||
type="java.lang.String"
|
type="java.lang.String"
|
||||||
transient="false"
|
transient="false"
|
||||||
@@ -35766,6 +35788,8 @@
|
|||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="accountType" type="java.lang.String">
|
<parameter name="accountType" type="java.lang.String">
|
||||||
</parameter>
|
</parameter>
|
||||||
|
<parameter name="userVisible" type="boolean">
|
||||||
|
</parameter>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor name="SyncAdapterType"
|
<constructor name="SyncAdapterType"
|
||||||
type="android.content.SyncAdapterType"
|
type="android.content.SyncAdapterType"
|
||||||
@@ -35788,6 +35812,21 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="newKey"
|
||||||
|
return="android.content.SyncAdapterType"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="true"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="authority" type="java.lang.String">
|
||||||
|
</parameter>
|
||||||
|
<parameter name="accountType" type="java.lang.String">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
<method name="writeToParcel"
|
<method name="writeToParcel"
|
||||||
return="void"
|
return="void"
|
||||||
abstract="false"
|
abstract="false"
|
||||||
@@ -35833,11 +35872,10 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</field>
|
</field>
|
||||||
<field name="isUserFacing"
|
<field name="userVisible"
|
||||||
type="boolean"
|
type="boolean"
|
||||||
transient="false"
|
transient="false"
|
||||||
volatile="false"
|
volatile="false"
|
||||||
value="true"
|
|
||||||
static="false"
|
static="false"
|
||||||
final="true"
|
final="true"
|
||||||
deprecated="not deprecated"
|
deprecated="not deprecated"
|
||||||
|
|||||||
@@ -44,16 +44,23 @@ public abstract class AbstractThreadedSyncAdapter {
|
|||||||
|
|
||||||
/** Kernel event log tag. Also listed in data/etc/event-log-tags. */
|
/** Kernel event log tag. Also listed in data/etc/event-log-tags. */
|
||||||
public static final int LOG_SYNC_DETAILS = 2743;
|
public static final int LOG_SYNC_DETAILS = 2743;
|
||||||
|
private final boolean mAutoInitialize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link AbstractThreadedSyncAdapter}.
|
* Creates an {@link AbstractThreadedSyncAdapter}.
|
||||||
* @param context the {@link Context} that this is running within.
|
* @param context the {@link android.content.Context} that this is running within.
|
||||||
|
* @param autoInitialize if true then sync requests that have
|
||||||
|
* {@link ContentResolver#SYNC_EXTRAS_INITIALIZE} set will be internally handled by
|
||||||
|
* {@link AbstractThreadedSyncAdapter} by calling
|
||||||
|
* {@link ContentResolver#setIsSyncable(android.accounts.Account, String, int)} with 1 if it
|
||||||
|
* is currently set to <0.
|
||||||
*/
|
*/
|
||||||
public AbstractThreadedSyncAdapter(Context context) {
|
public AbstractThreadedSyncAdapter(Context context, boolean autoInitialize) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mISyncAdapterImpl = new ISyncAdapterImpl();
|
mISyncAdapterImpl = new ISyncAdapterImpl();
|
||||||
mNumSyncStarts = new AtomicInteger(0);
|
mNumSyncStarts = new AtomicInteger(0);
|
||||||
mSyncThread = null;
|
mSyncThread = null;
|
||||||
|
mAutoInitialize = autoInitialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ISyncAdapterImpl extends ISyncAdapter.Stub {
|
class ISyncAdapterImpl extends ISyncAdapter.Stub {
|
||||||
@@ -66,6 +73,15 @@ public abstract class AbstractThreadedSyncAdapter {
|
|||||||
// check it and when we use it
|
// check it and when we use it
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mSyncThread == null) {
|
if (mSyncThread == null) {
|
||||||
|
if (mAutoInitialize
|
||||||
|
&& extras != null
|
||||||
|
&& extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
|
||||||
|
if (ContentResolver.getIsSyncable(account, authority) < 0) {
|
||||||
|
ContentResolver.setIsSyncable(account, authority, 1);
|
||||||
|
}
|
||||||
|
syncContextClient.onFinished(new SyncResult());
|
||||||
|
return;
|
||||||
|
}
|
||||||
mSyncThread = new SyncThread(
|
mSyncThread = new SyncThread(
|
||||||
"SyncAdapterThread-" + mNumSyncStarts.incrementAndGet(),
|
"SyncAdapterThread-" + mNumSyncStarts.incrementAndGet(),
|
||||||
syncContextClient, authority, account, extras);
|
syncContextClient, authority, account, extras);
|
||||||
|
|||||||
@@ -52,18 +52,29 @@ public abstract class ContentResolver {
|
|||||||
* @deprecated instead use
|
* @deprecated instead use
|
||||||
* {@link #requestSync(android.accounts.Account, String, android.os.Bundle)}
|
* {@link #requestSync(android.accounts.Account, String, android.os.Bundle)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static final String SYNC_EXTRAS_ACCOUNT = "account";
|
public static final String SYNC_EXTRAS_ACCOUNT = "account";
|
||||||
public static final String SYNC_EXTRAS_EXPEDITED = "expedited";
|
public static final String SYNC_EXTRAS_EXPEDITED = "expedited";
|
||||||
/**
|
/**
|
||||||
* @deprecated instead use
|
* @deprecated instead use
|
||||||
* {@link #SYNC_EXTRAS_MANUAL}
|
* {@link #SYNC_EXTRAS_MANUAL}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static final String SYNC_EXTRAS_FORCE = "force";
|
public static final String SYNC_EXTRAS_FORCE = "force";
|
||||||
public static final String SYNC_EXTRAS_MANUAL = "force";
|
public static final String SYNC_EXTRAS_MANUAL = "force";
|
||||||
public static final String SYNC_EXTRAS_UPLOAD = "upload";
|
public static final String SYNC_EXTRAS_UPLOAD = "upload";
|
||||||
public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override";
|
public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override";
|
||||||
public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions";
|
public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set by the SyncManager to request that the SyncAdapter initialize itself for
|
||||||
|
* the given account/authority pair. One required initialization step is to
|
||||||
|
* ensure that {@link #setIsSyncable(android.accounts.Account, String, int)} has been
|
||||||
|
* called with a >= 0 value. When this flag is set the SyncAdapter does not need to
|
||||||
|
* do a full sync, though it is allowed to do so.
|
||||||
|
*/
|
||||||
|
public static final String SYNC_EXTRAS_INITIALIZE = "initialize";
|
||||||
|
|
||||||
public static final String SCHEME_CONTENT = "content";
|
public static final String SCHEME_CONTENT = "content";
|
||||||
public static final String SCHEME_ANDROID_RESOURCE = "android.resource";
|
public static final String SCHEME_ANDROID_RESOURCE = "android.resource";
|
||||||
public static final String SCHEME_FILE = "file";
|
public static final String SCHEME_FILE = "file";
|
||||||
@@ -1094,8 +1105,7 @@ public abstract class ContentResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the status that matches the authority. If there are multiples accounts for
|
* Returns the status that matches the authority.
|
||||||
* the authority, the one with the latest "lastSuccessTime" status is returned.
|
|
||||||
* @param account the account whose setting we are querying
|
* @param account the account whose setting we are querying
|
||||||
* @param authority the provider whose behavior is being queried
|
* @param authority the provider whose behavior is being queried
|
||||||
* @return the SyncStatusInfo for the authority, or null if none exists
|
* @return the SyncStatusInfo for the authority, or null if none exists
|
||||||
|
|||||||
@@ -197,7 +197,8 @@ public final class ContentService extends IContentService.Stub {
|
|||||||
try {
|
try {
|
||||||
SyncManager syncManager = getSyncManager();
|
SyncManager syncManager = getSyncManager();
|
||||||
if (syncManager != null) {
|
if (syncManager != null) {
|
||||||
syncManager.scheduleSync(account, authority, extras, 0 /* no delay */);
|
syncManager.scheduleSync(account, authority, extras, 0 /* no delay */,
|
||||||
|
false /* onlyThoseWithUnkownSyncableState */);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
restoreCallingIdentity(identityToken);
|
restoreCallingIdentity(identityToken);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public abstract class SyncAdapter {
|
|||||||
class Transport extends ISyncAdapter.Stub {
|
class Transport extends ISyncAdapter.Stub {
|
||||||
public void startSync(ISyncContext syncContext, String authority, Account account,
|
public void startSync(ISyncContext syncContext, String authority, Account account,
|
||||||
Bundle extras) throws RemoteException {
|
Bundle extras) throws RemoteException {
|
||||||
SyncAdapter.this.startSync(new SyncContext(syncContext), account, extras);
|
SyncAdapter.this.startSync(new SyncContext(syncContext), account, authority, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelSync(ISyncContext syncContext) throws RemoteException {
|
public void cancelSync(ISyncContext syncContext) throws RemoteException {
|
||||||
@@ -58,9 +58,11 @@ public abstract class SyncAdapter {
|
|||||||
* @param syncContext the ISyncContext used to indicate the progress of the sync. When
|
* @param syncContext the ISyncContext used to indicate the progress of the sync. When
|
||||||
* the sync is finished (successfully or not) ISyncContext.onFinished() must be called.
|
* the sync is finished (successfully or not) ISyncContext.onFinished() must be called.
|
||||||
* @param account the account that should be synced
|
* @param account the account that should be synced
|
||||||
|
* @param authority the authority if the sync request
|
||||||
* @param extras SyncAdapter-specific parameters
|
* @param extras SyncAdapter-specific parameters
|
||||||
*/
|
*/
|
||||||
public abstract void startSync(SyncContext syncContext, Account account, Bundle extras);
|
public abstract void startSync(SyncContext syncContext, Account account, String authority,
|
||||||
|
Bundle extras);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the most recently initiated sync. Due to race conditions, this may arrive
|
* Cancel the most recently initiated sync. Due to race conditions, this may arrive
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ import android.os.Parcel;
|
|||||||
public class SyncAdapterType implements Parcelable {
|
public class SyncAdapterType implements Parcelable {
|
||||||
public final String authority;
|
public final String authority;
|
||||||
public final String accountType;
|
public final String accountType;
|
||||||
public final boolean isUserFacing = true; // TODO: implement logic to set this
|
public final boolean userVisible;
|
||||||
|
|
||||||
public SyncAdapterType(String authority, String accountType) {
|
public SyncAdapterType(String authority, String accountType, boolean userVisible) {
|
||||||
if (TextUtils.isEmpty(authority)) {
|
if (TextUtils.isEmpty(authority)) {
|
||||||
throw new IllegalArgumentException("the authority must not be empty: " + authority);
|
throw new IllegalArgumentException("the authority must not be empty: " + authority);
|
||||||
}
|
}
|
||||||
@@ -38,12 +38,18 @@ public class SyncAdapterType implements Parcelable {
|
|||||||
}
|
}
|
||||||
this.authority = authority;
|
this.authority = authority;
|
||||||
this.accountType = accountType;
|
this.accountType = accountType;
|
||||||
|
this.userVisible = userVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SyncAdapterType newKey(String authority, String accountType) {
|
||||||
|
return new SyncAdapterType(authority, accountType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o == this) return true;
|
if (o == this) return true;
|
||||||
if (!(o instanceof SyncAdapterType)) return false;
|
if (!(o instanceof SyncAdapterType)) return false;
|
||||||
final SyncAdapterType other = (SyncAdapterType)o;
|
final SyncAdapterType other = (SyncAdapterType)o;
|
||||||
|
// don't include userVisible in the equality check
|
||||||
return authority.equals(other.authority) && accountType.equals(other.accountType);
|
return authority.equals(other.authority) && accountType.equals(other.accountType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,11 +57,13 @@ public class SyncAdapterType implements Parcelable {
|
|||||||
int result = 17;
|
int result = 17;
|
||||||
result = 31 * result + authority.hashCode();
|
result = 31 * result + authority.hashCode();
|
||||||
result = 31 * result + accountType.hashCode();
|
result = 31 * result + accountType.hashCode();
|
||||||
|
// don't include userVisible in the hash
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SyncAdapterType {name=" + authority + ", type=" + accountType + "}";
|
return "SyncAdapterType {name=" + authority + ", type=" + accountType
|
||||||
|
+ ", userVisible=" + userVisible + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
@@ -65,10 +73,11 @@ public class SyncAdapterType implements Parcelable {
|
|||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeString(authority);
|
dest.writeString(authority);
|
||||||
dest.writeString(accountType);
|
dest.writeString(accountType);
|
||||||
|
dest.writeInt(userVisible ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SyncAdapterType(Parcel source) {
|
public SyncAdapterType(Parcel source) {
|
||||||
this(source.readString(), source.readString());
|
this(source.readString(), source.readString(), source.readInt() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<SyncAdapterType> CREATOR = new Creator<SyncAdapterType>() {
|
public static final Creator<SyncAdapterType> CREATOR = new Creator<SyncAdapterType>() {
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ import android.util.AttributeSet;
|
|||||||
if (authority == null || accountType == null) {
|
if (authority == null || accountType == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new SyncAdapterType(authority, accountType);
|
final boolean userVisible =
|
||||||
|
sa.getBoolean(com.android.internal.R.styleable.SyncAdapter_userVisible, true);
|
||||||
|
return new SyncAdapterType(authority, accountType, userVisible);
|
||||||
} finally {
|
} finally {
|
||||||
sa.recycle();
|
sa.recycle();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,8 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void onAccountsUpdated(Account[] accounts) {
|
public void onAccountsUpdated(Account[] accounts) {
|
||||||
final boolean hadAccountsAlready = mAccounts != null;
|
// remember if this was the first time this was called after an update
|
||||||
|
final boolean justBootedUp = mAccounts == null;
|
||||||
mAccounts = accounts;
|
mAccounts = accounts;
|
||||||
|
|
||||||
// if a sync is in progress yet it is no longer in the accounts list,
|
// if a sync is in progress yet it is no longer in the accounts list,
|
||||||
@@ -200,10 +201,22 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
|
|
||||||
mSyncStorageEngine.doDatabaseCleanup(accounts);
|
mSyncStorageEngine.doDatabaseCleanup(accounts);
|
||||||
|
|
||||||
if (hadAccountsAlready && accounts.length > 0) {
|
if (accounts.length > 0) {
|
||||||
// request a sync so that if the password was changed we will
|
// If this is the first time this was called after a bootup then
|
||||||
// retry any sync that failed when it was wrong
|
// the accounts haven't really changed, instead they were just loaded
|
||||||
scheduleSync(null, null, null, 0 /* no delay */);
|
// from the AccountManager. Otherwise at least one of the accounts
|
||||||
|
// has a change.
|
||||||
|
//
|
||||||
|
// If there was a real account change then force a sync of all accounts.
|
||||||
|
// This is a bit of overkill, but at least it will end up retrying syncs
|
||||||
|
// that failed due to an authentication failure and thus will recover if the
|
||||||
|
// account change was a password update.
|
||||||
|
//
|
||||||
|
// If this was the bootup case then don't sync everything, instead only
|
||||||
|
// sync those that have an unknown syncable state, which will give them
|
||||||
|
// a chance to set their syncable state.
|
||||||
|
boolean onlyThoseWithUnkownSyncableState = !justBootedUp;
|
||||||
|
scheduleSync(null, null, null, 0 /* no delay */, onlyThoseWithUnkownSyncableState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +419,7 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
|
|
||||||
// perform a poll
|
// perform a poll
|
||||||
scheduleSync(null /* sync all syncable accounts */, null /* sync all syncable providers */,
|
scheduleSync(null /* sync all syncable accounts */, null /* sync all syncable providers */,
|
||||||
new Bundle(), 0 /* no delay */);
|
new Bundle(), 0 /* no delay */, false /* onlyThoseWithUnkownSyncableState */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeSyncPollTime(long when) {
|
private void writeSyncPollTime(long when) {
|
||||||
@@ -508,9 +521,10 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
* syncs of a specific provider. Can be null. Is ignored
|
* syncs of a specific provider. Can be null. Is ignored
|
||||||
* if the url is null.
|
* if the url is null.
|
||||||
* @param delay how many milliseconds in the future to wait before performing this
|
* @param delay how many milliseconds in the future to wait before performing this
|
||||||
|
* @param onlyThoseWithUnkownSyncableState
|
||||||
*/
|
*/
|
||||||
public void scheduleSync(Account requestedAccount, String requestedAuthority,
|
public void scheduleSync(Account requestedAccount, String requestedAuthority,
|
||||||
Bundle extras, long delay) {
|
Bundle extras, long delay, boolean onlyThoseWithUnkownSyncableState) {
|
||||||
boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
|
boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
|
||||||
if (isLoggable) {
|
if (isLoggable) {
|
||||||
Log.v(TAG, "scheduleSync:"
|
Log.v(TAG, "scheduleSync:"
|
||||||
@@ -596,14 +610,22 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
|
|
||||||
for (String authority : syncableAuthorities) {
|
for (String authority : syncableAuthorities) {
|
||||||
for (Account account : accounts) {
|
for (Account account : accounts) {
|
||||||
boolean isSyncable = mSyncStorageEngine.getIsSyncable(account, authority) > 0;
|
int isSyncable = mSyncStorageEngine.getIsSyncable(account, authority);
|
||||||
if (!isSyncable) {
|
if (isSyncable == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (mSyncAdapters.getServiceInfo(new SyncAdapterType(authority, account.type))
|
if (onlyThoseWithUnkownSyncableState && isSyncable >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mSyncAdapters.getServiceInfo(SyncAdapterType.newKey(authority, account.type))
|
||||||
!= null) {
|
!= null) {
|
||||||
|
// make this an initialization sync if the isSyncable state is unknown
|
||||||
|
Bundle extrasCopy = new Bundle(extras);
|
||||||
|
if (isSyncable < 0) {
|
||||||
|
extrasCopy.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
|
||||||
|
}
|
||||||
scheduleSyncOperation(
|
scheduleSyncOperation(
|
||||||
new SyncOperation(account, source, authority, extras, delay));
|
new SyncOperation(account, source, authority, extrasCopy, delay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -616,7 +638,8 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
public void scheduleLocalSync(Account account, String authority) {
|
public void scheduleLocalSync(Account account, String authority) {
|
||||||
final Bundle extras = new Bundle();
|
final Bundle extras = new Bundle();
|
||||||
extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
|
extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
|
||||||
scheduleSync(account, authority, extras, LOCAL_SYNC_DELAY);
|
scheduleSync(account, authority, extras, LOCAL_SYNC_DELAY,
|
||||||
|
false /* onlyThoseWithUnkownSyncableState */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPackageManager getPackageManager() {
|
private IPackageManager getPackageManager() {
|
||||||
@@ -1588,11 +1611,18 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
final boolean syncAutomatically =
|
final boolean syncAutomatically =
|
||||||
mSyncStorageEngine.getSyncAutomatically(op.account, op.authority)
|
mSyncStorageEngine.getSyncAutomatically(op.account, op.authority)
|
||||||
&& mSyncStorageEngine.getMasterSyncAutomatically();
|
&& mSyncStorageEngine.getMasterSyncAutomatically();
|
||||||
boolean isSyncable =
|
|
||||||
mSyncStorageEngine.getIsSyncable(op.account, op.authority) > 0;
|
|
||||||
boolean syncAllowed =
|
boolean syncAllowed =
|
||||||
manualSync || (backgroundDataUsageAllowed && syncAutomatically);
|
manualSync || (backgroundDataUsageAllowed && syncAutomatically);
|
||||||
if (!syncAllowed || !isSyncable) {
|
int isSyncable = mSyncStorageEngine.getIsSyncable(op.account, op.authority);
|
||||||
|
if (isSyncable == 0) {
|
||||||
|
// if not syncable, don't allow
|
||||||
|
syncAllowed = false;
|
||||||
|
} else if (isSyncable < 0) {
|
||||||
|
// if the syncable state is unknown, only allow initialization syncs
|
||||||
|
syncAllowed =
|
||||||
|
op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false);
|
||||||
|
}
|
||||||
|
if (!syncAllowed) {
|
||||||
if (isLoggable) {
|
if (isLoggable) {
|
||||||
Log.v(TAG, "runStateIdle: sync off, dropping " + op);
|
Log.v(TAG, "runStateIdle: sync off, dropping " + op);
|
||||||
}
|
}
|
||||||
@@ -1636,8 +1666,7 @@ class SyncManager implements OnAccountsUpdatedListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// connect to the sync adapter
|
// connect to the sync adapter
|
||||||
SyncAdapterType syncAdapterType = new SyncAdapterType(op.authority,
|
SyncAdapterType syncAdapterType = SyncAdapterType.newKey(op.authority, op.account.type);
|
||||||
op.account.type);
|
|
||||||
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
|
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
|
||||||
mSyncAdapters.getServiceInfo(syncAdapterType);
|
mSyncAdapters.getServiceInfo(syncAdapterType);
|
||||||
if (syncAdapterInfo == null) {
|
if (syncAdapterInfo == null) {
|
||||||
|
|||||||
@@ -162,8 +162,7 @@ public class SyncStorageEngine extends Handler {
|
|||||||
this.authority = authority;
|
this.authority = authority;
|
||||||
this.ident = ident;
|
this.ident = ident;
|
||||||
enabled = SYNC_ENABLED_DEFAULT;
|
enabled = SYNC_ENABLED_DEFAULT;
|
||||||
// TODO: change the default to -1 when the syncadapters are changed to set this
|
syncable = -1; // default to "unknown"
|
||||||
syncable = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ import android.util.EventLog;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TimingLogger;
|
import android.util.TimingLogger;
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
import android.accounts.AuthenticatorException;
|
||||||
|
import android.accounts.OperationCanceledException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
@@ -84,6 +88,9 @@ public abstract class TempProviderSyncAdapter extends SyncAdapter {
|
|||||||
*/
|
*/
|
||||||
public abstract boolean isReadOnly();
|
public abstract boolean isReadOnly();
|
||||||
|
|
||||||
|
public abstract boolean getIsSyncable(Account account)
|
||||||
|
throws IOException, AuthenticatorException, OperationCanceledException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get diffs from the server since the last completed sync and put them
|
* Get diffs from the server since the last completed sync and put them
|
||||||
* into a temporary provider.
|
* into a temporary provider.
|
||||||
@@ -173,6 +180,7 @@ public abstract class TempProviderSyncAdapter extends SyncAdapter {
|
|||||||
|
|
||||||
private class SyncThread extends Thread {
|
private class SyncThread extends Thread {
|
||||||
private final Account mAccount;
|
private final Account mAccount;
|
||||||
|
private final String mAuthority;
|
||||||
private final Bundle mExtras;
|
private final Bundle mExtras;
|
||||||
private final SyncContext mSyncContext;
|
private final SyncContext mSyncContext;
|
||||||
private volatile boolean mIsCanceled = false;
|
private volatile boolean mIsCanceled = false;
|
||||||
@@ -180,9 +188,10 @@ public abstract class TempProviderSyncAdapter extends SyncAdapter {
|
|||||||
private long mInitialRxBytes;
|
private long mInitialRxBytes;
|
||||||
private final SyncResult mResult;
|
private final SyncResult mResult;
|
||||||
|
|
||||||
SyncThread(SyncContext syncContext, Account account, Bundle extras) {
|
SyncThread(SyncContext syncContext, Account account, String authority, Bundle extras) {
|
||||||
super("SyncThread");
|
super("SyncThread");
|
||||||
mAccount = account;
|
mAccount = account;
|
||||||
|
mAuthority = authority;
|
||||||
mExtras = extras;
|
mExtras = extras;
|
||||||
mSyncContext = syncContext;
|
mSyncContext = syncContext;
|
||||||
mResult = new SyncResult();
|
mResult = new SyncResult();
|
||||||
@@ -206,7 +215,7 @@ public abstract class TempProviderSyncAdapter extends SyncAdapter {
|
|||||||
mInitialTxBytes = NetStat.getUidTxBytes(uid);
|
mInitialTxBytes = NetStat.getUidTxBytes(uid);
|
||||||
mInitialRxBytes = NetStat.getUidRxBytes(uid);
|
mInitialRxBytes = NetStat.getUidRxBytes(uid);
|
||||||
try {
|
try {
|
||||||
sync(mSyncContext, mAccount, mExtras);
|
sync(mSyncContext, mAccount, mAuthority, mExtras);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
Log.e(TAG, "Sync failed", e);
|
Log.e(TAG, "Sync failed", e);
|
||||||
mResult.databaseError = true;
|
mResult.databaseError = true;
|
||||||
@@ -220,13 +229,39 @@ public abstract class TempProviderSyncAdapter extends SyncAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sync(SyncContext syncContext, Account account, Bundle extras) {
|
private void sync(SyncContext syncContext, Account account, String authority,
|
||||||
|
Bundle extras) {
|
||||||
mIsCanceled = false;
|
mIsCanceled = false;
|
||||||
|
|
||||||
mProviderSyncStarted = false;
|
mProviderSyncStarted = false;
|
||||||
mAdapterSyncStarted = false;
|
mAdapterSyncStarted = false;
|
||||||
String message = null;
|
String message = null;
|
||||||
|
|
||||||
|
// always attempt to initialize if the isSyncable state isn't set yet
|
||||||
|
int isSyncable = ContentResolver.getIsSyncable(account, authority);
|
||||||
|
if (isSyncable < 0) {
|
||||||
|
try {
|
||||||
|
isSyncable = (getIsSyncable(account)) ? 1 : 0;
|
||||||
|
ContentResolver.setIsSyncable(account, authority, isSyncable);
|
||||||
|
} catch (IOException e) {
|
||||||
|
++mResult.stats.numIoExceptions;
|
||||||
|
} catch (AuthenticatorException e) {
|
||||||
|
++mResult.stats.numParseExceptions;
|
||||||
|
} catch (OperationCanceledException e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this is an initialization request then our work is done here
|
||||||
|
if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we aren't syncable then get out
|
||||||
|
if (isSyncable <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
|
boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -517,13 +552,14 @@ public abstract class TempProviderSyncAdapter extends SyncAdapter {
|
|||||||
EventLog.writeEvent(SyncAdapter.LOG_SYNC_DETAILS, TAG, bytesSent, bytesReceived, "");
|
EventLog.writeEvent(SyncAdapter.LOG_SYNC_DETAILS, TAG, bytesSent, bytesReceived, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startSync(SyncContext syncContext, Account account, Bundle extras) {
|
public void startSync(SyncContext syncContext, Account account, String authority,
|
||||||
|
Bundle extras) {
|
||||||
if (mSyncThread != null) {
|
if (mSyncThread != null) {
|
||||||
syncContext.onFinished(SyncResult.ALREADY_IN_PROGRESS);
|
syncContext.onFinished(SyncResult.ALREADY_IN_PROGRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSyncThread = new SyncThread(syncContext, account, extras);
|
mSyncThread = new SyncThread(syncContext, account, authority, extras);
|
||||||
mSyncThread.start();
|
mSyncThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -361,7 +361,7 @@
|
|||||||
<!-- Small inverse ProgressBar style. This is a small circular progress bar. -->
|
<!-- Small inverse ProgressBar style. This is a small circular progress bar. -->
|
||||||
<attr name="progressBarStyleSmallInverse" format="reference" />
|
<attr name="progressBarStyleSmallInverse" format="reference" />
|
||||||
<!-- Large inverse ProgressBar style. This is a large circular progress bar. -->
|
<!-- Large inverse ProgressBar style. This is a large circular progress bar. -->
|
||||||
<attr name="progressBarStyleLargeInverse" format="reference" />
|
<attr name="progressBarStyleLargeInverse" format="reference" />
|
||||||
<!-- Default SeekBar style. -->
|
<!-- Default SeekBar style. -->
|
||||||
<attr name="seekBarStyle" format="reference" />
|
<attr name="seekBarStyle" format="reference" />
|
||||||
<!-- Default RatingBar style. -->
|
<!-- Default RatingBar style. -->
|
||||||
@@ -2348,7 +2348,7 @@
|
|||||||
<attr name="pivotY" />
|
<attr name="pivotY" />
|
||||||
<attr name="drawable" />
|
<attr name="drawable" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="InsetDrawable">
|
<declare-styleable name="InsetDrawable">
|
||||||
<attr name="visible" />
|
<attr name="visible" />
|
||||||
<attr name="drawable" />
|
<attr name="drawable" />
|
||||||
@@ -2886,7 +2886,7 @@
|
|||||||
results for "bo", it would not be queried again for "bob".
|
results for "bo", it would not be queried again for "bob".
|
||||||
The default value is <code>false</code>. <i>Optional attribute.</i>. -->
|
The default value is <code>false</code>. <i>Optional attribute.</i>. -->
|
||||||
<attr name="queryAfterZeroResults" format="boolean" />
|
<attr name="queryAfterZeroResults" format="boolean" />
|
||||||
|
|
||||||
<!-- If provided, this string will be used to describe the searchable item in the
|
<!-- If provided, this string will be used to describe the searchable item in the
|
||||||
searchable items settings within system search settings. <i>Optional
|
searchable items settings within system search settings. <i>Optional
|
||||||
attribute.</i> -->
|
attribute.</i> -->
|
||||||
@@ -3359,6 +3359,7 @@
|
|||||||
<!-- the authority of a content provider. -->
|
<!-- the authority of a content provider. -->
|
||||||
<attr name="contentAuthority" format="string"/>
|
<attr name="contentAuthority" format="string"/>
|
||||||
<attr name="accountType"/>
|
<attr name="accountType"/>
|
||||||
|
<attr name="userVisible" format="boolean"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<!-- =============================== -->
|
<!-- =============================== -->
|
||||||
|
|||||||
@@ -1130,17 +1130,17 @@
|
|||||||
|
|
||||||
<public type="style" name="Widget.ProgressBar.Inverse" id="0x0103005b" />
|
<public type="style" name="Widget.ProgressBar.Inverse" id="0x0103005b" />
|
||||||
<public type="style" name="Widget.ProgressBar.Large.Inverse" id="0x0103005c" />
|
<public type="style" name="Widget.ProgressBar.Large.Inverse" id="0x0103005c" />
|
||||||
<public type="style" name="Widget.ProgressBar.Small.Inverse" id="0x0103005d" />
|
<public type="style" name="Widget.ProgressBar.Small.Inverse" id="0x0103005d" />
|
||||||
|
|
||||||
<public type="drawable" name="stat_sys_vp_phone_call" id="0x010800a7" />
|
<public type="drawable" name="stat_sys_vp_phone_call" id="0x010800a7" />
|
||||||
<public type="drawable" name="stat_sys_vp_phone_call_on_hold" id="0x010800a8" />
|
<public type="drawable" name="stat_sys_vp_phone_call_on_hold" id="0x010800a8" />
|
||||||
|
|
||||||
<public type="anim" name="anticipate_interpolator" id="0x010a0007" />
|
<public type="anim" name="anticipate_interpolator" id="0x010a0007" />
|
||||||
<public type="anim" name="overshoot_interpolator" id="0x010a0008" />
|
<public type="anim" name="overshoot_interpolator" id="0x010a0008" />
|
||||||
<public type="anim" name="anticipate_overshoot_interpolator" id="0x010a0009" />
|
<public type="anim" name="anticipate_overshoot_interpolator" id="0x010a0009" />
|
||||||
<public type="anim" name="bounce_interpolator" id="0x010a000a" />
|
<public type="anim" name="bounce_interpolator" id="0x010a000a" />
|
||||||
<public type="anim" name="linear_interpolator" id="0x010a000b" />
|
<public type="anim" name="linear_interpolator" id="0x010a000b" />
|
||||||
|
|
||||||
<!-- ===============================================================
|
<!-- ===============================================================
|
||||||
Resources added in Eclair.
|
Resources added in Eclair.
|
||||||
=============================================================== -->
|
=============================================================== -->
|
||||||
@@ -1148,6 +1148,7 @@
|
|||||||
|
|
||||||
<public type="attr" name="accountType" />
|
<public type="attr" name="accountType" />
|
||||||
<public type="attr" name="contentAuthority" />
|
<public type="attr" name="contentAuthority" />
|
||||||
|
<public type="attr" name="userVisible" />
|
||||||
<public type="attr" name="windowShowWallpaper" />
|
<public type="attr" name="windowShowWallpaper" />
|
||||||
|
|
||||||
<public type="style" name="Theme.Wallpaper" />
|
<public type="style" name="Theme.Wallpaper" />
|
||||||
|
|||||||
Reference in New Issue
Block a user