Rearrange a few settings into System category page.

- Use activity-alias to define which activity shows up in what category.
  We choose activity-alias because it creates a reference to UI we need
  without having to define a new set of intent-filter and/or category
  keys. This reduces maintainence in the long run. We should merge
  metadata from activity-alias into targetActivity when cleaning up.

- Created new System dashboard activity that hosts all system category
  tiles dynamically, and a static tile for checking system update.

Bug: 31781480
Test: manual
Test: make RunSettingsRoboTests -j40
Change-Id: Ia2d762e3e1aebd17423a395c5e6c286dc3326492
This commit is contained in:
Fan Zhang
2016-09-29 14:37:14 -07:00
parent 9fc9f0f177
commit cc335d9509
11 changed files with 398 additions and 15 deletions

View File

@@ -2275,8 +2275,6 @@
</intent-filter> </intent-filter>
<meta-data android:name="com.android.settings.category" <meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.device" /> android:value="com.android.settings.category.device" />
<meta-data android:name="com.android.settings.iacategory"
android:value="com.android.settings.category.homepage" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS" <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.fuelgauge.PowerUsageSummary" /> android:value="com.android.settings.fuelgauge.PowerUsageSummary" />
</activity> </activity>
@@ -3033,21 +3031,117 @@
</activity> </activity>
<!-- Information architecture host activities --> <!-- Information architecture host activities -->
<activity
android:name=".Settings$SupportActivity" <!-- Alias for battery settings in new IA. Remove and merge metadata into TargetActivity -->
android:label="@string/page_tab_title_support" <activity-alias android:name="BatteryDashboardAlias"
android:icon="@drawable/ic_help_24dp"> android:targetActivity="Settings$PowerUsageSummaryActivity">
<intent-filter android:priority="-1"> <intent-filter android:priority="10">
<action android:name="com.android.settings.action.SETTINGS" /> <action android:name="com.android.settings.action.SETTINGS"/>
</intent-filter> </intent-filter>
<meta-data android:name="com.android.settings.iacategory" <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.category.homepage" /> android:value="com.android.settings.fuelgauge.PowerUsageSummary"/>
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.homepage"/>
</activity-alias>
<activity android:name=".Settings$SystemDashboardActivity"
android:label="@string/header_category_system"
android:icon="@drawable/ic_settings_about">
<intent-filter android:priority="1">
<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.homepage"/>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.system.SystemDashboardFragment"/>
</activity>
<activity android:name=".Settings$SupportDashboardActivity"
android:label="@string/page_tab_title_support"
android:icon="@drawable/ic_help_24dp">
<intent-filter android:priority="0">
<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.homepage"/>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS" <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.dashboard.SupportFragment"/> android:value="com.android.settings.dashboard.SupportFragment"/>
<meta-data android:name="com.android.settings.summary" <meta-data android:name="com.android.settings.summary"
android:resource="@string/help_label" /> android:resource="@string/help_label"/>
</activity> </activity>
<!-- Alias for IME & Language in new IA. Should merge into TargetActivity when launch -->
<activity-alias android:name="LanguageAndInputDashboardAlias"
android:targetActivity="Settings$InputMethodAndLanguageSettingsActivity">
<intent-filter android:priority="250">
<action android:name="com.android.settings.action.SETTINGS" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.inputmethod.InputMethodAndLanguageSettings" />
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.system" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity-alias>
<!-- Alias for Date & Time in new IA. Should merge into TargetActivity when launch -->
<activity-alias android:name="DateTimeDashboardAlias"
android:targetActivity="Settings$DateTimeSettingsActivity">
<intent-filter android:priority="240">
<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.FRAGMENT_CLASS"
android:value="com.android.settings.DateTimeSettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity-alias>
<activity-alias android:name="AccessibilityDashboardAlias"
android:targetActivity="Settings$AccessibilitySettingsActivity">
<intent-filter android:priority="150">
<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.FRAGMENT_CLASS"
android:value="com.android.settings.accessibility.AccessibilitySettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity-alias>
<!-- Alias for developer setting in new IA. Should merge into TargetActivity when launch -->
<activity-alias android:name="DevelopmentSettingsDashboardAlias"
android:targetActivity="Settings$DevelopmentSettingsActivity"
android:label="@string/development_settings_title"
android:icon="@drawable/ic_settings_development">
<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.FRAGMENT_CLASS"
android:value="com.android.settings.DevelopmentSettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity-alias>
<activity-alias android:name="AboutDeviceDashboardAlias"
android:targetActivity="Settings$DeviceInfoSettingsActivity">
<intent-filter android:priority="10">
<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.FRAGMENT_CLASS"
android:value="com.android.settings.DeviceInfoSettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity-alias>
<!-- End of information architecture host activities -->
<service <service
android:name=".SettingsDumpService" android:name=".SettingsDumpService"
android:exported="true" android:exported="true"

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- System updates -->
<com.android.settings.dashboard.DashboardTilePreference
android:key="system_update_settings"
android:title="@string/system_update_settings_list_item_title"
android:summary="@string/system_update_settings_list_item_summary"
android:order="-30">
<intent android:action="android.settings.SYSTEM_UPDATE_SETTINGS"/>
</com.android.settings.dashboard.DashboardTilePreference>
</PreferenceScreen>

View File

@@ -68,7 +68,10 @@ public class Settings extends SettingsActivity {
} }
public static class BackgroundCheckSummaryActivity extends SettingsActivity { /* empty */ } public static class BackgroundCheckSummaryActivity extends SettingsActivity { /* empty */ }
public static class StorageUseActivity 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 AccessibilitySettingsActivity extends SettingsActivity { /* empty */ }
public static class CaptioningSettingsActivity extends SettingsActivity { /* empty */ } public static class CaptioningSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccessibilityInversionSettingsActivity 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 */ } public static class SystemSettings extends SettingsActivity { /* empty */ }
// Top level categories for new IA // Top level categories for new IA
public static class SupportActivity extends SettingsActivity {} public static class SystemDashboardActivity extends SettingsActivity {}
public static class SupportDashboardActivity extends SettingsActivity {}
} }

View File

@@ -124,6 +124,7 @@ import com.android.settings.qstile.DevelopmentTiles;
import com.android.settings.search.DynamicIndexableContentMonitor; import com.android.settings.search.DynamicIndexableContentMonitor;
import com.android.settings.search.Index; import com.android.settings.search.Index;
import com.android.settings.sim.SimSettings; import com.android.settings.sim.SimSettings;
import com.android.settings.system.SystemDashboardFragment;
import com.android.settings.tts.TextToSpeechSettings; import com.android.settings.tts.TextToSpeechSettings;
import com.android.settings.users.UserSettings; import com.android.settings.users.UserSettings;
import com.android.settings.vpn2.VpnSettings; import com.android.settings.vpn2.VpnSettings;
@@ -264,6 +265,18 @@ public class SettingsActivity extends SettingsDrawerActivity
Settings.AccessibilitySettingsActivity.class.getName(), Settings.AccessibilitySettingsActivity.class.getName(),
Settings.PrintSettingsActivity.class.getName(), Settings.PrintSettingsActivity.class.getName(),
Settings.PaymentSettingsActivity.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 = { private static final String[] ENTRY_FRAGMENTS = {
@@ -363,7 +376,8 @@ public class SettingsActivity extends SettingsDrawerActivity
NightDisplaySettings.class.getName(), NightDisplaySettings.class.getName(),
ManageDomainUrls.class.getName(), ManageDomainUrls.class.getName(),
AutomaticStorageManagerSettings.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, setTileEnabled(new ComponentName(packageName,
Settings.DevelopmentSettingsActivity.class.getName()), Settings.DevelopmentSettingsActivity.class.getName()),
showDev, isAdmin, pm); showDev, isAdmin, pm);
setTileEnabled(new ComponentName(packageName,
Settings.DevelopmentSettingsActivity.DASHBOARD_ALIAS),
showDev, isAdmin, pm);
// Reveal development-only quick settings tiles // Reveal development-only quick settings tiles
DevelopmentTiles.setTilesEnabled(this, showDev); DevelopmentTiles.setTilesEnabled(this, showDev);

View File

@@ -16,7 +16,6 @@
package com.android.settings; package com.android.settings;
import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManagerNative; import android.app.ActivityManagerNative;
@@ -88,6 +87,7 @@ import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TabWidget; import android.widget.TabWidget;
import com.android.internal.app.UnlaunchableAppActivity; import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.internal.util.UserIcons; import com.android.internal.util.UserIcons;

View File

@@ -33,6 +33,10 @@ public abstract class InstrumentedFragment extends ObservablePreferenceFragment
protected MetricsFeatureProvider mMetricsFeatureProvider; 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() { public InstrumentedFragment() {
// Mixin that logs visibility change for activity. // Mixin that logs visibility change for activity.
getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory())); getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory()));

View File

@@ -16,6 +16,7 @@
package com.android.settings.dashboard; package com.android.settings.dashboard;
import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import java.util.List; import java.util.List;
@@ -34,8 +35,20 @@ public interface DashboardFeatureProvider {
*/ */
DashboardCategory getTilesForHomepage(); DashboardCategory getTilesForHomepage();
/**
* Get tiles (wrapped in {@link DashboardCategory}) for system category.
*/
DashboardCategory getTilesForSystemCategory();
/** /**
* Get all tiles, grouped by category. * Get all tiles, grouped by category.
*/ */
List<DashboardCategory> getAllCategories(); List<DashboardCategory> 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);
} }

View File

@@ -21,6 +21,7 @@ import android.content.Context;
import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.CategoryManager; import com.android.settingslib.drawer.CategoryManager;
import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import java.util.List; import java.util.List;
@@ -48,8 +49,18 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
return mCategoryManager.getTilesByCategory(mContext, CategoryKey.CATEGORY_HOMEPAGE); return mCategoryManager.getTilesByCategory(mContext, CategoryKey.CATEGORY_HOMEPAGE);
} }
@Override
public DashboardCategory getTilesForSystemCategory() {
return mCategoryManager.getTilesByCategory(mContext, CategoryKey.CATEGORY_SYSTEM);
}
@Override @Override
public List<DashboardCategory> getAllCategories() { public List<DashboardCategory> getAllCategories() {
return mCategoryManager.getCategories(mContext); return mCategoryManager.getCategories(mContext);
} }
@Override
public int getPriorityGroup(Tile tile) {
return tile.priority / 100;
}
} }

View File

@@ -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);
}
}

View File

@@ -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<Tile> 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);
}
}
}

View File

@@ -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();
}
}