Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c90ed1c3 authored by Devarshi Bhatt's avatar Devarshi Bhatt Committed by Android (Google) Code Review
Browse files

Merge changes from topic "sp_new_api" into main

* changes:
  Add async registerCO API in SettingsProxy.
  Add provision for passing CoroutineDispatcher for Fake Settings impls.
parents 7a19cf62 34329106
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -23,16 +23,23 @@ import android.content.ContentResolver;
import android.net.Uri;
import android.provider.Settings;

import com.android.systemui.dagger.qualifiers.Background;

import kotlinx.coroutines.CoroutineDispatcher;

import javax.inject.Inject;

// use UserHandle.USER_SYSTEM everywhere
@SuppressLint("StaticSettingsProvider")
class GlobalSettingsImpl implements GlobalSettings {
    private final ContentResolver mContentResolver;
    private final CoroutineDispatcher mBgDispatcher;

    @Inject
    GlobalSettingsImpl(ContentResolver contentResolver) {
    GlobalSettingsImpl(ContentResolver contentResolver,
            @Background CoroutineDispatcher bgDispatcher) {
        mContentResolver = contentResolver;
        mBgDispatcher = bgDispatcher;
    }

    @Override
@@ -45,6 +52,11 @@ class GlobalSettingsImpl implements GlobalSettings {
        return Settings.Global.getUriFor(name);
    }

    @Override
    public CoroutineDispatcher getBackgroundDispatcher() {
        return mBgDispatcher;
    }

    @Override
    public String getString(String name) {
        return Settings.Global.getString(mContentResolver, name);
+12 −1
Original line number Diff line number Diff line
@@ -22,18 +22,24 @@ import android.provider.Settings;

import androidx.annotation.NonNull;

import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.settings.UserTracker;

import kotlinx.coroutines.CoroutineDispatcher;

import javax.inject.Inject;

class SecureSettingsImpl implements SecureSettings {
    private final ContentResolver mContentResolver;
    private final UserTracker mUserTracker;
    private final CoroutineDispatcher mBgDispatcher;

    @Inject
    SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
    SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
            @Background CoroutineDispatcher bgDispatcher) {
        mContentResolver = contentResolver;
        mUserTracker = userTracker;
        mBgDispatcher = bgDispatcher;
    }

    @Override
@@ -51,6 +57,11 @@ class SecureSettingsImpl implements SecureSettings {
        return Settings.Secure.getUriFor(name);
    }

    @Override
    public CoroutineDispatcher getBackgroundDispatcher() {
        return mBgDispatcher;
    }

    @Override
    public String getStringForUser(String name, int userHandle) {
        return Settings.Secure.getStringForUser(mContentResolver, name,
+136 −0
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@ import android.database.ContentObserver
import android.net.Uri
import android.provider.Settings.SettingNotFoundException
import com.android.app.tracing.TraceUtils.trace
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * Used to interact with mainly with Settings.Global, but can also be used for Settings.System and
@@ -39,6 +43,12 @@ interface SettingsProxy {
    /** Returns the [ContentResolver] this instance was constructed with. */
    fun getContentResolver(): ContentResolver

    /**
     * Returns the background [CoroutineDispatcher] that the async APIs will use for a specific
     * implementation.
     */
    val backgroundDispatcher: CoroutineDispatcher

    /**
     * Construct the content URI for a particular name/value pair, useful for monitoring changes
     * with a ContentObserver.
@@ -57,10 +67,54 @@ interface SettingsProxy {
        registerContentObserverSync(getUriFor(name), settingsObserver)
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
     * registration happens on a worker thread. Caller may wrap the API in an async block if they
     * wish to synchronize execution.
     */
    suspend fun registerContentObserver(name: String, settingsObserver: ContentObserver) {
        withContext(backgroundDispatcher) {
            registerContentObserverSync(getUriFor(name), settingsObserver)
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserver] for Java usage.
     */
    fun registerContentObserverAsync(name: String, settingsObserver: ContentObserver) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverSync(getUriFor(name), settingsObserver)
        }

    /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
    fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) =
        registerContentObserverSync(uri, false, settingsObserver)

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
     * registration happens on a worker thread. Caller may wrap the API in an async block if they
     * wish to synchronize execution.
     */
    suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
        withContext(backgroundDispatcher) { registerContentObserverSync(uri, settingsObserver) }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserver] for Java usage.
     */
    fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverSync(uri, settingsObserver)
        }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
@@ -72,6 +126,37 @@ interface SettingsProxy {
        settingsObserver: ContentObserver
    ) = registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
     * registration happens on a worker thread. Caller may wrap the API in an async block if they
     * wish to synchronize execution.
     */
    suspend fun registerContentObserver(
        name: String,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver
    ) {
        withContext(backgroundDispatcher) {
            registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserver] for Java usage.
     */
    fun registerContentObserverAsync(
        name: String,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver
    ) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
        }

    /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
    fun registerContentObserverSync(
        uri: Uri,
@@ -84,6 +169,37 @@ interface SettingsProxy {
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
     * registration happens on a worker thread. Caller may wrap the API in an async block if they
     * wish to synchronize execution.
     */
    suspend fun registerContentObserver(
        uri: Uri,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver
    ) {
        withContext(backgroundDispatcher) {
            registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserver] for Java usage.
     */
    fun registerContentObserverAsync(
        uri: Uri,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver
    ) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
        }

    /** See [ContentResolver.unregisterContentObserver]. */
    fun unregisterContentObserverSync(settingsObserver: ContentObserver) {
        trace({ "SP#unregisterObserver" }) {
@@ -91,6 +207,26 @@ interface SettingsProxy {
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
     *
     * API corresponding to [unregisterContentObserver] for Java usage to ensure that
     * [ContentObserver] un-registration happens on a worker thread. Caller may wrap the API in an
     * async block if they wish to synchronize execution.
     */
    suspend fun unregisterContentObserver(settingsObserver: ContentObserver) {
        withContext(backgroundDispatcher) { unregisterContentObserverSync(settingsObserver) }
    }

    /**
     * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
     *
     * API corresponding to [unregisterContentObserver] for Java usage to ensure that
     * [ContentObserver] registration happens on a worker thread.
     */
    fun unregisterContentObserverAsync(settingsObserver: ContentObserver) =
        CoroutineScope(backgroundDispatcher).launch { unregisterContentObserver(settingsObserver) }

    /**
     * Look up a name in the database.
     *
+12 −1
Original line number Diff line number Diff line
@@ -22,18 +22,24 @@ import android.provider.Settings;

import androidx.annotation.NonNull;

import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.settings.UserTracker;

import kotlinx.coroutines.CoroutineDispatcher;

import javax.inject.Inject;

class SystemSettingsImpl implements SystemSettings {
    private final ContentResolver mContentResolver;
    private final UserTracker mUserTracker;
    private final CoroutineDispatcher mBgCoroutineDispatcher;

    @Inject
    SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
    SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
            @Background CoroutineDispatcher bgDispatcher) {
        mContentResolver = contentResolver;
        mUserTracker = userTracker;
        mBgCoroutineDispatcher = bgDispatcher;
    }

    @Override
@@ -51,6 +57,11 @@ class SystemSettingsImpl implements SystemSettings {
        return Settings.System.getUriFor(name);
    }

    @Override
    public CoroutineDispatcher getBackgroundDispatcher() {
        return mBgCoroutineDispatcher;
    }

    @Override
    public String getStringForUser(String name, int userHandle) {
        return Settings.System.getStringForUser(mContentResolver, name,
+188 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.systemui.util.settings

import android.annotation.UserIdInt
import android.content.ContentResolver
import android.database.ContentObserver
import android.net.Uri
import android.os.UserHandle
@@ -26,6 +27,9 @@ import com.android.systemui.util.settings.SettingsProxy.Companion.parseFloat
import com.android.systemui.util.settings.SettingsProxy.Companion.parseFloatOrThrow
import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrThrow
import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrUseDefault
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * Used to interact with per-user Settings.Secure and Settings.System settings (but not
@@ -66,6 +70,17 @@ interface UserSettingsProxy : SettingsProxy {
        registerContentObserverForUserSync(uri, settingsObserver, userId)
    }

    override suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
        withContext(backgroundDispatcher) {
            registerContentObserverForUserSync(uri, settingsObserver, userId)
        }
    }

    override fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverForUserSync(uri, settingsObserver, userId)
        }

    /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
    override fun registerContentObserverSync(
        uri: Uri,
@@ -75,6 +90,30 @@ interface UserSettingsProxy : SettingsProxy {
        registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
    }

    override suspend fun registerContentObserver(
        uri: Uri,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver
    ) {
        withContext(backgroundDispatcher) {
            registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserverForUser] for Java usage.
     */
    override fun registerContentObserverAsync(
        uri: Uri,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver
    ) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
        }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver]
     *
@@ -88,6 +127,37 @@ interface UserSettingsProxy : SettingsProxy {
        registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserverForUser] to ensure that
     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
     * async block if they wish to synchronize execution.
     */
    suspend fun registerContentObserverForUser(
        name: String,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) {
        withContext(backgroundDispatcher) {
            registerContentObserverForUserSync(name, settingsObserver, userHandle)
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserverForUser] for Java usage.
     */
    fun registerContentObserverForUserAsync(
        name: String,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
        }

    /** Convenience wrapper around [ContentResolver.registerContentObserver] */
    fun registerContentObserverForUserSync(
        uri: Uri,
@@ -97,6 +167,37 @@ interface UserSettingsProxy : SettingsProxy {
        registerContentObserverForUserSync(uri, false, settingsObserver, userHandle)
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserverForUser] to ensure that
     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
     * async block if they wish to synchronize execution.
     */
    suspend fun registerContentObserverForUser(
        uri: Uri,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) {
        withContext(backgroundDispatcher) {
            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserverForUser] for Java usage.
     */
    fun registerContentObserverForUserAsync(
        uri: Uri,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
        }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver]
     *
@@ -116,6 +217,50 @@ interface UserSettingsProxy : SettingsProxy {
        )
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserverForUser] to ensure that
     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
     * async block if they wish to synchronize execution.
     */
    suspend fun registerContentObserverForUser(
        name: String,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) {
        withContext(backgroundDispatcher) {
            registerContentObserverForUserSync(
                name,
                notifyForDescendants,
                settingsObserver,
                userHandle
            )
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserverForUser] for Java usage.
     */
    fun registerContentObserverForUserAsync(
        name: String,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) {
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverForUserSync(
                getUriFor(name),
                notifyForDescendants,
                settingsObserver,
                userHandle
            )
        }
    }

    /** Convenience wrapper around [ContentResolver.registerContentObserver] */
    fun registerContentObserverForUserSync(
        uri: Uri,
@@ -135,6 +280,49 @@ interface UserSettingsProxy : SettingsProxy {
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * suspend API corresponding to [registerContentObserverForUser] to ensure that
     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
     * async block if they wish to synchronize execution.
     */
    suspend fun registerContentObserverForUser(
        uri: Uri,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) {
        withContext(backgroundDispatcher) {
            registerContentObserverForUserSync(
                uri,
                notifyForDescendants,
                settingsObserver,
                getRealUserHandle(userHandle)
            )
        }
    }

    /**
     * Convenience wrapper around [ContentResolver.registerContentObserver].'
     *
     * API corresponding to [registerContentObserverForUser] for Java usage.
     */
    fun registerContentObserverForUserAsync(
        uri: Uri,
        notifyForDescendants: Boolean,
        settingsObserver: ContentObserver,
        userHandle: Int
    ) =
        CoroutineScope(backgroundDispatcher).launch {
            registerContentObserverForUserSync(
                uri,
                notifyForDescendants,
                settingsObserver,
                userHandle
            )
        }

    /**
     * Look up a name in the database.
     *
Loading