From d2e5f7f07469c7a8b72abf1aa68bad9421323d5c Mon Sep 17 00:00:00 2001 From: Liefu Liu Date: Tue, 20 Apr 2021 18:16:45 +0000 Subject: Set a rate limit to CP2 notifyChange, if the change is not to sync to network. Bug: 185855005 Test: manually tested modified: src/com/android/providers/contacts/ContactsProvider2.java Change-Id: I1f317fd8753087404473aed69a03ba64093296a8 --- .../providers/contacts/ContactsProvider2.java | 34 +++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java index befafc05..e29b0fb2 100644 --- a/src/com/android/providers/contacts/ContactsProvider2.java +++ b/src/com/android/providers/contacts/ContactsProvider2.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import android.os.Looper; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.OnAccountsUpdateListener; @@ -62,6 +63,7 @@ import android.os.AsyncTask; import android.os.Binder; import android.os.Bundle; import android.os.CancellationSignal; +import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor.AutoCloseInputStream; import android.os.RemoteException; @@ -258,6 +260,9 @@ public class ContactsProvider2 extends AbstractContactsProvider /** Limit for the maximum number of social stream items to store under a raw contact. */ private static final int MAX_STREAM_ITEMS_PER_RAW_CONTACT = 5; + /** Rate limit (in milliseconds) for notify change. Do it as most once every 5 seconds. */ + private static final int NOTIFY_CHANGE_RATE_LIMIT = 5 * 1000; + /** Rate limit (in milliseconds) for photo cleanup. Do it at most once per day. */ private static final int PHOTO_CLEANUP_RATE_LIMIT = 24 * 60 * 60 * 1000; @@ -1458,6 +1463,8 @@ public class ContactsProvider2 extends AbstractContactsProvider private ContactsTaskScheduler mTaskScheduler; + private long mLastNotifyChange = 0; + private long mLastPhotoCleanup = 0; private FastScrollingIndexCache mFastScrollingIndexCache; @@ -2575,9 +2582,34 @@ public class ContactsProvider2 extends AbstractContactsProvider mSyncToNetwork = false; } - protected void notifyChange(boolean syncToNetwork) { + private final Handler mHandler = new Handler(Looper.getMainLooper()); + private final Runnable mChangeNotifier = () -> { + Log.v(TAG, "Scheduled notifyChange started."); + mLastNotifyChange = System.currentTimeMillis(); getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null, + false); + }; + + protected void notifyChange(boolean syncToNetwork) { + if (syncToNetwork) { + // Changes to sync to network won't be rate limited. + getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null, syncToNetwork); + } else { + // Rate limit the changes which are not to sync to network. + long uptimeMillis = System.currentTimeMillis(); + + mHandler.removeCallbacks(mChangeNotifier); + if (uptimeMillis > mLastNotifyChange + NOTIFY_CHANGE_RATE_LIMIT) { + // Notify change immediately, since it has been a while since last notify. + mLastNotifyChange = uptimeMillis; + getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null, + false); + } else { + // Schedule a deleyed notify, to ensure the very last notifyChange will be executed. + mHandler.postDelayed(mChangeNotifier, NOTIFY_CHANGE_RATE_LIMIT * 2); + } + } } protected void setProviderStatus(int status) { -- cgit v1.2.3