android:background="?android:attr/listDivider" />
<TextView
+ style="@style/TextAppearanceSmall"
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
- android:paddingStart="16dp"
- android:textAppearance="?android:attr/textAppearanceSmall" />
+ android:paddingStart="16dp" />
</LinearLayout>
<ImageView
android:id="@android:id/icon"
- android:layout_width="72dp"
- android:layout_height="24dp"
+ android:layout_width="@dimen/drawer_icon_size"
+ android:layout_height="@dimen/drawer_icon_size"
+ android:layout_marginStart="@dimen/drawer_icon_margin"
+ android:layout_marginEnd="@dimen/drawer_icon_margin"
+ android:layout_marginTop="@dimen/drawer_item_top_bottom_margin"
+ android:layout_marginBottom="@dimen/drawer_item_top_bottom_margin"
+ android:scaleType="fitCenter"
android:layout_gravity="center_vertical"
- android:tint="?android:attr/colorAccent"
- android:paddingStart="16dp"
- android:paddingEnd="32dp" />
+ android:tint="?android:attr/colorAccent"/>
<TextView
+ android:textAppearance="@style/TextAppearanceMedium"
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:textColor="?android:attr/colorControlNormal"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ android:textColor="?android:attr/colorControlNormal" />
</LinearLayout>
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/spacer"
android:layout_width="match_parent"
- android:layout_height="32dp" />
+ android:layout_height="@dimen/drawer_spacer_height" />
</LinearLayout>
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
- android:layout_width="300dp"
+ android:layout_width="@dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
<dimen name="usage_graph_dot_size">.75dp</dimen>
<dimen name="usage_graph_dot_interval">7dp</dimen>
-
+ <dimen name="drawer_icon_size">24dp</dimen>
+ <dimen name="normal_icon_size">24dp</dimen>
+ <dimen name="drawer_icon_margin">24dp</dimen>
+ <dimen name="drawer_width">300dp</dimen>
+ <dimen name="drawer_item_top_bottom_margin">4dp</dimen>
+ <dimen name="drawer_spacer_height">32dp</dimen>
</resources>
--- /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
+ -->
+
+<resources>
+ <style name="TextAppearanceSmall">
+ <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+ </style>
+ <style name="TextAppearanceMedium">
+ <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
+ </style>
+</resources>
}
public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) {
- tryInitCategories(context);
+ return getTilesByCategory(context, categoryKey, TileUtils.SETTING_PKG);
+ }
+
+ public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey,
+ String settingPkg) {
+ tryInitCategories(context, settingPkg);
return mCategoryByKeyMap.get(categoryKey);
}
public synchronized List<DashboardCategory> getCategories(Context context) {
- tryInitCategories(context);
+ return getCategories(context, TileUtils.SETTING_PKG);
+ }
+
+ public synchronized List<DashboardCategory> getCategories(Context context, String settingPkg) {
+ tryInitCategories(context, settingPkg);
return mCategories;
}
- public synchronized void reloadAllCategories(Context context) {
+ public synchronized void reloadAllCategories(Context context, String settingPkg) {
final boolean forceClearCache = mInterestingConfigChanges.applyNewConfig(
context.getResources());
mCategories = null;
- tryInitCategories(context, forceClearCache);
+ tryInitCategories(context, forceClearCache, settingPkg);
}
public synchronized void updateCategoryFromBlacklist(Set<ComponentName> tileBlacklist) {
}
}
- private synchronized void tryInitCategories(Context context) {
+ private synchronized void tryInitCategories(Context context, String settingPkg) {
// Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange
// happens.
- tryInitCategories(context, false /* forceClearCache */);
+ tryInitCategories(context, false /* forceClearCache */, settingPkg);
}
- private synchronized void tryInitCategories(Context context, boolean forceClearCache) {
+ private synchronized void tryInitCategories(Context context, boolean forceClearCache,
+ String settingPkg) {
if (mCategories == null) {
if (forceClearCache) {
mTileByComponentCache.clear();
}
mCategoryByKeyMap.clear();
mCategories = TileUtils.getCategories(context, mTileByComponentCache,
- false /* categoryDefinedInManifest */, mExtraAction);
+ false /* categoryDefinedInManifest */, mExtraAction, settingPkg);
for (DashboardCategory category : mCategories) {
mCategoryByKeyMap.put(category.key, category);
}
}
if (isDashboardFeatureEnabled()) {
final DashboardCategory homepageCategories = CategoryManager.get(this)
- .getTilesByCategory(this, CategoryKey.CATEGORY_HOMEPAGE);
- return homepageCategories.containsComponent(componentName);
+ .getTilesByCategory(this, CategoryKey.CATEGORY_HOMEPAGE, getSettingPkg());
+ return homepageCategories ==
+ null ? false : homepageCategories.containsComponent(componentName);
} else {
// Look for a tile that has the same component as incoming intent
final List<DashboardCategory> categories = getDashboardCategories();
}
}
+ /**
+ * Gets the name of the intent action of the default setting app. Used to launch setting app
+ * when Settings Home is clicked.
+ */
+ public String getSettingAction() {
+ return Settings.ACTION_SETTINGS;
+ }
+
public void addCategoryListener(CategoryListener listener) {
mCategoryListeners.add(listener);
}
}
// TODO: Do this in the background with some loading.
if (isDashboardFeatureEnabled()) {
- mDrawerAdapter.updateHomepageCategories();
+ mDrawerAdapter.updateHomepageCategories(getSettingPkg());
} else {
mDrawerAdapter.updateCategories();
}
public boolean openTile(Tile tile) {
closeDrawer();
if (tile == null) {
- startActivity(new Intent(Settings.ACTION_SETTINGS).addFlags(
- Intent.FLAG_ACTIVITY_CLEAR_TASK));
+ Intent intent = new Intent(getSettingAction()).addFlags(
+ Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
return true;
}
try {
}
}
+ public String getSettingPkg() {
+ return TileUtils.SETTING_PKG;
+ }
+
public interface CategoryListener {
void onCategoriesChanged();
}
@Override
protected Void doInBackground(Void... params) {
- mCategoryManager.reloadAllCategories(SettingsDrawerActivity.this);
+ mCategoryManager.reloadAllCategories(SettingsDrawerActivity.this, getSettingPkg());
return null;
}
}
}
+ /**
+ * @return {@code true} if IA (Information Architecture) is enabled.
+ */
protected boolean isDashboardFeatureEnabled() {
return false;
}
notifyDataSetChanged();
}
- public void updateHomepageCategories() {
+ public void updateHomepageCategories(String settingPkg) {
final DashboardCategory category = CategoryManager.get(mActivity)
- .getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE);
+ .getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE, settingPkg);
mItems.clear();
// Spacer.
mItems.add(null);
public static final String META_DATA_PREFERENCE_SUMMARY_URI =
"com.android.settings.summary_uri";
- private static final String SETTING_PKG = "com.android.settings";
+ public static final String SETTING_PKG = "com.android.settings";
/**
* Build a list of DashboardCategory. Each category must be defined in manifest.
*/
public static List<DashboardCategory> getCategories(Context context,
Map<Pair<String, String>, Tile> cache, boolean categoryDefinedInManifest) {
- return getCategories(context, cache, categoryDefinedInManifest, null);
+ return getCategories(context, cache, categoryDefinedInManifest, null, SETTING_PKG);
}
/**
* Build a list of DashboardCategory.
* @param categoryDefinedInManifest If true, an dummy activity must exists in manifest to
* represent this category (eg: .Settings$DeviceSettings)
- * @param extraAction additional intent filter action to be used to build the dashboard
+ * @param extraAction additional intent filter action to be usetileutild to build the dashboard
* categories
*/
public static List<DashboardCategory> getCategories(Context context,
Map<Pair<String, String>, Tile> cache, boolean categoryDefinedInManifest,
- String extraAction) {
+ String extraAction, String settingPkg) {
final long startTime = System.currentTimeMillis();
boolean setup = Global.getInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0)
!= 0;
ArrayList<Tile> tiles = new ArrayList<>();
- UserManager userManager = UserManager.get(context);
+ UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
for (UserHandle user : userManager.getUserProfiles()) {
// TODO: Needs much optimization, too many PM queries going on here.
if (user.getIdentifier() == ActivityManager.getCurrentUser()) {
// Only add Settings for this user.
- getTilesForAction(context, user, SETTINGS_ACTION, cache, null, tiles, true);
+ getTilesForAction(context, user, SETTINGS_ACTION, cache, null, tiles, true,
+ settingPkg);
getTilesForAction(context, user, OPERATOR_SETTINGS, cache,
- OPERATOR_DEFAULT_CATEGORY, tiles, false, true);
+ OPERATOR_DEFAULT_CATEGORY, tiles, false, true, settingPkg);
getTilesForAction(context, user, MANUFACTURER_SETTINGS, cache,
- MANUFACTURER_DEFAULT_CATEGORY, tiles, false, true);
+ MANUFACTURER_DEFAULT_CATEGORY, tiles, false, true, settingPkg);
}
if (setup) {
- getTilesForAction(context, user, EXTRA_SETTINGS_ACTION, cache, null, tiles, false);
- getTilesForAction(context, user, IA_SETTINGS_ACTION, cache, null, tiles, false);
+ getTilesForAction(context, user, EXTRA_SETTINGS_ACTION, cache, null, tiles, false,
+ settingPkg);
+ getTilesForAction(context, user, IA_SETTINGS_ACTION, cache, null, tiles, false,
+ settingPkg);
if (extraAction != null) {
- getTilesForAction(context, user, extraAction, cache, null, tiles, false);
+ getTilesForAction(context, user, extraAction, cache, null, tiles, false,
+ settingPkg);
}
}
}
private static void getTilesForAction(Context context,
UserHandle user, String action, Map<Pair<String, String>, Tile> addedCache,
- String defaultCategory, ArrayList<Tile> outTiles, boolean requireSettings) {
+ String defaultCategory, ArrayList<Tile> outTiles, boolean requireSettings,
+ String settingPkg) {
getTilesForAction(context, user, action, addedCache, defaultCategory, outTiles,
- requireSettings, requireSettings);
+ requireSettings, requireSettings, settingPkg);
}
private static void getTilesForAction(Context context,
UserHandle user, String action, Map<Pair<String, String>, Tile> addedCache,
String defaultCategory, ArrayList<Tile> outTiles, boolean requireSettings,
- boolean usePriority) {
+ boolean usePriority, String settingPkg) {
Intent intent = new Intent(action);
if (requireSettings) {
- intent.setPackage(SETTING_PKG);
+ intent.setPackage(settingPkg);
}
getTilesForIntent(context, user, intent, addedCache, defaultCategory, outTiles,
usePriority, true);
package com.android.settingslib.drawer;
+import android.app.ActivityManager;
+import static org.mockito.Mockito.verify;
import android.content.IContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.util.Pair;
import com.android.settingslib.TestConfig;
+import static org.mockito.Mockito.atLeastOnce;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.shadows.ShadowApplication;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import org.mockito.ArgumentCaptor;
+
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
List<Tile> outTiles = new ArrayList<>();
List<ResolveInfo> info = new ArrayList<>();
info.add(newInfo(true, testCategory));
-
+ Map<Pair<String, String>, Tile> cache = new ArrayMap<>();
when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
.thenReturn(info);
}), anyInt(), anyInt())).thenReturn(info);
List<DashboardCategory> categoryList = TileUtils.getCategories(
- mContext, cache, false /* categoryDefinedInManifest */, testAction);
-
+ mContext, cache, false /* categoryDefinedInManifest */, testAction,
+ TileUtils.SETTING_PKG);
assertThat(categoryList.get(0).tiles.get(0).category).isEqualTo(testCategory);
}
@Test
+ public void getCategories_withPackageName() throws Exception {
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ Map<Pair<String, String>, Tile> cache = new ArrayMap<>();
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ List<UserHandle> userHandleList = new ArrayList<>();
+
+ userHandleList.add(new UserHandle(ActivityManager.getCurrentUser()));
+ when(mUserManager.getUserProfiles()).thenReturn(userHandleList);
+
+ TileUtils.getCategories(
+ mContext, cache, false /* categoryDefinedInManifest */, null /* action */,
+ TileUtils.SETTING_PKG);
+ verify(mPackageManager, atLeastOnce()).queryIntentActivitiesAsUser(
+ intentCaptor.capture(), anyInt(), anyInt());
+
+ assertThat(intentCaptor.getAllValues().get(0).getPackage())
+ .isEqualTo(TileUtils.SETTING_PKG);
+ }
+
+ @Test
public void getTilesForIntent_shouldNotProcessInvalidUriContentSystemApp()
throws RemoteException {
Intent intent = new Intent();