Add location to security settings.

Bug: 32437756
Test: RunSettingsRoboTests
Change-Id: I999669963801684eb2399f5e642159970727b3c4
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 5f90353..eb79c25 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -20,7 +20,6 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
 import android.app.FragmentManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
@@ -35,7 +34,6 @@
 import android.os.PersistableBundle;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.provider.SearchIndexableResource;
 import android.provider.Settings;
 import android.security.KeyStore;
@@ -52,11 +50,14 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.fingerprint.FingerprintSettings;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Index;
 import com.android.settings.search.Indexable;
@@ -64,6 +65,9 @@
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.DashboardCategory;
+import com.android.settingslib.drawer.Tile;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -79,6 +83,7 @@
         GearPreference.OnGearClickListener {
 
     private static final String TAG = "SecuritySettings";
+
     private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent";
     private static final Intent TRUST_AGENT_INTENT =
             new Intent(TrustAgentService.SERVICE_INTERFACE);
@@ -125,6 +130,7 @@
 
     private static final int MY_USER_ID = UserHandle.myUserId();
 
+    private DashboardFeatureProvider mDashboardFeatureProvider;
     private DevicePolicyManager mDPM;
     private SubscriptionManager mSubscriptionManager;
     private UserManager mUm;
@@ -162,17 +168,22 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mSubscriptionManager = SubscriptionManager.from(getActivity());
+        final Activity activity = getActivity();
 
-        mLockPatternUtils = new LockPatternUtils(getActivity());
+        mSubscriptionManager = SubscriptionManager.from(activity);
 
-        mManagedPasswordProvider = ManagedLockPasswordProvider.get(getActivity(), MY_USER_ID);
+        mLockPatternUtils = new LockPatternUtils(activity);
+
+        mManagedPasswordProvider = ManagedLockPasswordProvider.get(activity, MY_USER_ID);
 
         mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
 
-        mUm = UserManager.get(getActivity());
+        mUm = UserManager.get(activity);
 
-        mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
+        mChooseLockSettingsHelper = new ChooseLockSettingsHelper(activity);
+
+        mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
+                .getDashboardFeatureProvider(activity);
 
         if (savedInstanceState != null
                 && savedInstanceState.containsKey(TRUST_AGENT_CLICK_INTENT)) {
@@ -399,6 +410,13 @@
         Index.getInstance(getActivity())
                 .updateFromClassNameResource(SecuritySettings.class.getName(), true, true);
 
+        final List<Preference> tilePrefs = getDynamicTilesForSecurity();
+        if (tilePrefs != null && !tilePrefs.isEmpty()) {
+            for (Preference preference : tilePrefs) {
+                root.addPreference(preference);
+            }
+        }
+
         for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
             final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
             if (pref != null) pref.setOnPreferenceChangeListener(this);
@@ -745,6 +763,31 @@
                 SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
     }
 
+    private List<Preference> getDynamicTilesForSecurity() {
+        if (!mDashboardFeatureProvider.isEnabled()) {
+            return null;
+        }
+        final DashboardCategory category =
+                mDashboardFeatureProvider.getTilesForCategory(CategoryKey.CATEGORY_SECURITY);
+        if (category == null) {
+            Log.d(TAG, "NO dashboard tiles for " + TAG);
+            return null;
+        }
+        final List<Tile> tiles = category.tiles;
+        if (tiles == null) {
+            Log.d(TAG, "tile list is empty, skipping category " + category.title);
+            return null;
+        }
+        final List<Preference> preferences = new ArrayList<>();
+        for (Tile tile : tiles) {
+            final Preference pref = new Preference(getPrefContext());
+            mDashboardFeatureProvider
+                    .bindPreferenceToTile(getActivity(), pref, tile, null /* key */);
+            preferences.add(pref);
+        }
+        return preferences;
+    }
+
     @Override
     public boolean onPreferenceChange(Preference preference, Object value) {
         boolean result = true;
@@ -1053,7 +1096,6 @@
             if (root != null) {
                 root.removeAll();
             }
-            root = null;
 
             final int resid = getResIdForLockUnlockSubScreen(getActivity(),
                     new LockPatternUtils(getContext()),
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 432dec3..eff2004 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -289,6 +289,8 @@
             // Home page > Network & Internet
             "com.android.settings.Settings.WifiDashboardAlias",
             "com.android.settings.Settings.DataUsageDashboardAlias",
+            // Home page > Security
+            "com.android.settings.Settings.LocationDashboardAlias",
             // Home page > System
             "com.android.settings.Settings.LanguageAndInputDashboardAlias",
             "com.android.settings.Settings.DateTimeDashboardAlias",
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProvider.java b/src/com/android/settings/dashboard/DashboardFeatureProvider.java
index 0a8dbbf..8601f1d 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProvider.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProvider.java
@@ -15,6 +15,7 @@
  */
 package com.android.settings.dashboard;
 
+import android.app.Activity;
 import android.content.Context;
 import android.support.v7.preference.Preference;
 
@@ -56,6 +57,16 @@
     String getDashboardKeyForTile(Tile tile);
 
     /**
+     * Binds preference to data provided by tile.
+     *
+     * @param activity If tile contains intent to launch, it will be launched from this activity
+     * @param pref The preference to bind data
+     * @param tile The binding data
+     * @param key They key for preference. If null, we will generate one from tile data
+     */
+    void bindPreferenceToTile(Activity activity, Preference pref, Tile tile, String key);
+
+    /**
      * Returns a {@link ProgressiveDisclosureMixin} for specified fragment.
      */
     ProgressiveDisclosureMixin getProgressiveDisclosureMixin(Context context,
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index ed0520a..4480281 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -16,10 +16,15 @@
 
 package com.android.settings.dashboard;
 
+import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
 import android.support.v7.preference.Preference;
+import android.text.TextUtils;
 
+import com.android.settings.SettingsActivity;
 import com.android.settingslib.drawer.CategoryManager;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
@@ -74,6 +79,40 @@
     }
 
     @Override
+    public void bindPreferenceToTile(Activity activity, Preference pref, Tile tile, String key) {
+        pref.setTitle(tile.title);
+        if (!TextUtils.isEmpty(key)) {
+            pref.setKey(key);
+        } else {
+            pref.setKey(getDashboardKeyForTile(tile));
+        }
+        pref.setSummary(tile.summary);
+        if (tile.icon != null) {
+            pref.setIcon(tile.icon.loadDrawable(activity));
+        }
+        final Bundle metadata = tile.metaData;
+        String clsName = null;
+        if (metadata != null) {
+            clsName = metadata.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
+        }
+        if (!TextUtils.isEmpty(clsName)) {
+            pref.setFragment(clsName);
+        } else if (tile.intent != null) {
+            final Intent intent = new Intent(tile.intent);
+            pref.setOnPreferenceClickListener(preference -> {
+                activity.startActivityForResult(intent, 0);
+                return true;
+            });
+        }
+        // Use negated priority for order, because tile priority is based on intent-filter
+        // (larger value has higher priority). However pref order defines smaller value has
+        // higher priority.
+        if (tile.priority != 0) {
+            pref.setOrder(-tile.priority);
+        }
+    }
+
+    @Override
     public ProgressiveDisclosureMixin getProgressiveDisclosureMixin(Context context,
             DashboardFragment fragment) {
         return new ProgressiveDisclosureMixin(context, this, fragment);
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index d76fe7a..3bbec09 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -17,7 +17,6 @@
 
 import android.app.Activity;
 import android.content.Context;
-import android.content.Intent;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -34,7 +33,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.core.PreferenceController;
 import com.android.settings.overlay.FeatureFactory;
@@ -322,11 +320,12 @@
                 // Have the key already, will rebind.
                 final Preference preference = mProgressiveDisclosureMixin.findPreference(
                         screen, key);
-                bindPreferenceToTile(context, preference, tile, key);
+                mDashboardFeatureProvider.bindPreferenceToTile(
+                        getActivity(), preference, tile, key);
             } else {
                 // Don't have this key, add it.
                 final Preference pref = new DashboardTilePreference(context);
-                bindPreferenceToTile(context, pref, tile, key);
+                mDashboardFeatureProvider.bindPreferenceToTile(getActivity(), pref, tile, key);
                 mProgressiveDisclosureMixin.addPreference(screen, pref);
                 mDashboardTilePrefKeys.add(key);
             }
@@ -338,32 +337,4 @@
             mProgressiveDisclosureMixin.removePreference(screen, key);
         }
     }
-
-    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
-    void bindPreferenceToTile(Context context, Preference pref, Tile tile, String key) {
-        pref.setTitle(tile.title);
-        pref.setKey(key);
-        pref.setSummary(tile.summary);
-        if (tile.icon != null) {
-            pref.setIcon(tile.icon.loadDrawable(context));
-        }
-        final Bundle metadata = tile.metaData;
-        String clsName = null;
-        if (metadata != null) {
-            clsName = metadata.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
-        }
-        if (!TextUtils.isEmpty(clsName)) {
-            pref.setFragment(clsName);
-        } else if (tile.intent != null) {
-            final Intent intent = new Intent(tile.intent);
-            pref.setOnPreferenceClickListener(preference -> {
-                getActivity().startActivityForResult(intent, 0);
-                return true;
-            });
-        }
-        // Use negated priority for order, because tile priority is based on intent-filter
-        // (larger value has higher priority). However pref order defines smaller value has
-        // higher priority.
-        pref.setOrder(-tile.priority);
-    }
 }