Merge "Support dynamic summary and icon for injected tiles"

This commit is contained in:
Fan Zhang
2017-08-02 21:39:56 +00:00
committed by Android (Google) Code Review
8 changed files with 239 additions and 108 deletions

View File

@@ -16,16 +16,25 @@
package com.android.settings.dashboard;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_URI;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
@@ -37,9 +46,12 @@ import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.ProfileSelectDialog;
import com.android.settingslib.drawer.SettingsDrawerActivity;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Impl for {@code DashboardFeatureProvider}.
@@ -125,14 +137,8 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
} else {
pref.setKey(getDashboardKeyForTile(tile));
}
if (tile.summary != null) {
pref.setSummary(tile.summary);
} else {
pref.setSummary(R.string.summary_placeholder);
}
if (tile.icon != null) {
pref.setIcon(tile.icon.loadDrawable(activity));
}
bindSummary(pref, tile);
bindIcon(pref, tile);
final Bundle metadata = tile.metaData;
String clsName = null;
String action = null;
@@ -206,6 +212,50 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
launchIntentOrSelectProfile(activity, tile, intent, MetricsEvent.DASHBOARD_SUMMARY);
}
private void bindSummary(Preference preference, Tile tile) {
if (tile.summary != null) {
preference.setSummary(tile.summary);
} else if (tile.metaData != null
&& tile.metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
ThreadUtils.postOnBackgroundThread(() -> {
final Map<String, IContentProvider> providerMap = new ArrayMap<>();
final String uri = tile.metaData.getString(META_DATA_PREFERENCE_SUMMARY_URI);
final String summary = TileUtils.getTextFromUri(
mContext, uri, providerMap, META_DATA_PREFERENCE_SUMMARY);
ThreadUtils.postOnMainThread(() -> preference.setSummary(summary));
});
} else {
preference.setSummary(R.string.summary_placeholder);
}
}
@VisibleForTesting
void bindIcon(Preference preference, Tile tile) {
if (tile.icon != null) {
preference.setIcon(tile.icon.loadDrawable(preference.getContext()));
} else if (tile.metaData != null
&& tile.metaData.containsKey(META_DATA_PREFERENCE_ICON_URI))
ThreadUtils.postOnBackgroundThread(() -> {
String packageName = null;
if (tile.intent != null) {
Intent intent = tile.intent;
if (!TextUtils.isEmpty(intent.getPackage())) {
packageName = intent.getPackage();
} else if (intent.getComponent() != null) {
packageName = intent.getComponent().getPackageName();
}
}
final Map<String, IContentProvider> providerMap = new ArrayMap<>();
final String uri = tile.metaData.getString(META_DATA_PREFERENCE_ICON_URI);
final Pair<String, Integer> iconInfo = TileUtils.getIconFromUri(
mContext, packageName, uri, providerMap);
tile.icon = Icon.createWithResource(iconInfo.first, iconInfo.second);
ThreadUtils.postOnMainThread(() ->
preference.setIcon(tile.icon.loadDrawable(preference.getContext()))
);
});
}
private void launchIntentOrSelectProfile(Activity activity, Tile tile, Intent intent,
int sourceMetricCategory) {
if (!isIntentResolvable(intent)) {

View File

@@ -201,7 +201,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
/**
* Returns the CategoryKey for loading {@link DashboardCategory} for this fragment.
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
@VisibleForTesting
public String getCategoryKey() {
return DashboardFragmentRegistry.PARENT_TO_CATEGORY_KEY_MAP.get(getClass().getName());
}

View File

@@ -22,8 +22,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
@@ -37,10 +35,10 @@ import com.android.settings.trustagent.TrustAgentManagerImpl;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;
import com.android.settingslib.utils.ThreadUtils;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Executors;
/** Implementation for {@code SecurityFeatureProvider}. */
public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
@@ -71,12 +69,8 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
// Fetching the summary and icon from the provider introduces latency, so do this on a
// separate thread.
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
updatePreferencesToRunOnWorkerThread(context, preferenceScreen, dashboardCategory);
}
});
ThreadUtils.postOnBackgroundThread(() ->
updatePreferencesToRunOnWorkerThread(context, preferenceScreen, dashboardCategory));
}
@VisibleForTesting
@@ -162,19 +156,16 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
sIconCache.put(iconUri, icon);
// Icon is only returned if the icon belongs to Settings or the target app.
// setIcon must be called on the UI thread.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
matchingPref.setIcon(context.getPackageManager()
.getResourcesForApplication(icon.first /* package name */)
.getDrawable(icon.second /* res id */,
context.getTheme()));
} catch (PackageManager.NameNotFoundException
| Resources.NotFoundException e) {
// Intentionally ignored. If icon resources cannot be found, do not
// update.
}
ThreadUtils.postOnMainThread(() -> {
try {
matchingPref.setIcon(context.getPackageManager()
.getResourcesForApplication(icon.first /* package name */)
.getDrawable(icon.second /* res id */,
context.getTheme()));
} catch (PackageManager.NameNotFoundException
| Resources.NotFoundException e) {
// Intentionally ignored. If icon resources cannot be found, do not
// update.
}
});
}
@@ -184,17 +175,14 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
TileUtils.META_DATA_PREFERENCE_SUMMARY);
sSummaryCache.put(summaryUri, summary);
// setSummary must be called on UI thread.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// Only update the summary if it has actually changed.
if (summary == null) {
if (matchingPref.getSummary() != null) {
matchingPref.setSummary(summary);
}
} else if (!summary.equals(matchingPref.getSummary())) {
ThreadUtils.postOnMainThread(() -> {
// Only update the summary if it has actually changed.
if (summary == null) {
if (matchingPref.getSummary() != null) {
matchingPref.setSummary(summary);
}
} else if (!summary.equals(matchingPref.getSummary())) {
matchingPref.setSummary(summary);
}
});
}