diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 55ec159..9d5f96f 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -389,9 +389,7 @@
      */
     public static UserHandle getManagedProfile(UserManager userManager) {
         List<UserHandle> userProfiles = userManager.getUserProfiles();
-        final int count = userProfiles.size();
-        for (int i = 0; i < count; i++) {
-            final UserHandle profile = userProfiles.get(i);
+        for (UserHandle profile : userProfiles) {
             if (profile.getIdentifier() == userManager.getUserHandle()) {
                 continue;
             }
diff --git a/src/com/android/settings/location/InjectedSetting.java b/src/com/android/settings/location/InjectedSetting.java
deleted file mode 100644
index 4877cb4..0000000
--- a/src/com/android/settings/location/InjectedSetting.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.location;
-
-import android.content.Intent;
-import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.Immutable;
-
-import java.util.Objects;
-
-/**
- * Specifies a setting that is being injected into Settings &gt; Location &gt; Location services.
- *
- * @see android.location.SettingInjectorService
- */
-@Immutable
-class InjectedSetting {
-
-    /**
-     * Package for the subclass of {@link android.location.SettingInjectorService} and for the
-     * settings activity.
-     */
-    public final String packageName;
-
-    /**
-     * Class name for the subclass of {@link android.location.SettingInjectorService} that
-     * specifies dynamic values for the location setting.
-     */
-    public final String className;
-
-    /**
-     * The {@link androidx.preference.Preference#getTitle()} value.
-     */
-    public final String title;
-
-    /**
-     * The {@link androidx.preference.Preference#getIcon()} value.
-     */
-    public final int iconId;
-
-    /**
-     * The user/profile associated with this setting (e.g. managed profile)
-     */
-    public final UserHandle mUserHandle;
-
-    /**
-     * The activity to launch to allow the user to modify the settings value. Assumed to be in the
-     * {@link #packageName} package.
-     */
-    public final String settingsActivity;
-
-    /**
-     * The user restriction associated with this setting.
-     */
-    public final String userRestriction;
-
-    private InjectedSetting(Builder builder) {
-        this.packageName = builder.mPackageName;
-        this.className = builder.mClassName;
-        this.title = builder.mTitle;
-        this.iconId = builder.mIconId;
-        this.mUserHandle = builder.mUserHandle;
-        this.settingsActivity = builder.mSettingsActivity;
-        this.userRestriction = builder.mUserRestriction;
-    }
-
-    @Override
-    public String toString() {
-        return "InjectedSetting{" +
-                "mPackageName='" + packageName + '\'' +
-                ", mClassName='" + className + '\'' +
-                ", label=" + title +
-                ", iconId=" + iconId +
-                ", userId=" + mUserHandle.getIdentifier() +
-                ", settingsActivity='" + settingsActivity + '\'' +
-                ", userRestriction='" + userRestriction +
-                '}';
-    }
-
-    /**
-     * Returns the intent to start the {@link #className} service.
-     */
-    public Intent getServiceIntent() {
-        Intent intent = new Intent();
-        intent.setClassName(packageName, className);
-        return intent;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof InjectedSetting)) return false;
-
-        InjectedSetting that = (InjectedSetting) o;
-
-        return Objects.equals(packageName, that.packageName)
-                && Objects.equals(className, that.className)
-                && Objects.equals(title, that.title)
-                && Objects.equals(iconId, that.iconId)
-                && Objects.equals(mUserHandle, that.mUserHandle)
-                && Objects.equals(settingsActivity, that.settingsActivity)
-                && Objects.equals(userRestriction, that.userRestriction);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = packageName.hashCode();
-        result = 31 * result + className.hashCode();
-        result = 31 * result + title.hashCode();
-        result = 31 * result + iconId;
-        result = 31 * result + (mUserHandle == null ? 0 : mUserHandle.hashCode());
-        result = 31 * result + settingsActivity.hashCode();
-        result = 31 * result + (userRestriction == null ? 0 : userRestriction.hashCode());
-        return result;
-    }
-
-    public static class Builder {
-        private String mPackageName;
-        private String mClassName;
-        private String mTitle;
-        private int mIconId;
-        private UserHandle mUserHandle;
-        private String mSettingsActivity;
-        private String mUserRestriction;
-
-        public Builder setPackageName(String packageName) {
-            mPackageName = packageName;
-            return this;
-        }
-
-        public Builder setClassName(String className) {
-            mClassName = className;
-            return this;
-        }
-
-        public Builder setTitle(String title) {
-            mTitle = title;
-            return this;
-        }
-
-        public Builder setIconId(int iconId) {
-            mIconId = iconId;
-            return this;
-        }
-
-        public Builder setUserHandle(UserHandle userHandle) {
-            mUserHandle = userHandle;
-            return this;
-        }
-
-        public Builder setSettingsActivity(String settingsActivity) {
-            mSettingsActivity = settingsActivity;
-            return this;
-        }
-
-        public Builder setUserRestriction(String userRestriction) {
-            mUserRestriction = userRestriction;
-            return this;
-        }
-
-        public InjectedSetting build() {
-            if (mPackageName == null || mClassName == null || TextUtils.isEmpty(mTitle)
-                    || TextUtils.isEmpty(mSettingsActivity)) {
-                if (Log.isLoggable(SettingsInjector.TAG, Log.WARN)) {
-                    Log.w(SettingsInjector.TAG, "Illegal setting specification: package="
-                            + mPackageName + ", class=" + mClassName
-                            + ", title=" + mTitle + ", settingsActivity=" + mSettingsActivity);
-                }
-                return null;
-            }
-            return new InjectedSetting(this);
-        }
-    }
-}
diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java
index 1206e85..4137933 100644
--- a/src/com/android/settings/location/SettingsInjector.java
+++ b/src/com/android/settings/location/SettingsInjector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,228 +16,67 @@
 
 package com.android.settings.location;
 
-import android.app.ActivityManager;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
-import android.location.SettingInjectorService;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
-import android.util.AttributeSet;
 import android.util.IconDrawableFactory;
 import android.util.Log;
-import android.util.Xml;
 
 import com.android.settings.widget.AppPreference;
 import com.android.settings.widget.RestrictedAppPreference;
+import com.android.settingslib.location.BaseSettingsInjector;
+import com.android.settingslib.location.InjectedSetting;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 
 import androidx.preference.Preference;
 
 /**
  * Adds the preferences specified by the {@link InjectedSetting} objects to a preference group.
- *
- * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}. We do not use that
- * class directly because it is not a good match for our use case: we do not need the caching, and
- * so do not want the additional resource hit at app install/upgrade time; and we would have to
- * suppress the tie-breaking between multiple services reporting settings with the same name.
- * Code-sharing would require extracting {@link
- * android.content.pm.RegisteredServicesCache#parseServiceAttributes(android.content.res.Resources,
- * String, android.util.AttributeSet)} into an interface, which didn't seem worth it.
  */
-class SettingsInjector {
+public class SettingsInjector extends BaseSettingsInjector {
     static final String TAG = "SettingsInjector";
 
-    /**
-     * If reading the status of a setting takes longer than this, we go ahead and start reading
-     * the next setting.
-     */
-    private static final long INJECTED_STATUS_UPDATE_TIMEOUT_MILLIS = 1000;
-
-    /**
-     * {@link Message#what} value for starting to load status values
-     * in case we aren't already in the process of loading them.
-     */
-    private static final int WHAT_RELOAD = 1;
-
-    /**
-     * {@link Message#what} value sent after receiving a status message.
-     */
-    private static final int WHAT_RECEIVED_STATUS = 2;
-
-    /**
-     * {@link Message#what} value sent after the timeout waiting for a status message.
-     */
-    private static final int WHAT_TIMEOUT = 3;
-
-    private final Context mContext;
-
-    /**
-     * The settings that were injected
-     */
-    private final Set<Setting> mSettings;
-
-    private final Handler mHandler;
+    Context mContext;
 
     public SettingsInjector(Context context) {
+        super(context);
         mContext = context;
-        mSettings = new HashSet<Setting>();
-        mHandler = new StatusLoadingHandler();
     }
 
     /**
-     * Returns a list for a profile with one {@link InjectedSetting} object for each
-     * {@link android.app.Service} that responds to
-     * {@link SettingInjectorService#ACTION_SERVICE_INTENT} and provides the expected setting
-     * metadata.
-     *
-     * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
-     *
-     * TODO: unit test
+     * Adds an injected setting to the root.
      */
-    private List<InjectedSetting> getSettings(final UserHandle userHandle) {
-        PackageManager pm = mContext.getPackageManager();
-        Intent intent = new Intent(SettingInjectorService.ACTION_SERVICE_INTENT);
-
-        final int profileId = userHandle.getIdentifier();
-        List<ResolveInfo> resolveInfos =
-                pm.queryIntentServicesAsUser(intent, PackageManager.GET_META_DATA, profileId);
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Found services for profile id " + profileId + ": " + resolveInfos);
-        }
-        List<InjectedSetting> settings = new ArrayList<InjectedSetting>(resolveInfos.size());
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            try {
-                InjectedSetting setting = parseServiceInfo(resolveInfo, userHandle, pm);
-                if (setting == null) {
-                    Log.w(TAG, "Unable to load service info " + resolveInfo);
-                } else {
-                    settings.add(setting);
-                }
-            } catch (XmlPullParserException e) {
-                Log.w(TAG, "Unable to load service info " + resolveInfo, e);
-            } catch (IOException e) {
-                Log.w(TAG, "Unable to load service info " + resolveInfo, e);
-            }
-        }
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Loaded settings for profile id " + profileId + ": " + settings);
-        }
-
-        return settings;
-    }
-
-    /**
-     * Returns the settings parsed from the attributes of the
-     * {@link SettingInjectorService#META_DATA_NAME} tag, or null.
-     *
-     * Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
-     */
-    private static InjectedSetting parseServiceInfo(ResolveInfo service, UserHandle userHandle,
-            PackageManager pm) throws XmlPullParserException, IOException {
-
-        ServiceInfo si = service.serviceInfo;
-        ApplicationInfo ai = si.applicationInfo;
-
-        if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-            if (Log.isLoggable(TAG, Log.WARN)) {
-                Log.w(TAG, "Ignoring attempt to inject setting from app not in system image: "
-                        + service);
-                return null;
-            }
-        }
-
-        XmlResourceParser parser = null;
+    private Preference addServiceSetting(Context prefContext, List<Preference> prefs,
+            InjectedSetting info) {
+        final PackageManager pm = mContext.getPackageManager();
+        Drawable appIcon = null;
         try {
-            parser = si.loadXmlMetaData(pm, SettingInjectorService.META_DATA_NAME);
-            if (parser == null) {
-                throw new XmlPullParserException("No " + SettingInjectorService.META_DATA_NAME
-                        + " meta-data for " + service + ": " + si);
-            }
-
-            AttributeSet attrs = Xml.asAttributeSet(parser);
-
-            int type;
-            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                    && type != XmlPullParser.START_TAG) {
-            }
-
-            String nodeName = parser.getName();
-            if (!SettingInjectorService.ATTRIBUTES_NAME.equals(nodeName)) {
-                throw new XmlPullParserException("Meta-data does not start with "
-                        + SettingInjectorService.ATTRIBUTES_NAME + " tag");
-            }
-
-            Resources res = pm.getResourcesForApplicationAsUser(si.packageName,
-                    userHandle.getIdentifier());
-            return parseAttributes(si.packageName, si.name, userHandle, res, attrs);
+            final PackageItemInfo itemInfo = new PackageItemInfo();
+            itemInfo.icon = info.iconId;
+            itemInfo.packageName = info.packageName;
+            final ApplicationInfo appInfo = pm.getApplicationInfo(info.packageName,
+                    PackageManager.GET_META_DATA);
+            appIcon = IconDrawableFactory.newInstance(mContext)
+                    .getBadgedIcon(itemInfo, appInfo, info.mUserHandle.getIdentifier());
         } catch (PackageManager.NameNotFoundException e) {
-            throw new XmlPullParserException(
-                    "Unable to load resources for package " + si.packageName);
-        } finally {
-            if (parser != null) {
-                parser.close();
-            }
+            Log.e(TAG, "Can't get ApplicationInfo for " + info.packageName, e);
         }
-    }
-
-    /**
-     * Returns an immutable representation of the static attributes for the setting, or null.
-     */
-    private static InjectedSetting parseAttributes(String packageName, String className,
-            UserHandle userHandle, Resources res, AttributeSet attrs) {
-
-        TypedArray sa = res.obtainAttributes(attrs, android.R.styleable.SettingInjectorService);
-        try {
-            // Note that to help guard against malicious string injection, we do not allow dynamic
-            // specification of the label (setting title)
-            final String title = sa.getString(android.R.styleable.SettingInjectorService_title);
-            final int iconId =
-                    sa.getResourceId(android.R.styleable.SettingInjectorService_icon, 0);
-            final String settingsActivity =
-                    sa.getString(android.R.styleable.SettingInjectorService_settingsActivity);
-            final String userRestriction = sa.getString(
-                    android.R.styleable.SettingInjectorService_userRestriction);
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "parsed title: " + title + ", iconId: " + iconId
-                        + ", settingsActivity: " + settingsActivity);
-            }
-            return new InjectedSetting.Builder()
-                    .setPackageName(packageName)
-                    .setClassName(className)
-                    .setTitle(title)
-                    .setIconId(iconId)
-                    .setUserHandle(userHandle)
-                    .setSettingsActivity(settingsActivity)
-                    .setUserRestriction(userRestriction)
-                    .build();
-        } finally {
-            sa.recycle();
-        }
+        Preference pref = TextUtils.isEmpty(info.userRestriction)
+                ? new AppPreference(prefContext)
+                : new RestrictedAppPreference(prefContext, info.userRestriction);
+        pref.setTitle(info.title);
+        pref.setSummary(null);
+        pref.setIcon(appIcon);
+        pref.setOnPreferenceClickListener(new ServiceSettingClickedListener(info));
+        prefs.add(pref);
+        return pref;
     }
 
     /**
@@ -266,312 +105,4 @@
 
         return prefs;
     }
-
-    /**
-     * Checks wheteher there is any preference that other apps have injected.
-     *
-     * @param profileId Identifier of the user/profile to obtain the injected settings for or
-     *                  UserHandle.USER_CURRENT for all profiles associated with current user.
-     */
-    public boolean hasInjectedSettings(final int profileId) {
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        final List<UserHandle> profiles = um.getUserProfiles();
-        final int profileCount = profiles.size();
-        for (int i = 0; i < profileCount; ++i) {
-            final UserHandle userHandle = profiles.get(i);
-            if (profileId == UserHandle.USER_CURRENT || profileId == userHandle.getIdentifier()) {
-                Iterable<InjectedSetting> settings = getSettings(userHandle);
-                for (InjectedSetting setting : settings) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Reloads the status messages for all the preference items.
-     */
-    public void reloadStatusMessages() {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "reloadingStatusMessages: " + mSettings);
-        }
-        mHandler.sendMessage(mHandler.obtainMessage(WHAT_RELOAD));
-    }
-
-    /**
-     * Adds an injected setting to the root.
-     */
-    private Preference addServiceSetting(Context prefContext, List<Preference> prefs,
-            InjectedSetting info) {
-        final PackageManager pm = mContext.getPackageManager();
-        Drawable appIcon = null;
-        try {
-            final PackageItemInfo itemInfo = new PackageItemInfo();
-            itemInfo.icon = info.iconId;
-            itemInfo.packageName = info.packageName;
-            final ApplicationInfo appInfo = pm.getApplicationInfo(info.packageName,
-                PackageManager.GET_META_DATA);
-            appIcon = IconDrawableFactory.newInstance(mContext)
-                .getBadgedIcon(itemInfo, appInfo, info.mUserHandle.getIdentifier());
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "Can't get ApplicationInfo for " + info.packageName, e);
-        }
-        Preference pref = TextUtils.isEmpty(info.userRestriction)
-                ? new AppPreference(prefContext)
-                : new RestrictedAppPreference(prefContext, info.userRestriction);
-        pref.setTitle(info.title);
-        pref.setSummary(null);
-        pref.setIcon(appIcon);
-        pref.setOnPreferenceClickListener(new ServiceSettingClickedListener(info));
-        prefs.add(pref);
-        return pref;
-    }
-
-    private class ServiceSettingClickedListener
-            implements Preference.OnPreferenceClickListener {
-        private InjectedSetting mInfo;
-
-        public ServiceSettingClickedListener(InjectedSetting info) {
-            mInfo = info;
-        }
-
-        @Override
-        public boolean onPreferenceClick(Preference preference) {
-            // Activity to start if they click on the preference. Must start in new task to ensure
-            // that "android.settings.LOCATION_SOURCE_SETTINGS" brings user back to
-            // Settings > Location.
-            Intent settingIntent = new Intent();
-            settingIntent.setClassName(mInfo.packageName, mInfo.settingsActivity);
-            // Sometimes the user may navigate back to "Settings" and launch another different
-            // injected setting after one injected setting has been launched.
-            //
-            // FLAG_ACTIVITY_CLEAR_TOP allows multiple Activities to stack on each other. When
-            // "back" button is clicked, the user will navigate through all the injected settings
-            // launched before. Such behavior could be quite confusing sometimes.
-            //
-            // In order to avoid such confusion, we use FLAG_ACTIVITY_CLEAR_TASK, which always clear
-            // up all existing injected settings and make sure that "back" button always brings the
-            // user back to "Settings" directly.
-            settingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            mContext.startActivityAsUser(settingIntent, mInfo.mUserHandle);
-            return true;
-        }
-    }
-
-    /**
-     * Loads the setting status values one at a time. Each load starts a subclass of {@link
-     * SettingInjectorService}, so to reduce memory pressure we don't want to load too many at
-     * once.
-     */
-    private final class StatusLoadingHandler extends Handler {
-
-        /**
-         * Settings whose status values need to be loaded. A set is used to prevent redundant loads.
-         */
-        private Set<Setting> mSettingsToLoad = new HashSet<Setting>();
-
-        /**
-         * Settings that are being loaded now and haven't timed out. In practice this should have
-         * zero or one elements.
-         */
-        private Set<Setting> mSettingsBeingLoaded = new HashSet<Setting>();
-
-        /**
-         * Settings that are being loaded but have timed out. If only one setting has timed out, we
-         * will go ahead and start loading the next setting so that one slow load won't delay the
-         * load of the other settings.
-         */
-        private Set<Setting> mTimedOutSettings = new HashSet<Setting>();
-
-        private boolean mReloadRequested;
-
-        private StatusLoadingHandler() {
-            super(Looper.getMainLooper());
-        }
-        @Override
-        public void handleMessage(Message msg) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "handleMessage start: " + msg + ", " + this);
-            }
-
-            // Update state in response to message
-            switch (msg.what) {
-                case WHAT_RELOAD:
-                    mReloadRequested = true;
-                    break;
-                case WHAT_RECEIVED_STATUS:
-                    final Setting receivedSetting = (Setting) msg.obj;
-                    receivedSetting.maybeLogElapsedTime();
-                    mSettingsBeingLoaded.remove(receivedSetting);
-                    mTimedOutSettings.remove(receivedSetting);
-                    removeMessages(WHAT_TIMEOUT, receivedSetting);
-                    break;
-                case WHAT_TIMEOUT:
-                    final Setting timedOutSetting = (Setting) msg.obj;
-                    mSettingsBeingLoaded.remove(timedOutSetting);
-                    mTimedOutSettings.add(timedOutSetting);
-                    if (Log.isLoggable(TAG, Log.WARN)) {
-                        Log.w(TAG, "Timed out after " + timedOutSetting.getElapsedTime()
-                                + " millis trying to get status for: " + timedOutSetting);
-                    }
-                    break;
-                default:
-                    Log.wtf(TAG, "Unexpected what: " + msg);
-            }
-
-            // Decide whether to load additional settings based on the new state. Start by seeing
-            // if we have headroom to load another setting.
-            if (mSettingsBeingLoaded.size() > 0 || mTimedOutSettings.size() > 1) {
-                // Don't load any more settings until one of the pending settings has completed.
-                // To reduce memory pressure, we want to be loading at most one setting (plus at
-                // most one timed-out setting) at a time. This means we'll be responsible for
-                // bringing in at most two services.
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "too many services already live for " + msg + ", " + this);
-                }
-                return;
-            }
-
-            if (mReloadRequested && mSettingsToLoad.isEmpty() && mSettingsBeingLoaded.isEmpty()
-                    && mTimedOutSettings.isEmpty()) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "reloading because idle and reload requesteed " + msg + ", " + this);
-                }
-                // Reload requested, so must reload all settings
-                mSettingsToLoad.addAll(mSettings);
-                mReloadRequested = false;
-            }
-
-            // Remove the next setting to load from the queue, if any
-            Iterator<Setting> iter = mSettingsToLoad.iterator();
-            if (!iter.hasNext()) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "nothing left to do for " + msg + ", " + this);
-                }
-                return;
-            }
-            Setting setting = iter.next();
-            iter.remove();
-
-            // Request the status value
-            setting.startService();
-            mSettingsBeingLoaded.add(setting);
-
-            // Ensure that if receiving the status value takes too long, we start loading the
-            // next value anyway
-            Message timeoutMsg = obtainMessage(WHAT_TIMEOUT, setting);
-            sendMessageDelayed(timeoutMsg, INJECTED_STATUS_UPDATE_TIMEOUT_MILLIS);
-
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "handleMessage end " + msg + ", " + this
-                        + ", started loading " + setting);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "StatusLoadingHandler{" +
-                    "mSettingsToLoad=" + mSettingsToLoad +
-                    ", mSettingsBeingLoaded=" + mSettingsBeingLoaded +
-                    ", mTimedOutSettings=" + mTimedOutSettings +
-                    ", mReloadRequested=" + mReloadRequested +
-                    '}';
-        }
-    }
-
-    /**
-     * Represents an injected setting and the corresponding preference.
-     */
-    private final class Setting {
-
-        public final InjectedSetting setting;
-        public final Preference preference;
-        public long startMillis;
-
-        private Setting(InjectedSetting setting, Preference preference) {
-            this.setting = setting;
-            this.preference = preference;
-        }
-
-        @Override
-        public String toString() {
-            return "Setting{" +
-                    "setting=" + setting +
-                    ", preference=" + preference +
-                    '}';
-        }
-
-        /**
-         * Returns true if they both have the same {@link #setting} value. Ignores mutable
-         * {@link #preference} and {@link #startMillis} so that it's safe to use in sets.
-         */
-        @Override
-        public boolean equals(Object o) {
-            return this == o || o instanceof Setting && setting.equals(((Setting) o).setting);
-        }
-
-        @Override
-        public int hashCode() {
-            return setting.hashCode();
-        }
-
-        /**
-         * Starts the service to fetch for the current status for the setting, and updates the
-         * preference when the service replies.
-         */
-        public void startService() {
-            final ActivityManager am = (ActivityManager)
-                    mContext.getSystemService(Context.ACTIVITY_SERVICE);
-            if (!am.isUserRunning(setting.mUserHandle.getIdentifier())) {
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "Cannot start service as user "
-                            + setting.mUserHandle.getIdentifier() + " is not running");
-                }
-                return;
-            }
-            Handler handler = new Handler() {
-                @Override
-                public void handleMessage(Message msg) {
-                    Bundle bundle = msg.getData();
-                    boolean enabled = bundle.getBoolean(SettingInjectorService.ENABLED_KEY, true);
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, setting + ": received " + msg + ", bundle: " + bundle);
-                    }
-                    preference.setSummary(null);
-                    preference.setEnabled(enabled);
-                    mHandler.sendMessage(
-                            mHandler.obtainMessage(WHAT_RECEIVED_STATUS, Setting.this));
-                }
-            };
-            Messenger messenger = new Messenger(handler);
-
-            Intent intent = setting.getServiceIntent();
-            intent.putExtra(SettingInjectorService.MESSENGER_KEY, messenger);
-
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, setting + ": sending update intent: " + intent
-                        + ", handler: " + handler);
-                startMillis = SystemClock.elapsedRealtime();
-            } else {
-                startMillis = 0;
-            }
-
-            // Start the service, making sure that this is attributed to the user associated with
-            // the setting rather than the system user.
-            mContext.startServiceAsUser(intent, setting.mUserHandle);
-        }
-
-        public long getElapsedTime() {
-            long end = SystemClock.elapsedRealtime();
-            return end - startMillis;
-        }
-
-        public void maybeLogElapsedTime() {
-            if (Log.isLoggable(TAG, Log.DEBUG) && startMillis != 0) {
-                long elapsed = getElapsedTime();
-                Log.d(TAG, this + " update took " + elapsed + " millis");
-            }
-        }
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/location/InjectedSettingTest.java b/tests/robotests/src/com/android/settings/location/InjectedSettingTest.java
deleted file mode 100644
index 5045837..0000000
--- a/tests/robotests/src/com/android/settings/location/InjectedSettingTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.location;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public final class InjectedSettingTest {
-
-    private static final String TEST_STRING = "test";
-
-    @Test
-    public void buildWithoutPackageName_ShouldReturnNull() {
-        assertThat(((new InjectedSetting.Builder())
-                .setClassName(TEST_STRING)
-                .setTitle(TEST_STRING)
-                .setSettingsActivity(TEST_STRING).build())).isNull();
-    }
-
-    private InjectedSetting getTestSetting() {
-        return new InjectedSetting.Builder()
-                .setPackageName(TEST_STRING)
-                .setClassName(TEST_STRING)
-                .setTitle(TEST_STRING)
-                .setSettingsActivity(TEST_STRING).build();
-    }
-
-    @Test
-    public void testEquals() {
-        InjectedSetting setting1 = getTestSetting();
-        InjectedSetting setting2 = getTestSetting();
-        assertThat(setting1).isEqualTo(setting2);
-    }
-
-    @Test
-    public void testHashCode() {
-        InjectedSetting setting = getTestSetting();
-        assertThat(setting.hashCode()).isEqualTo(1225314048);
-    }
-}
