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

Commit e5482dba authored by Biswarup Pal's avatar Biswarup Pal
Browse files

Cache settings per deviceId in ActivityThread

With go/device-aware-settings , we can have custom
settings values for every deviceId. CoreSettingsObserver
in ActivityManagerService fetches settings for all devices
and sends them to ActivityThread to cache in the app process.
This is required as an application can be running on multiple
devices at the same time (eg: one activity on phone and
another on Chromebook).

Test: atest CoreSettingsObserverTest
Test: atest ActivityThreadTest
Test: atest ActivityThreadClientTest
Bug: 371801645
Flag: android.companion.virtualdevice.flags.device_aware_settings_override
Change-Id: I872b39ef944073a4169c59256cefe35a95397941
parent 6d7cf8b2
Loading
Loading
Loading
Loading
+57 −39
Original line number Diff line number Diff line
@@ -562,17 +562,13 @@ public final class ActivityThread extends ClientTransactionHandler

    // The lock of mProviderMap protects the following variables.
    @UnsupportedAppUsage
    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
        = new ArrayMap<ProviderKey, ProviderClientRecord>();
    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap = new ArrayMap<>();
    @UnsupportedAppUsage
    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
        = new ArrayMap<IBinder, ProviderRefCount>();
    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap = new ArrayMap<>();
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
        = new ArrayMap<IBinder, ProviderClientRecord>();
    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders = new ArrayMap<>();
    @UnsupportedAppUsage
    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
            = new ArrayMap<ComponentName, ProviderClientRecord>();
    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<>();

    // Mitigation for b/74523247: Used to serialize calls to AM.getContentProvider().
    // Note we never removes items from this map but that's okay because there are only so many
@@ -580,8 +576,8 @@ public final class ActivityThread extends ClientTransactionHandler
    @GuardedBy("mGetProviderKeys")
    final ArrayMap<ProviderKey, ProviderKey> mGetProviderKeys = new ArrayMap<>();

    final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
        = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
    final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners =
            new ArrayMap<>();

    private SplashScreen.SplashScreenManagerGlobal mSplashScreenGlobal;

@@ -595,7 +591,7 @@ public final class ActivityThread extends ClientTransactionHandler
    static volatile Handler sMainThreadHandler;  // set once in main()
    private long mStartSeq; // Only accesssed from the main thread

    Bundle mCoreSettings = null;
    private Bundle mCoreSettings = null;

    /**
     * The lock word for the {@link #mCoreSettings}.
@@ -3014,12 +3010,12 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
    public LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
            int flags) {
        return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
    }

    public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
    public LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
            int flags, int userId) {
        final boolean differentUser = (UserHandle.myUserId() != userId);
        ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached(
@@ -3066,7 +3062,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage(trackingBug = 171933273)
    public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
    public LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
            int flags) {
        boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
        boolean securityViolation = includeCode && ai.uid != 0
@@ -3093,7 +3089,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
    public LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
            CompatibilityInfo compatInfo) {
        return getPackageInfo(ai, compatInfo, null, false, true, false);
    }
@@ -3105,7 +3101,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
    public LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (includeCode) {
@@ -3953,7 +3949,7 @@ public final class ActivityThread extends ClientTransactionHandler
        }
    }

    public final ActivityInfo resolveActivityInfo(Intent intent) {
    public ActivityInfo resolveActivityInfo(Intent intent) {
        ActivityInfo aInfo = intent.resolveActivityInfo(
                mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
        if (aInfo == null) {
@@ -5690,7 +5686,7 @@ public final class ActivityThread extends ClientTransactionHandler
        return true;
    }

    static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
    static void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
        if (r.mPreserveWindow && !force) {
            return;
        }
@@ -6198,12 +6194,13 @@ public final class ActivityThread extends ClientTransactionHandler

        // mCoreSettings is only updated from the main thread, while this function is only called
        // from main thread as well, so no need to lock here.
        View.sDebugViewAttributesApplicationPackage = mCoreSettings.getString(
        final Bundle defaultDeviceCoreSettings = getCoreSettingsForDefaultDeviceLocked();
        View.sDebugViewAttributesApplicationPackage = defaultDeviceCoreSettings.getString(
                Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, "");
        String currentPackage = (mBoundApplication != null && mBoundApplication.appInfo != null)
                ? mBoundApplication.appInfo.packageName : "<unknown-app>";
        View.sDebugViewAttributes =
                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0
                defaultDeviceCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0
                        || View.sDebugViewAttributesApplicationPackage.equals(currentPackage);
        return previousState != View.sDebugViewAttributes;
    }
@@ -7249,7 +7246,7 @@ public final class ActivityThread extends ClientTransactionHandler
                r.mActivityWindowInfo);
    }

    final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
    void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
        if (start) {
            switch (profileType) {
                case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD:
@@ -7350,7 +7347,7 @@ public final class ActivityThread extends ClientTransactionHandler
        }
    }

    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
    void handleDispatchPackageBroadcast(int cmd, String[] packages) {
        boolean hasPkgInfo = false;
        switch (cmd) {
            case ApplicationThreadConstants.PACKAGE_REMOVED:
@@ -7464,7 +7461,7 @@ public final class ActivityThread extends ClientTransactionHandler
        ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo);
    }

    final void handleLowMemory() {
    void handleLowMemory() {
        final ArrayList<ComponentCallbacks2> callbacks =
                collectComponentCallbacks(true /* includeUiContexts */);

@@ -7561,7 +7558,7 @@ public final class ActivityThread extends ClientTransactionHandler

        // mCoreSettings is only updated from the main thread, while this function is only called
        // from main thread as well, so no need to lock here.
        GraphicsEnvironment.getInstance().setup(context, mCoreSettings);
        GraphicsEnvironment.getInstance().setup(context, getCoreSettingsForDefaultDeviceLocked());
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }

@@ -7735,7 +7732,8 @@ public final class ActivityThread extends ClientTransactionHandler

        // mCoreSettings is only updated from the main thread, while this function is only called
        // from main thread as well, so no need to lock here.
        final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
        final String use24HourSetting = getCoreSettingsForDefaultDeviceLocked().getString(
                Settings.System.TIME_12_24);
        Boolean is24Hr = null;
        if (use24HourSetting != null) {
            is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
@@ -8211,7 +8209,7 @@ public final class ActivityThread extends ClientTransactionHandler
        mInstrumentingWithoutRestart = false;
    }

    /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
    /*package*/ void finishInstrumentation(int resultCode, Bundle results) {
        IActivityManager am = ActivityManager.getService();
        if (mProfiler.profileFile != null && mProfiler.handlingProfiling
                && mProfiler.profileFd == null) {
@@ -8260,7 +8258,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    public final IContentProvider acquireProvider(
    public IContentProvider acquireProvider(
            Context c, String auth, int userId, boolean stable) {
        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
        if (provider != null) {
@@ -8332,7 +8330,7 @@ public final class ActivityThread extends ClientTransactionHandler
        }
    }

    private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
    private void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
        if (stable) {
            prc.stableCount += 1;
            if (prc.stableCount == 1) {
@@ -8412,7 +8410,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    public final IContentProvider acquireExistingProvider(
    public IContentProvider acquireExistingProvider(
            Context c, String auth, int userId, boolean stable) {
        synchronized (mProviderMap) {
            final ProviderKey key = new ProviderKey(auth, userId);
@@ -8443,7 +8441,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    public final boolean releaseProvider(IContentProvider provider, boolean stable) {
    public boolean releaseProvider(IContentProvider provider, boolean stable) {
        if (provider == null) {
            return false;
        }
@@ -8540,7 +8538,7 @@ public final class ActivityThread extends ClientTransactionHandler
        }
    }

    final void completeRemoveProvider(ProviderRefCount prc) {
    void completeRemoveProvider(ProviderRefCount prc) {
        synchronized (mProviderMap) {
            if (!prc.removePending) {
                // There was a race!  Some other client managed to acquire
@@ -8584,13 +8582,13 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
    void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
        synchronized (mProviderMap) {
            handleUnstableProviderDiedLocked(provider, fromClient);
        }
    }

    final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
    void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
        ProviderRefCount prc = mProviderRefCountMap.get(provider);
        if (prc != null) {
            if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
@@ -8943,7 +8941,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    @UnsupportedAppUsage
    public final void installSystemProviders(List<ProviderInfo> providers) {
    public void installSystemProviders(List<ProviderInfo> providers) {
        if (providers != null) {
            installContentProviders(mInitialApplication, providers);
        }
@@ -8952,16 +8950,19 @@ public final class ActivityThread extends ClientTransactionHandler
    /**
     * Caller should NEVER mutate the Bundle returned from here
     */
    Bundle getCoreSettings() {
    Bundle getDefaultDeviceCoreSettings() {
        synchronized (mCoreSettingsLock) {
            return mCoreSettings;
            return getCoreSettingsForDefaultDeviceLocked();
        }
    }

    public int getIntCoreSetting(String key, int defaultValue) {
        synchronized (mCoreSettingsLock) {
            if (mCoreSettings != null) {
                return mCoreSettings.getInt(key, defaultValue);
                Bundle bundle = getCoreSettingsForDeviceLocked(mLastReportedDeviceId);
                if (bundle != null) {
                    return bundle.getInt(key, defaultValue);
                }
            }
            return defaultValue;
        }
@@ -8973,7 +8974,10 @@ public final class ActivityThread extends ClientTransactionHandler
    public String getStringCoreSetting(String key, String defaultValue) {
        synchronized (mCoreSettingsLock) {
            if (mCoreSettings != null) {
                return mCoreSettings.getString(key, defaultValue);
                Bundle bundle = getCoreSettingsForDeviceLocked(mLastReportedDeviceId);
                if (bundle != null) {
                    return bundle.getString(key, defaultValue);
                }
            }
            return defaultValue;
        }
@@ -8982,12 +8986,26 @@ public final class ActivityThread extends ClientTransactionHandler
    float getFloatCoreSetting(String key, float defaultValue) {
        synchronized (mCoreSettingsLock) {
            if (mCoreSettings != null) {
                return mCoreSettings.getFloat(key, defaultValue);
                Bundle bundle = getCoreSettingsForDeviceLocked(mLastReportedDeviceId);
                if (bundle != null) {
                    return bundle.getFloat(key, defaultValue);
                }
            }
            return defaultValue;
        }
    }

    private Bundle getCoreSettingsForDefaultDeviceLocked() {
        return getCoreSettingsForDeviceLocked(Context.DEVICE_ID_DEFAULT);
    }

    private Bundle getCoreSettingsForDeviceLocked(int deviceId) {
        if (android.companion.virtualdevice.flags.Flags.deviceAwareSettingsOverride()) {
            return mCoreSettings.getBundle(String.valueOf(deviceId));
        }
        return mCoreSettings;
    }

    private static class AndroidOs extends ForwardingOs {
        /**
         * Install selective syscall interception. For example, this is used to
+2 −1
Original line number Diff line number Diff line
@@ -955,7 +955,8 @@ public final class LoadedApk {
                            .getApplicationInfo(mPackageName, PackageManager.GET_META_DATA,
                                    UserHandle.myUserId());
                    final String debugLayerPath = GraphicsEnvironment.getInstance()
                            .getDebugLayerPathsFromSettings(mActivityThread.getCoreSettings(),
                            .getDebugLayerPathsFromSettings(
                                    mActivityThread.getDefaultDeviceCoreSettings(),
                                    ActivityThread.getPackageManager(), mPackageName, ai);
                    if (debugLayerPath != null) {
                        libraryPermittedPath += File.pathSeparator + debugLayerPath;
+55 −21
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.am;

import android.annotation.NonNull;
import android.app.ActivityThread;
import android.companion.virtual.VirtualDevice;
import android.companion.virtual.VirtualDeviceManager;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
@@ -44,7 +46,6 @@ import java.util.Objects;
 * in {@link Settings.Secure}.
 */
final class CoreSettingsObserver extends ContentObserver {
    private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();

    private static class DeviceConfigEntry<T> {
        String namespace;
@@ -65,15 +66,12 @@ final class CoreSettingsObserver extends ContentObserver {

    // mapping form property name to its type
    @VisibleForTesting
    static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<
            String, Class<?>>();
    static final Map<String, Class<?>> sSecureSettingToTypeMap = new HashMap<>();
    @VisibleForTesting
    static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<
            String, Class<?>>();
    static final Map<String, Class<?>> sSystemSettingToTypeMap = new HashMap<>();
    @VisibleForTesting
    static final Map<String, Class<?>> sGlobalSettingToTypeMap = new HashMap<
            String, Class<?>>();
    static final List<DeviceConfigEntry> sDeviceConfigEntries = new ArrayList<DeviceConfigEntry>();
    static final Map<String, Class<?>> sGlobalSettingToTypeMap = new HashMap<>();
    static final List<DeviceConfigEntry> sDeviceConfigEntries = new ArrayList<>();
    static {
        sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
        sSecureSettingToTypeMap.put(Settings.Secure.MULTI_PRESS_TIMEOUT, int.class);
@@ -170,6 +168,7 @@ final class CoreSettingsObserver extends ContentObserver {
    private final Bundle mCoreSettings = new Bundle();

    private final ActivityManagerService mActivityManagerService;
    private VirtualDeviceManager mVirtualDeviceManager;

    public CoreSettingsObserver(ActivityManagerService activityManagerService) {
        super(activityManagerService.mHandler);
@@ -197,7 +196,7 @@ final class CoreSettingsObserver extends ContentObserver {
    }

    public Bundle getCoreSettingsLocked() {
        return (Bundle) mCoreSettings.clone();
        return mCoreSettings.deepCopy();
    }

    @Override
@@ -208,10 +207,46 @@ final class CoreSettingsObserver extends ContentObserver {
    }

    private void sendCoreSettings() {
        populateSettings(mCoreSettings, sSecureSettingToTypeMap);
        populateSettings(mCoreSettings, sSystemSettingToTypeMap);
        populateSettings(mCoreSettings, sGlobalSettingToTypeMap);
        populateSettingsFromDeviceConfig();
        final Context context = mActivityManagerService.mContext;
        if (android.companion.virtualdevice.flags.Flags.deviceAwareSettingsOverride()) {
            final List<Integer> deviceIds = new ArrayList<>();
            if (mVirtualDeviceManager == null) {
                mVirtualDeviceManager = mActivityManagerService.mContext.getSystemService(
                        VirtualDeviceManager.class);
            }
            if (mVirtualDeviceManager != null) {
                final List<VirtualDevice> virtualDevices =
                        mVirtualDeviceManager.getVirtualDevices();
                for (VirtualDevice virtualDevice : virtualDevices) {
                    deviceIds.add(virtualDevice.getDeviceId());
                }
            }

            Bundle globalSettingsBundle = new Bundle();
            populateSettings(context, globalSettingsBundle, sGlobalSettingToTypeMap);
            Bundle deviceConfigBundle = new Bundle();
            populateSettingsFromDeviceConfig(deviceConfigBundle);

            deviceIds.add(Context.DEVICE_ID_DEFAULT);
            for (int deviceId : deviceIds) {
                final Bundle deviceBundle = new Bundle();
                final Context deviceContext = context.createDeviceContext(deviceId);
                populateSettings(deviceContext, deviceBundle, sSecureSettingToTypeMap);
                populateSettings(deviceContext, deviceBundle, sSystemSettingToTypeMap);

                // Copy global settings and device config values, as they don't vary across devices.
                deviceBundle.putAll(globalSettingsBundle);
                deviceBundle.putAll(deviceConfigBundle);

                mCoreSettings.putBundle(String.valueOf(deviceId), deviceBundle);
            }
        } else {
            populateSettings(context, mCoreSettings, sSecureSettingToTypeMap);
            populateSettings(context, mCoreSettings, sSystemSettingToTypeMap);
            populateSettings(context, mCoreSettings, sGlobalSettingToTypeMap);
            populateSettingsFromDeviceConfig(mCoreSettings);
        }

        mActivityManagerService.onCoreSettingsChange(mCoreSettings);
    }

@@ -246,8 +281,7 @@ final class CoreSettingsObserver extends ContentObserver {
    }

    @VisibleForTesting
    void populateSettings(Bundle snapshot, Map<String, Class<?>> map) {
        final Context context = mActivityManagerService.mContext;
    void populateSettings(Context context, Bundle snapshot, Map<String, Class<?>> map) {
        final ContentResolver cr = context.getContentResolver();
        for (Map.Entry<String, Class<?>> entry : map.entrySet()) {
            String setting = entry.getKey();
@@ -277,27 +311,27 @@ final class CoreSettingsObserver extends ContentObserver {
    }

    @SuppressWarnings("unchecked")
    private void populateSettingsFromDeviceConfig() {
    private static void populateSettingsFromDeviceConfig(Bundle bundle) {
        for (DeviceConfigEntry<?> entry : sDeviceConfigEntries) {
            if (entry.type == String.class) {
                String defaultValue = ((DeviceConfigEntry<String>) entry).defaultValue;
                mCoreSettings.putString(entry.coreSettingKey,
                bundle.putString(entry.coreSettingKey,
                        DeviceConfig.getString(entry.namespace, entry.flag, defaultValue));
            } else if (entry.type == int.class) {
                int defaultValue = ((DeviceConfigEntry<Integer>) entry).defaultValue;
                mCoreSettings.putInt(entry.coreSettingKey,
                bundle.putInt(entry.coreSettingKey,
                        DeviceConfig.getInt(entry.namespace, entry.flag, defaultValue));
            } else if (entry.type == float.class) {
                float defaultValue = ((DeviceConfigEntry<Float>) entry).defaultValue;
                mCoreSettings.putFloat(entry.coreSettingKey,
                bundle.putFloat(entry.coreSettingKey,
                        DeviceConfig.getFloat(entry.namespace, entry.flag, defaultValue));
            } else if (entry.type == long.class) {
                long defaultValue = ((DeviceConfigEntry<Long>) entry).defaultValue;
                mCoreSettings.putLong(entry.coreSettingKey,
                bundle.putLong(entry.coreSettingKey,
                        DeviceConfig.getLong(entry.namespace, entry.flag, defaultValue));
            } else if (entry.type == boolean.class) {
                boolean defaultValue = ((DeviceConfigEntry<Boolean>) entry).defaultValue;
                mCoreSettings.putInt(entry.coreSettingKey,
                bundle.putInt(entry.coreSettingKey,
                        DeviceConfig.getBoolean(entry.namespace, entry.flag, defaultValue) ? 1 : 0);
            }
        }
+9 −2
Original line number Diff line number Diff line
@@ -27,11 +27,15 @@ import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.companion.virtualdevice.flags.Flags;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import android.test.mock.MockContentResolver;

@@ -55,6 +59,7 @@ import org.mockito.MockitoAnnotations;
 *  atest FrameworksServicesTests:CoreSettingsObserverTest
 */
@SmallTest
@RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_SETTINGS_OVERRIDE)
public class CoreSettingsObserverTest {
    private static final String TEST_SETTING_SECURE_INT = "secureInt";
    private static final String TEST_SETTING_GLOBAL_FLOAT = "globalFloat";
@@ -65,6 +70,8 @@ public class CoreSettingsObserverTest {
    private static final String TEST_STRING = "testString";

    @Rule public ServiceThreadRule mServiceThreadRule = new ServiceThreadRule();
    @Rule public final CheckFlagsRule checkFlagsRule =
            DeviceFlagsValueProvider.createCheckFlagsRule();

    private ActivityManagerService mAms;
    @Mock private Context mContext;
@@ -162,12 +169,12 @@ public class CoreSettingsObserverTest {
                TEST_INT, settingsBundle.getInt(TEST_SETTING_SECURE_INT));
        assertEquals("Unexpected value of " + TEST_SETTING_SYSTEM_STRING,
                TEST_STRING, settingsBundle.getString(TEST_SETTING_SYSTEM_STRING));

    }

    private Bundle getPopulatedBundle() {
        mCoreSettingsObserver.onChange(false);
        return mCoreSettingsObserver.getCoreSettingsLocked();
        return mCoreSettingsObserver.getCoreSettingsLocked().getBundle(
                String.valueOf(Context.DEVICE_ID_DEFAULT));
    }

    private class TestInjector extends Injector {