From 186e3b31fc41c657a02efe75aec7b3cfe90402b0 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 15 Mar 2018 16:32:44 -0700 Subject: [PATCH] onUnsyncableAccount: Better docs, main thread Describe that AbstractThreadedSyncAdapter.onUnsyncableAccount should return immediately and call it on main thread. Test: atest android.content.cts.AccountAccessSameCertTest android.content.cts.DeferSyncTest android.content.cts.ContentResolverSyncTestCase com.android.cts.content.CtsSyncAccountAccessOtherCertTestCases Fixes: 73750859 Change-Id: Ie9e1aefafe3a4a1b3f0fe8a65803554f07a94c42 --- .../content/AbstractThreadedSyncAdapter.java | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java index 5a1216b79b829..b528e397906f5 100644 --- a/core/java/android/content/AbstractThreadedSyncAdapter.java +++ b/core/java/android/content/AbstractThreadedSyncAdapter.java @@ -16,9 +16,14 @@ package android.content; +import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; + import android.accounts.Account; +import android.annotation.MainThread; +import android.annotation.NonNull; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; @@ -167,9 +172,10 @@ public abstract class AbstractThreadedSyncAdapter { private class ISyncAdapterImpl extends ISyncAdapter.Stub { @Override - public void onUnsyncableAccount(ISyncAdapterUnsyncableAccountCallback cb) - throws RemoteException { - cb.onUnsyncableAccountDone(AbstractThreadedSyncAdapter.this.onUnsyncableAccount()); + public void onUnsyncableAccount(ISyncAdapterUnsyncableAccountCallback cb) { + Handler.getMain().sendMessage(obtainMessage( + AbstractThreadedSyncAdapter::handleOnUnsyncableAccount, + AbstractThreadedSyncAdapter.this, cb)); } @Override @@ -380,6 +386,27 @@ public abstract class AbstractThreadedSyncAdapter { return mISyncAdapterImpl.asBinder(); } + /** + * Handle a call of onUnsyncableAccount. + * + * @param cb The callback to report the return value to + */ + private void handleOnUnsyncableAccount(@NonNull ISyncAdapterUnsyncableAccountCallback cb) { + boolean doSync; + try { + doSync = onUnsyncableAccount(); + } catch (RuntimeException e) { + Log.e(TAG, "Exception while calling onUnsyncableAccount, assuming 'true'", e); + doSync = true; + } + + try { + cb.onUnsyncableAccountDone(doSync); + } catch (RemoteException e) { + Log.e(TAG, "Could not report result of onUnsyncableAccount", e); + } + } + /** * Allows to defer syncing until all accounts are properly set up. * @@ -393,9 +420,16 @@ public abstract class AbstractThreadedSyncAdapter { * *

This might be called on a different service connection as {@link #onPerformSync}. * + *

The system expects this method to immediately return. If the call stalls the system + * behaves as if this method returned {@code true}. If it is required to perform a longer task + * (such as interacting with the user), return {@code false} and proceed in a difference + * context, such as an {@link android.app.Activity}, or foreground service. The sync can then be + * rescheduled once the account becomes syncable. + * * @return If {@code false} syncing is deferred. Returns {@code true} by default, i.e. by * default syncing starts immediately. */ + @MainThread public boolean onUnsyncableAccount() { return true; }