Merge "Use the migrated injected setting code in settingslib. Manual merge to master from pi-car-dev Bug: 68198078 Test: Tested on device Change-Id: Iff767cd6bf7408b45ce9594628d3fd0a71744e9f"
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);
-    }
-}