diff --git a/sdk/src/java/lineageos/providers/LineageSettings.java b/sdk/src/java/lineageos/providers/LineageSettings.java index f1b6e5f9..bc40c159 100644 --- a/sdk/src/java/lineageos/providers/LineageSettings.java +++ b/sdk/src/java/lineageos/providers/LineageSettings.java @@ -34,6 +34,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import java.util.ArrayList; @@ -170,10 +171,33 @@ public final class LineageSettings { // endregion + private static final class ContentProviderHolder { + private final Object mLock = new Object(); + + private final Uri mUri; + @GuardedBy("mLock") + private IContentProvider mContentProvider; + + public ContentProviderHolder(Uri uri) { + mUri = uri; + } + + public IContentProvider getProvider(ContentResolver contentResolver) { + synchronized (mLock) { + if (mContentProvider == null) { + mContentProvider = contentResolver + .acquireProvider(mUri.getAuthority()); + } + return mContentProvider; + } + } + } + // Thread-safe. private static class NameValueCache { private final String mVersionSystemProperty; private final Uri mUri; + private final ContentProviderHolder mProviderHolder; private static final String[] SELECT_VALUE_PROJECTION = new String[] { Settings.NameValueTable.VALUE }; @@ -183,31 +207,18 @@ public final class LineageSettings { private final HashMap mValues = new HashMap(); private long mValuesVersion = 0; - // Initially null; set lazily and held forever. Synchronized on 'this'. - private IContentProvider mContentProvider = null; - // The method we'll call (or null, to not use) on the provider // for the fast path of retrieving settings. private final String mCallGetCommand; private final String mCallSetCommand; public NameValueCache(String versionSystemProperty, Uri uri, - String getCommand, String setCommand) { + String getCommand, String setCommand, ContentProviderHolder providerHolder) { mVersionSystemProperty = versionSystemProperty; mUri = uri; mCallGetCommand = getCommand; mCallSetCommand = setCommand; - } - - private IContentProvider lazyGetProvider(ContentResolver cr) { - IContentProvider cp; - synchronized (this) { - cp = mContentProvider; - if (cp == null) { - cp = mContentProvider = cr.acquireProvider(mUri.getAuthority()); - } - } - return cp; + mProviderHolder = providerHolder; } /** @@ -224,9 +235,9 @@ public final class LineageSettings { Bundle arg = new Bundle(); arg.putString(Settings.NameValueTable.VALUE, value); arg.putInt(CALL_METHOD_USER_KEY, userId); - IContentProvider cp = lazyGetProvider(cr); + IContentProvider cp = mProviderHolder.getProvider(cr); cp.call(cr.getAttributionSource(), - AUTHORITY, mCallSetCommand, name, arg); + mProviderHolder.mUri.getAuthority(), mCallSetCommand, name, arg); } catch (RemoteException e) { Log.w(TAG, "Can't set key " + name + " in " + mUri, e); return false; @@ -270,7 +281,7 @@ public final class LineageSettings { + " by user " + UserHandle.myUserId() + " so skipping cache"); } - IContentProvider cp = lazyGetProvider(cr); + IContentProvider cp = mProviderHolder.getProvider(cr); // Try the fast path first, not using query(). If this // fails (alternate Settings provider that doesn't support @@ -284,7 +295,7 @@ public final class LineageSettings { args.putInt(CALL_METHOD_USER_KEY, userId); } Bundle b = cp.call(cr.getAttributionSource(), - AUTHORITY, mCallGetCommand, name, args); + mProviderHolder.mUri.getAuthority(), mCallGetCommand, name, args); if (b != null) { String value = b.getPairValue(); // Don't update our cache for reads of other users' data @@ -485,12 +496,15 @@ public final class LineageSettings { public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/system"); public static final String SYS_PROP_LINEAGE_SETTING_VERSION = "sys.lineage_settings_system_version"; + private static final ContentProviderHolder sProviderHolder = + new ContentProviderHolder(CONTENT_URI); private static final NameValueCache sNameValueCache = new NameValueCache( SYS_PROP_LINEAGE_SETTING_VERSION, CONTENT_URI, CALL_METHOD_GET_SYSTEM, - CALL_METHOD_PUT_SYSTEM); + CALL_METHOD_PUT_SYSTEM, + sProviderHolder); /** @hide */ protected static final ArraySet MOVED_TO_SECURE; @@ -2463,11 +2477,15 @@ public final class LineageSettings { public static final String SYS_PROP_LINEAGE_SETTING_VERSION = "sys.lineage_settings_secure_version"; + private static final ContentProviderHolder sProviderHolder = + new ContentProviderHolder(CONTENT_URI); + private static final NameValueCache sNameValueCache = new NameValueCache( SYS_PROP_LINEAGE_SETTING_VERSION, CONTENT_URI, CALL_METHOD_GET_SECURE, - CALL_METHOD_PUT_SECURE); + CALL_METHOD_PUT_SECURE, + sProviderHolder); /** @hide */ protected static final ArraySet MOVED_TO_GLOBAL; @@ -3388,11 +3406,15 @@ public final class LineageSettings { public static final String SYS_PROP_LINEAGE_SETTING_VERSION = "sys.lineage_settings_global_version"; + private static final ContentProviderHolder sProviderHolder = + new ContentProviderHolder(CONTENT_URI); + private static final NameValueCache sNameValueCache = new NameValueCache( SYS_PROP_LINEAGE_SETTING_VERSION, CONTENT_URI, CALL_METHOD_GET_GLOBAL, - CALL_METHOD_PUT_GLOBAL); + CALL_METHOD_PUT_GLOBAL, + sProviderHolder); // region Methods