diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fd22c635b29..092743584ce 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2275,8 +2275,6 @@ - @@ -3033,21 +3031,117 @@ - - - + + + + + - + + + + + + + + + + + + + + + + + + android:resource="@string/help_label"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index cf08f4af396..3bec337da41 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -68,7 +68,10 @@ public class Settings extends SettingsActivity { } public static class BackgroundCheckSummaryActivity extends SettingsActivity { /* empty */ } public static class StorageUseActivity extends SettingsActivity { /* empty */ } - public static class DevelopmentSettingsActivity extends SettingsActivity { /* empty */ } + public static class DevelopmentSettingsActivity extends SettingsActivity { + public static final String DASHBOARD_ALIAS = + "com.android.settings.DevelopmentSettingsDashboardAlias"; + } public static class AccessibilitySettingsActivity extends SettingsActivity { /* empty */ } public static class CaptioningSettingsActivity extends SettingsActivity { /* empty */ } public static class AccessibilityInversionSettingsActivity extends SettingsActivity { /* empty */ } @@ -161,6 +164,7 @@ public class Settings extends SettingsActivity { public static class SystemSettings extends SettingsActivity { /* empty */ } // Top level categories for new IA - public static class SupportActivity extends SettingsActivity {} + public static class SystemDashboardActivity extends SettingsActivity {} + public static class SupportDashboardActivity extends SettingsActivity {} } diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index ecfc3738447..08fa97190a6 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -124,6 +124,7 @@ import com.android.settings.qstile.DevelopmentTiles; import com.android.settings.search.DynamicIndexableContentMonitor; import com.android.settings.search.Index; import com.android.settings.sim.SimSettings; +import com.android.settings.system.SystemDashboardFragment; import com.android.settings.tts.TextToSpeechSettings; import com.android.settings.users.UserSettings; import com.android.settings.vpn2.VpnSettings; @@ -264,6 +265,18 @@ public class SettingsActivity extends SettingsDrawerActivity Settings.AccessibilitySettingsActivity.class.getName(), Settings.PrintSettingsActivity.class.getName(), Settings.PaymentSettingsActivity.class.getName(), + + // New IA + // Home page + "com.android.settings.Settings.BatteryDashboardAlias", + Settings.SystemDashboardActivity.class.getName(), + Settings.SupportDashboardActivity.class.getName(), + // Home page > System + "com.android.settings.Settings.LanguageAndInputDashboardAlias", + "com.android.settings.Settings.DateTimeDashboardAlias", + "com.android.settings.Settings.AccessibilityDashboardAlias", + "com.android.settings.Settings.AboutDeviceDashboardAlias", + }; private static final String[] ENTRY_FRAGMENTS = { @@ -363,7 +376,8 @@ public class SettingsActivity extends SettingsDrawerActivity NightDisplaySettings.class.getName(), ManageDomainUrls.class.getName(), AutomaticStorageManagerSettings.class.getName(), - SupportFragment.class.getName() + SupportFragment.class.getName(), + SystemDashboardFragment.class.getName(), }; @@ -1120,6 +1134,9 @@ public class SettingsActivity extends SettingsDrawerActivity setTileEnabled(new ComponentName(packageName, Settings.DevelopmentSettingsActivity.class.getName()), showDev, isAdmin, pm); + setTileEnabled(new ComponentName(packageName, + Settings.DevelopmentSettingsActivity.DASHBOARD_ALIAS), + showDev, isAdmin, pm); // Reveal development-only quick settings tiles DevelopmentTiles.setTilesEnabled(this, showDev); diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 9e86688012a..1186c4605fd 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -16,7 +16,6 @@ package com.android.settings; -import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerNative; @@ -88,6 +87,7 @@ import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.ListView; import android.widget.TabWidget; + import com.android.internal.app.UnlaunchableAppActivity; import com.android.internal.util.ArrayUtils; import com.android.internal.util.UserIcons; diff --git a/src/com/android/settings/core/InstrumentedFragment.java b/src/com/android/settings/core/InstrumentedFragment.java index e50eae3fd6e..79ba5c7e398 100644 --- a/src/com/android/settings/core/InstrumentedFragment.java +++ b/src/com/android/settings/core/InstrumentedFragment.java @@ -33,6 +33,10 @@ public abstract class InstrumentedFragment extends ObservablePreferenceFragment protected MetricsFeatureProvider mMetricsFeatureProvider; + // metrics placeholder value. Only use this for development. + protected final int PLACEHOLDER_METRIC = 10000; + protected final int SYSTEM_CATEGORY_FRAGMENT = PLACEHOLDER_METRIC + 1; + public InstrumentedFragment() { // Mixin that logs visibility change for activity. getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory())); diff --git a/src/com/android/settings/dashboard/DashboardFeatureProvider.java b/src/com/android/settings/dashboard/DashboardFeatureProvider.java index c09374832a9..148127eeded 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProvider.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProvider.java @@ -16,6 +16,7 @@ package com.android.settings.dashboard; import com.android.settingslib.drawer.DashboardCategory; +import com.android.settingslib.drawer.Tile; import java.util.List; @@ -34,8 +35,20 @@ public interface DashboardFeatureProvider { */ DashboardCategory getTilesForHomepage(); + /** + * Get tiles (wrapped in {@link DashboardCategory}) for system category. + */ + DashboardCategory getTilesForSystemCategory(); + /** * Get all tiles, grouped by category. */ List getAllCategories(); + + /** + * Returns a priority group for tile. priority level is grouped into hundreds. tiles with + * priority 100 - 199 belongs to priority level 100, tiles with priority 200 - 299 is in + * group 200, and so on. + */ + int getPriorityGroup(Tile tile); } diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index 1f0b7f24d4c..836bfb08fae 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -21,6 +21,7 @@ import android.content.Context; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.CategoryManager; import com.android.settingslib.drawer.DashboardCategory; +import com.android.settingslib.drawer.Tile; import java.util.List; @@ -48,8 +49,18 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { return mCategoryManager.getTilesByCategory(mContext, CategoryKey.CATEGORY_HOMEPAGE); } + @Override + public DashboardCategory getTilesForSystemCategory() { + return mCategoryManager.getTilesByCategory(mContext, CategoryKey.CATEGORY_SYSTEM); + } + @Override public List getAllCategories() { return mCategoryManager.getCategories(mContext); } + + @Override + public int getPriorityGroup(Tile tile) { + return tile.priority / 100; + } } diff --git a/src/com/android/settings/dashboard/DashboardTilePreference.java b/src/com/android/settings/dashboard/DashboardTilePreference.java new file mode 100644 index 00000000000..918cf0841f4 --- /dev/null +++ b/src/com/android/settings/dashboard/DashboardTilePreference.java @@ -0,0 +1,45 @@ +/** + * 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.content.Context; +import android.util.AttributeSet; + +import com.android.settings.DividerPreference; +import com.android.settings.R; + +/** + * A {@code Preference} styled as a dashboard tile. + */ +public class DashboardTilePreference extends DividerPreference { + + public DashboardTilePreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public DashboardTilePreference(Context context) { + super(context); + init(); + } + + private void init() { + setLayoutResource(R.layout.dashboard_tile); + setDividerAllowedAbove(false); + setDividerAllowedBelow(false); + } + +} diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java new file mode 100644 index 00000000000..ca56255dd4e --- /dev/null +++ b/src/com/android/settings/system/SystemDashboardFragment.java @@ -0,0 +1,89 @@ +/* + * 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.system; + +import android.content.Context; +import android.os.Bundle; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.dashboard.DashboardFeatureProvider; +import com.android.settings.dashboard.DashboardTilePreference; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.drawer.DashboardCategory; +import com.android.settingslib.drawer.Tile; + +import java.util.List; + +public class SystemDashboardFragment extends SettingsPreferenceFragment implements + Preference.OnPreferenceClickListener { + + private DashboardFeatureProvider mDashboardFeatureProvider; + + @Override + public int getMetricsCategory() { + return SYSTEM_CATEGORY_FRAGMENT; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mDashboardFeatureProvider = + FeatureFactory.getFactory(context).getDashboardFeatureProvider(context); + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + addPreferencesFromResource(R.xml.system_dashboard_fragment); + addDashboardCategoryAsPreference(); + } + + @Override + public boolean onPreferenceClick(Preference preference) { + // Needed to enable preference click ripple + return false; + } + + /** + * Adds dynamic tiles for system category onto PreferenceScreen. + */ + private void addDashboardCategoryAsPreference() { + final Context context = getContext(); + final PreferenceScreen screen = getPreferenceScreen(); + final DashboardCategory category = mDashboardFeatureProvider.getTilesForSystemCategory(); + final List tiles = category.tiles; + for (Tile tile : tiles) { + final DashboardTilePreference pref = new DashboardTilePreference(context); + pref.setTitle(tile.title); + pref.setSummary(tile.summary); + if (tile.icon != null) { + pref.setIcon(tile.icon.loadDrawable(context)); + } + if (tile.intent != null) { + pref.setIntent(tile.intent); + } + // 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); + screen.addPreference(pref); + } + } + +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/DashboardTilePreferenceTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/DashboardTilePreferenceTest.java new file mode 100644 index 00000000000..470eb439512 --- /dev/null +++ b/tests/robotests/src/com/android/settings/dashboard/conditional/DashboardTilePreferenceTest.java @@ -0,0 +1,78 @@ +/** + * 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.conditional; + + +import android.content.Context; +import android.support.v7.preference.PreferenceViewHolder; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import com.android.settings.TestConfig; +import com.android.settings.dashboard.DashboardTilePreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class DashboardTilePreferenceTest { + + private ShadowApplication mShadowApplication; + private Context mContext; + private PreferenceViewHolder mHolder; + private DashboardTilePreference mPreference; + + @Before + public void setUp() { + mShadowApplication = ShadowApplication.getInstance(); + mContext = mShadowApplication.getApplicationContext(); + mPreference = new DashboardTilePreference(mContext); + + LayoutInflater inflater = LayoutInflater.from(mContext); + final View view = inflater.inflate(mPreference.getLayoutResource(), + new LinearLayout(mContext), false); + + mHolder = new PreferenceViewHolder(view); + } + + @Test + public void setHasDivider_shouldShowDivider() { + mPreference.setDividerAllowedAbove(true); + mPreference.setDividerAllowedBelow(true); + mPreference.onBindViewHolder(mHolder); + + assertThat(mHolder.isDividerAllowedAbove()).isTrue(); + assertThat(mHolder.isDividerAllowedBelow()).isTrue(); + } + + @Test + public void setHasNoDivider_shouldHideDivider() { + mPreference.setDividerAllowedAbove(false); + mPreference.setDividerAllowedBelow(false); + mPreference.onBindViewHolder(mHolder); + + assertThat(mHolder.isDividerAllowedAbove()).isFalse(); + assertThat(mHolder.isDividerAllowedBelow()).isFalse(); + } +}