- make the SyncManager add periodic syncs when it upgrades from a
version of the accounts.xml file that pre-dated periodic syncs, e.g. eclair or early froyo. http://b/2515823 - make the AccountManagerService dump() use a getAccounts call that doesn't check the GET_ACCOUNTS permission to make it useful in "adb bugreport" - add some logging to SyncManager to help track down a problem Change-Id: Icb646909074e2d327d71f6bb39cf06b6fac29e77
This commit is contained in:
@ -1699,7 +1699,7 @@ public class AccountManagerService
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Account[] accounts = getAccounts(null /* type */);
|
||||
Account[] accounts = getAccountsByType(null /* type */);
|
||||
fout.println("Accounts: " + accounts.length);
|
||||
for (Account account : accounts) {
|
||||
fout.println(" " + account);
|
||||
|
@ -416,6 +416,9 @@ public class SyncManager implements OnAccountsUpdateListener {
|
||||
}
|
||||
|
||||
private void initializeSyncAdapter(Account account, String authority) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "initializeSyncAdapter: " + account + ", authority " + authority);
|
||||
}
|
||||
SyncAdapterType syncAdapterType = SyncAdapterType.newKey(authority, account.type);
|
||||
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
|
||||
mSyncAdapters.getServiceInfo(syncAdapterType);
|
||||
@ -427,9 +430,11 @@ public class SyncManager implements OnAccountsUpdateListener {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("android.content.SyncAdapter");
|
||||
intent.setComponent(syncAdapterInfo.componentName);
|
||||
mContext.bindService(intent, new InitializerServiceConnection(account, authority, mContext,
|
||||
if (!mContext.bindService(intent, new InitializerServiceConnection(account, authority, mContext,
|
||||
mMainHandler),
|
||||
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
|
||||
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND)) {
|
||||
Log.w(TAG, "initializeSyncAdapter: failed to bind to " + intent);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InitializerServiceConnection implements ServiceConnection {
|
||||
@ -452,6 +457,9 @@ public class SyncManager implements OnAccountsUpdateListener {
|
||||
try {
|
||||
if (!mInitialized) {
|
||||
mInitialized = true;
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "calling initialize: " + mAccount + ", authority " + mAuthority);
|
||||
}
|
||||
ISyncAdapter.Stub.asInterface(service).initialize(mAccount, mAuthority);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@ -1307,7 +1315,6 @@ public class SyncManager implements OnAccountsUpdateListener {
|
||||
// it if sync is still failing
|
||||
private boolean mErrorNotificationInstalled = false;
|
||||
private volatile CountDownLatch mReadyToRunLatch = new CountDownLatch(1);
|
||||
|
||||
public void onBootCompleted() {
|
||||
mBootCompleted = true;
|
||||
if (mReadyToRunLatch != null) {
|
||||
|
@ -121,6 +121,9 @@ public class SyncStorageEngine extends Handler {
|
||||
|
||||
private static final boolean SYNC_ENABLED_DEFAULT = false;
|
||||
|
||||
// the version of the accounts xml file format
|
||||
private static final int ACCOUNTS_VERSION = 1;
|
||||
|
||||
public static class PendingOperation {
|
||||
final Account account;
|
||||
final int syncSource;
|
||||
@ -1322,6 +1325,7 @@ public class SyncStorageEngine extends Handler {
|
||||
* Read all account information back in to the initial engine state.
|
||||
*/
|
||||
private void readAccountInfoLocked() {
|
||||
boolean writeNeeded = false;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = mAccountInfoFile.openRead();
|
||||
@ -1336,6 +1340,16 @@ public class SyncStorageEngine extends Handler {
|
||||
if ("accounts".equals(tagName)) {
|
||||
String listen = parser.getAttributeValue(
|
||||
null, "listen-for-tickles");
|
||||
String versionString = parser.getAttributeValue(null, "version");
|
||||
int version;
|
||||
try {
|
||||
version = (versionString == null) ? 0 : Integer.parseInt(versionString);
|
||||
} catch (NumberFormatException e) {
|
||||
version = 0;
|
||||
}
|
||||
if (version < ACCOUNTS_VERSION) {
|
||||
writeNeeded = true;
|
||||
}
|
||||
mMasterSyncAutomatically = listen == null
|
||||
|| Boolean.parseBoolean(listen);
|
||||
eventType = parser.next();
|
||||
@ -1346,7 +1360,7 @@ public class SyncStorageEngine extends Handler {
|
||||
tagName = parser.getName();
|
||||
if (parser.getDepth() == 2) {
|
||||
if ("authority".equals(tagName)) {
|
||||
authority = parseAuthority(parser);
|
||||
authority = parseAuthority(parser, version);
|
||||
periodicSync = null;
|
||||
}
|
||||
} else if (parser.getDepth() == 3) {
|
||||
@ -1364,9 +1378,11 @@ public class SyncStorageEngine extends Handler {
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
Log.w(TAG, "Error reading accounts", e);
|
||||
return;
|
||||
} catch (java.io.IOException e) {
|
||||
if (fis == null) Log.i(TAG, "No initial accounts");
|
||||
else Log.w(TAG, "Error reading accounts", e);
|
||||
return;
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
@ -1375,9 +1391,13 @@ public class SyncStorageEngine extends Handler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (writeNeeded) {
|
||||
writeAccountInfoLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private AuthorityInfo parseAuthority(XmlPullParser parser) {
|
||||
private AuthorityInfo parseAuthority(XmlPullParser parser, int version) {
|
||||
AuthorityInfo authority = null;
|
||||
int id = -1;
|
||||
try {
|
||||
@ -1406,8 +1426,14 @@ public class SyncStorageEngine extends Handler {
|
||||
if (DEBUG_FILE) Log.v(TAG, "Creating entry");
|
||||
authority = getOrCreateAuthorityLocked(
|
||||
new Account(accountName, accountType), authorityName, id, false);
|
||||
// clear this since we will read these later on
|
||||
authority.periodicSyncs.clear();
|
||||
// If the version is 0 then we are upgrading from a file format that did not
|
||||
// know about periodic syncs. In that case don't clear the list since we
|
||||
// want the default, which is a daily periodioc sync.
|
||||
// Otherwise clear out this default list since we will populate it later with
|
||||
// the periodic sync descriptions that are read from the configuration file.
|
||||
if (version > 0) {
|
||||
authority.periodicSyncs.clear();
|
||||
}
|
||||
}
|
||||
if (authority != null) {
|
||||
authority.enabled = enabled == null || Boolean.parseBoolean(enabled);
|
||||
@ -1443,6 +1469,7 @@ public class SyncStorageEngine extends Handler {
|
||||
}
|
||||
final Pair<Bundle, Long> periodicSync = Pair.create(extras, period);
|
||||
authority.periodicSyncs.add(periodicSync);
|
||||
|
||||
return periodicSync;
|
||||
}
|
||||
|
||||
@ -1491,6 +1518,7 @@ public class SyncStorageEngine extends Handler {
|
||||
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
||||
|
||||
out.startTag(null, "accounts");
|
||||
out.attribute(null, "version", Integer.toString(ACCOUNTS_VERSION));
|
||||
if (!mMasterSyncAutomatically) {
|
||||
out.attribute(null, "listen-for-tickles", "false");
|
||||
}
|
||||
@ -1505,7 +1533,7 @@ public class SyncStorageEngine extends Handler {
|
||||
out.attribute(null, "authority", authority.authority);
|
||||
if (!authority.enabled) {
|
||||
out.attribute(null, "enabled", "false");
|
||||
}
|
||||
}
|
||||
if (authority.syncable < 0) {
|
||||
out.attribute(null, "syncable", "unknown");
|
||||
} else if (authority.syncable == 0) {
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package android.content;
|
||||
|
||||
import com.android.internal.os.AtomicFile;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
@ -26,6 +28,7 @@ import android.os.Bundle;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class SyncStorageEngineTest extends AndroidTestCase {
|
||||
|
||||
@ -193,6 +196,109 @@ public class SyncStorageEngineTest extends AndroidTestCase {
|
||||
assertEquals(1, engine.getIsSyncable(account1, authority2));
|
||||
assertEquals(0, engine.getIsSyncable(account2, authority2));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testAuthorityParsing() throws Exception {
|
||||
final Account account = new Account("account1", "type1");
|
||||
final String authority1 = "auth1";
|
||||
final String authority2 = "auth2";
|
||||
final String authority3 = "auth3";
|
||||
final Bundle extras = new Bundle();
|
||||
PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24));
|
||||
PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24));
|
||||
PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24));
|
||||
PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, 1000);
|
||||
PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, 1000);
|
||||
PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, 1000);
|
||||
|
||||
MockContentResolver mockResolver = new MockContentResolver();
|
||||
|
||||
final TestContext testContext = new TestContext(mockResolver, getContext());
|
||||
SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
|
||||
|
||||
byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
|
||||
+ "<accounts>\n"
|
||||
+ "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
|
||||
+ "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n"
|
||||
+ "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n"
|
||||
+ "</accounts>\n").getBytes();
|
||||
|
||||
File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync");
|
||||
syncDir.mkdirs();
|
||||
AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
|
||||
FileOutputStream fos = accountInfoFile.startWrite();
|
||||
fos.write(accountsFileData);
|
||||
accountInfoFile.finishWrite(fos);
|
||||
|
||||
engine.clearAndReadState();
|
||||
|
||||
List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, authority1);
|
||||
assertEquals(1, syncs.size());
|
||||
assertEquals(sync1, syncs.get(0));
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority2);
|
||||
assertEquals(1, syncs.size());
|
||||
assertEquals(sync2, syncs.get(0));
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority3);
|
||||
assertEquals(1, syncs.size());
|
||||
assertEquals(sync3, syncs.get(0));
|
||||
|
||||
accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
|
||||
+ "<accounts version=\"1\">\n"
|
||||
+ "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
|
||||
+ "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n"
|
||||
+ "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n"
|
||||
+ "</accounts>\n").getBytes();
|
||||
|
||||
accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
|
||||
fos = accountInfoFile.startWrite();
|
||||
fos.write(accountsFileData);
|
||||
accountInfoFile.finishWrite(fos);
|
||||
|
||||
engine.clearAndReadState();
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority1);
|
||||
assertEquals(0, syncs.size());
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority2);
|
||||
assertEquals(0, syncs.size());
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority3);
|
||||
assertEquals(0, syncs.size());
|
||||
|
||||
accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
|
||||
+ "<accounts version=\"1\">\n"
|
||||
+ "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n"
|
||||
+ "<periodicSync period=\"1000\" />\n"
|
||||
+ "</authority>"
|
||||
+ "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n"
|
||||
+ "<periodicSync period=\"1000\" />\n"
|
||||
+ "</authority>"
|
||||
+ "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n"
|
||||
+ "<periodicSync period=\"1000\" />\n"
|
||||
+ "</authority>"
|
||||
+ "</accounts>\n").getBytes();
|
||||
|
||||
accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
|
||||
fos = accountInfoFile.startWrite();
|
||||
fos.write(accountsFileData);
|
||||
accountInfoFile.finishWrite(fos);
|
||||
|
||||
engine.clearAndReadState();
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority1);
|
||||
assertEquals(1, syncs.size());
|
||||
assertEquals(sync1s, syncs.get(0));
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority2);
|
||||
assertEquals(1, syncs.size());
|
||||
assertEquals(sync2s, syncs.get(0));
|
||||
|
||||
syncs = engine.getPeriodicSyncs(account, authority3);
|
||||
assertEquals(1, syncs.size());
|
||||
assertEquals(sync3s, syncs.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
class TestContext extends ContextWrapper {
|
||||
|
Reference in New Issue
Block a user