Merge "Fork a new developer options page."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7702257..46c6490 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1934,6 +1934,32 @@
android:value="true" />
</activity>
+ <activity android:name="Settings$DevelopmentSettingsDashboardActivity"
+ android:label="@string/development_settings_title"
+ android:icon="@drawable/ic_settings_development"
+ android:taskAffinity="com.android.settings"
+ android:parentActivityName="Settings">
+
+ <!-- Enable when deleting DevelopmentSettingsActivity
+ <intent-filter android:priority="1">
+ <action android:name="android.settings.APPLICATION_DEVELOPMENT_SETTINGS" />
+ <action android:name="com.android.settings.APPLICATION_DEVELOPMENT_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ -->
+ <intent-filter android:priority="50">
+ <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.system" />
+ <meta-data android:name="com.android.settings.summary"
+ android:resource="@string/summary_empty"/>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.development.DevelopmentSettingsDashboardFragment" />
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity>
+
<!-- The opposite of DevelopmentSettingsActivity, it's no-op and only enabled when the real
activity is disabled to be CTS compliant. -->
<activity
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 1ec4284..cd479a5 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -17,6 +17,7 @@
package com.android.settings;
import android.os.Bundle;
+import android.util.FeatureFlagUtils;
import com.android.settings.applications.AppOpsSummary;
import com.android.settings.enterprise.EnterprisePrivacySettings;
@@ -70,7 +71,17 @@
}
public static class BackgroundCheckSummaryActivity extends SettingsActivity { /* empty */ }
public static class StorageUseActivity extends SettingsActivity { /* empty */ }
+
+ /**
+ * @deprecated in favor of {@link DevelopmentSettingsDashboardActivity}.
+ */
+ @Deprecated
public static class DevelopmentSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class DevelopmentSettingsDashboardActivity extends SettingsActivity {
+ public static final boolean isEnabled() {
+ return FeatureFlagUtils.isEnabled("dev_option_v2");
+ }
+ }
public static class AccessibilitySettingsActivity extends SettingsActivity { /* empty */ }
public static class CaptioningSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccessibilityInversionSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index f9b849e..c927889 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -50,6 +50,7 @@
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toolbar;
+
import com.android.internal.util.ArrayUtils;
import com.android.settings.Settings.WifiSettingsActivity;
import com.android.settings.backup.BackupSettingsActivity;
@@ -58,7 +59,6 @@
import com.android.settings.core.instrumentation.SharedPreferencesLogger;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardSummary;
-import com.android.settings.development.DevelopmentSettings;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.SearchActivity;
import com.android.settings.wfd.WifiDisplaySettings;
@@ -66,6 +66,7 @@
import com.android.settingslib.development.DevelopmentSettingsEnabler;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.SettingsDrawerActivity;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -831,9 +832,16 @@
final boolean showDev = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(this)
&& !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
+ final boolean useDevOptionV2 = Settings.DevelopmentSettingsDashboardActivity.isEnabled();
+ // Enable old Dev option if v2 is disabled
somethingChanged = setTileEnabled(new ComponentName(packageName,
Settings.DevelopmentSettingsActivity.class.getName()),
- showDev, isAdmin)
+ showDev && !useDevOptionV2, isAdmin)
+ || somethingChanged;
+ // Enable new Dev option if v2 is enable
+ somethingChanged = setTileEnabled(new ComponentName(packageName,
+ Settings.DevelopmentSettingsDashboardActivity.class.getName()),
+ showDev && useDevOptionV2, isAdmin)
|| somethingChanged;
// Enable/disable backup settings depending on whether the user is admin.
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index a03314c..884696c 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -66,6 +66,7 @@
import com.android.settings.datausage.DataUsageSummary;
import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
import com.android.settings.development.DevelopmentSettings;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
import com.android.settings.deviceinfo.ImeiInformation;
import com.android.settings.deviceinfo.PrivateVolumeForget;
import com.android.settings.deviceinfo.PrivateVolumeSettings;
@@ -177,6 +178,7 @@
PrivateVolumeSettings.class.getName(),
PublicVolumeSettings.class.getName(),
DevelopmentSettings.class.getName(),
+ DevelopmentSettingsDashboardFragment.class.getName(),
AndroidBeam.class.getName(),
WifiDisplaySettings.class.getName(),
PowerUsageSummary.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index fddd522..17e556e 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -20,12 +20,14 @@
import com.android.settings.DisplaySettings;
import com.android.settings.SecuritySettings;
+import com.android.settings.Settings;
import com.android.settings.accounts.AccountDetailDashboardFragment;
import com.android.settings.accounts.UserAndAccountDashboardFragment;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.applications.DefaultAppSettings;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.development.DevelopmentSettings;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.language.LanguageAndInputSettings;
@@ -83,8 +85,13 @@
SystemDashboardFragment.class.getName(), CategoryKey.CATEGORY_SYSTEM);
PARENT_TO_CATEGORY_KEY_MAP.put(LanguageAndInputSettings.class.getName(),
CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
- PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettings.class.getName(),
- CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
+ if (Settings.DevelopmentSettingsDashboardActivity.isEnabled()) {
+ PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
+ CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
+ } else {
+ PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettings.class.getName(),
+ CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
+ }
PARENT_TO_CATEGORY_KEY_MAP.put(ConfigureNotificationSettings.class.getName(),
CategoryKey.CATEGORY_NOTIFICATIONS);
PARENT_TO_CATEGORY_KEY_MAP.put(LockscreenDashboardFragment.class.getName(),
diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java
index 3759ea1..3115dc4 100644
--- a/src/com/android/settings/development/DevelopmentSettings.java
+++ b/src/com/android/settings/development/DevelopmentSettings.java
@@ -110,7 +110,9 @@
/*
* Displays preferences for application developers.
+ * @deprecated in favor of {@link DevelopmentSettingsDashboardFragment}
*/
+@Deprecated
public class DevelopmentSettings extends RestrictedSettingsFragment
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable {
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
new file mode 100644
index 0000000..30be654
--- /dev/null
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 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.development;
+
+import android.content.Context;
+import android.os.UserManager;
+import android.provider.SearchIndexableResource;
+import android.util.Log;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.development.DevelopmentSettingsEnabler;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment {
+
+ private static final String TAG = "DevSettingsDashboard";
+
+ private SwitchBar mSwitchBar;
+
+ public DevelopmentSettingsDashboardFragment() {
+ super(UserManager.DISALLOW_DEBUGGING_FEATURES);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.DEVELOPMENT;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected int getHelpResource() {
+ return 0;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ Log.d(TAG, "Creating pref screen");
+ return R.xml.development_prefs;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context);
+ }
+
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
+ return null;
+ }
+
+ /**
+ * For Search.
+ */
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(context);
+ }
+
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.development_prefs;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context
+ context) {
+ return buildPreferenceControllers(context);
+ }
+ };
+}
diff --git a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
index 948b14a..a2a772b 100644
--- a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
+++ b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
@@ -1 +1,2 @@
+com.android.settings.development.DevelopmentSettingsDashboardFragment
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
diff --git a/tests/robotests/src/android/util/FeatureFlagUtils.java b/tests/robotests/src/android/util/FeatureFlagUtils.java
new file mode 100644
index 0000000..6bc0557
--- /dev/null
+++ b/tests/robotests/src/android/util/FeatureFlagUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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 android.util;
+
+import android.os.SystemProperties;
+import android.text.TextUtils;
+
+/**
+ * This class is only needed to get around Robolectric issue.
+ */
+public class FeatureFlagUtils {
+ public static final String FFLAG_PREFIX = "sys.fflag.";
+ public static final String FFLAG_OVERRIDE_PREFIX = FFLAG_PREFIX + "override.";
+
+ /**
+ * Whether or not a flag is enabled.
+ *
+ * @param feature the flag name
+ * @return true if the flag is enabled (either by default in system, or override by user)
+ */
+ public static boolean isEnabled(String feature) {
+ // Tries to get feature flag from system property.
+ // Step 1: check if feature flag has any override. Flag name: sys.fflag.override.<feature>
+ String value = SystemProperties.get(FFLAG_OVERRIDE_PREFIX + feature);
+ if (!TextUtils.isEmpty(value)) {
+ return Boolean.parseBoolean(value);
+ }
+ // Step 2: check if feature flag has any default value. Flag name: sys.fflag.<feature>
+ value = SystemProperties.get(FFLAG_PREFIX + feature);
+ return Boolean.parseBoolean(value);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
new file mode 100644
index 0000000..04ff721
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 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.development;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settingslib.development.DevelopmentSettingsEnabler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+ shadows = {
+ SettingsShadowResources.class,
+ SettingsShadowResources.SettingsShadowTheme.class
+ })
+public class DevelopmentSettingsDashboardFragmentTest {
+
+ private DevelopmentSettingsDashboardFragment mDashboard;
+
+ @Before
+ public void setUp() {
+ mDashboard = new DevelopmentSettingsDashboardFragment();
+ }
+
+ @Test
+ public void shouldNotHaveHelpResource() {
+ assertThat(mDashboard.getHelpResource()).isEqualTo(0);
+ }
+
+ @Test
+ public void shouldLogAsFeatureFlagPage() {
+ assertThat(mDashboard.getMetricsCategory())
+ .isEqualTo(MetricsProto.MetricsEvent.DEVELOPMENT);
+ }
+
+ @Test
+ public void searchIndex_shouldIndexFromPrefXml() {
+ final List<SearchIndexableResource> index =
+ DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
+ .getXmlResourcesToIndex(RuntimeEnvironment.application, true);
+
+ assertThat(index.size()).isEqualTo(1);
+ assertThat(index.get(0).xmlResId).isEqualTo(R.xml.development_prefs);
+ }
+
+ @Test
+ public void searchIndex_pageDisabled_shouldAddAllKeysToNonIndexable() {
+ final Context appContext = RuntimeEnvironment.application;
+ DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(appContext, false);
+
+ final List<String> nonIndexableKeys =
+ DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
+ .getNonIndexableKeys(appContext);
+
+ assertThat(nonIndexableKeys).contains("development_prefs_screen");
+ }
+
+ @Test
+ public void searchIndex_pageEnabled_shouldNotAddKeysToNonIndexable() {
+ final Context appContext = RuntimeEnvironment.application;
+ DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(appContext, true);
+
+ final List<String> nonIndexableKeys =
+ DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
+ .getNonIndexableKeys(appContext);
+
+ assertThat(nonIndexableKeys).doesNotContain("development_prefs_screen");
+ }
+}