android:value="true" />
</activity-alias>
+ <activity-alias android:name="LocationDashboardAlias"
+ android:targetActivity="Settings$LocationSettingsActivity">
+ <intent-filter>
+ <action android:name="com.android.settings.action.SETTINGS" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.category"
+ android:value="com.android.settings.category.ia.security" />
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.location.LocationSettings" />
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity-alias>
+
<activity android:name=".Settings$SystemDashboardActivity"
android:label="@string/header_category_system"
android:icon="@drawable/ic_settings_about">
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;
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;
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;
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;
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);
private static final int MY_USER_ID = UserHandle.myUserId();
+ private DashboardFeatureProvider mDashboardFeatureProvider;
private DevicePolicyManager mDPM;
private SubscriptionManager mSubscriptionManager;
private UserManager mUm;
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(activity);
- mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
+ mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
+ .getDashboardFeatureProvider(activity);
if (savedInstanceState != null
&& savedInstanceState.containsKey(TRUST_AGENT_CLICK_INTENT)) {
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);
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;
if (root != null) {
root.removeAll();
}
- root = null;
final int resid = getResIdForLockUnlockSubScreen(getActivity(),
new LockPatternUtils(getContext()),
// 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",
*/
package com.android.settings.dashboard;
+import android.app.Activity;
import android.content.Context;
import android.support.v7.preference.Preference;
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,
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;
}
@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);
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;
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;
// 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);
}
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);
- }
}
--- /dev/null
+/*
+ * Copyright (C) 2016 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.dashboard;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settingslib.drawer.Tile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DashboardFeatureProviderImplTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Activity mActivity;
+
+ private DashboardFeatureProviderImpl mImpl;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mImpl = new DashboardFeatureProviderImpl(mActivity);
+ }
+
+ @Test
+ public void bindPreference_shouldBindAllData() {
+ final Preference preference = new Preference(
+ ShadowApplication.getInstance().getApplicationContext());
+ final Tile tile = new Tile();
+ tile.title = "title";
+ tile.summary = "summary";
+ tile.icon = Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565));
+ tile.metaData = new Bundle();
+ tile.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
+ tile.priority = 10;
+ mImpl.bindPreferenceToTile(mActivity, preference, tile, "123");
+
+ assertThat(preference.getTitle()).isEqualTo(tile.title);
+ assertThat(preference.getSummary()).isEqualTo(tile.summary);
+ assertThat(preference.getIcon()).isNotNull();
+ assertThat(preference.getFragment())
+ .isEqualTo(tile.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS));
+ assertThat(preference.getOrder()).isEqualTo(-tile.priority);
+ }
+
+ @Test
+ public void bindPreference_noFragmentMetadata_shouldBindIntent() {
+ final Preference preference = new Preference(
+ ShadowApplication.getInstance().getApplicationContext());
+ final Tile tile = new Tile();
+ tile.metaData = new Bundle();
+ tile.priority = 10;
+ tile.intent = new Intent();
+ mImpl.bindPreferenceToTile(mActivity, preference, tile, "123");
+
+ assertThat(preference.getFragment()).isNull();
+ assertThat(preference.getOnPreferenceClickListener()).isNotNull();
+ assertThat(preference.getOrder()).isEqualTo(-tile.priority);
+ }
+
+ @Test
+ public void bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority() {
+ final Preference preference = new Preference(
+ ShadowApplication.getInstance().getApplicationContext());
+ final Tile tile = new Tile();
+ tile.intent = new Intent();
+ tile.intent.setComponent(new ComponentName("pkg", "class"));
+ mImpl.bindPreferenceToTile(mActivity, preference, tile, null /* key */);
+
+ assertThat(preference.getKey()).isNotNull();
+ assertThat(preference.getOrder()).isEqualTo(Preference.DEFAULT_ORDER);
+ }
+}
}
@Test
- public void bindPreference_shouldBindAllData() {
- final Preference preference = new Preference(
- ShadowApplication.getInstance().getApplicationContext());
- final Tile tile = new Tile();
- tile.title = "title";
- tile.summary = "summary";
- tile.icon = Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565));
- tile.metaData = new Bundle();
- tile.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
- tile.priority = 10;
- mTestFragment.bindPreferenceToTile(mContext, preference, tile, "123");
-
- assertThat(preference.getTitle()).isEqualTo(tile.title);
- assertThat(preference.getSummary()).isEqualTo(tile.summary);
- assertThat(preference.getIcon()).isNotNull();
- assertThat(preference.getFragment())
- .isEqualTo(tile.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS));
- assertThat(preference.getOrder()).isEqualTo(-tile.priority);
- }
-
- @Test
- public void bindPreference_noFragmentMetadata_shouldBindIntent() {
- final Preference preference = new Preference(
- ShadowApplication.getInstance().getApplicationContext());
- final Tile tile = new Tile();
- tile.metaData = new Bundle();
- tile.priority = 10;
- tile.intent = new Intent();
- mTestFragment.bindPreferenceToTile(mContext, preference, tile, "123");
-
- assertThat(preference.getFragment()).isNull();
- assertThat(preference.getOnPreferenceClickListener()).isNotNull();
- assertThat(preference.getOrder()).isEqualTo(-tile.priority);
- }
-
- @Test
public void updateState_skipUnavailablePrefs() {
List<PreferenceController> preferenceControllers = mTestFragment.mControllers;
preferenceControllers.add(mock(PreferenceController.class));