blob: ef59b3db184a3cf2b80f23053e2d8c818ad37723 [file] [log] [blame]
/*
* Copyright (C) 2018 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.car.settings.common;
import static com.android.settingslib.drawer.CategoryKey.CATEGORY_DEVICE;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.preference.Preference;
import com.android.car.apps.common.util.Themes;
import com.android.car.settings.R;
import com.android.car.ui.preference.CarUiPreference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Loads Activity with TileUtils.EXTRA_SETTINGS_ACTION.
*/
// TODO: investigate using SettingsLib Tiles.
public class ExtraSettingsLoader {
private static final Logger LOG = new Logger(ExtraSettingsLoader.class);
private static final String META_DATA_PREFERENCE_CATEGORY = "com.android.settings.category";
private Map<Preference, Bundle> mPreferenceBundleMap;
private final Context mContext;
public ExtraSettingsLoader(Context context) {
mContext = context;
mPreferenceBundleMap = new HashMap<>();
}
/**
* Returns a map of {@link Preference} and {@link Bundle} representing settings injected from
* system apps and their metadata. The given intent must specify the action to use for
* resolving activities and a category with the key "com.android.settings.category" and one of
* the values in {@link com.android.settingslib.drawer.CategoryKey}.
*
* @param intent intent specifying the extra settings category to load
*/
public Map<Preference, Bundle> loadPreferences(Intent intent) {
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
PackageManager.GET_META_DATA, ActivityManager.getCurrentUser());
String extraCategory = intent.getStringExtra(META_DATA_PREFERENCE_CATEGORY);
for (ResolveInfo resolved : results) {
if (!resolved.system) {
// Do not allow any app to be added to settings, only system ones.
continue;
}
String title = null;
String summary = null;
String category = null;
ActivityInfo activityInfo = resolved.activityInfo;
Bundle metaData = activityInfo.metaData;
try {
Resources res = pm.getResourcesForApplication(activityInfo.packageName);
if (metaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
} else {
title = metaData.getString(META_DATA_PREFERENCE_TITLE);
}
}
if (TextUtils.isEmpty(title)) {
LOG.d("no title.");
title = activityInfo.loadLabel(pm).toString();
}
if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY)) {
if (metaData.get(META_DATA_PREFERENCE_SUMMARY) instanceof Integer) {
summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
} else {
summary = metaData.getString(META_DATA_PREFERENCE_SUMMARY);
}
} else {
LOG.d("no description.");
}
if (metaData.containsKey(META_DATA_PREFERENCE_CATEGORY)) {
if (metaData.get(META_DATA_PREFERENCE_CATEGORY) instanceof Integer) {
category = res.getString(metaData.getInt(META_DATA_PREFERENCE_CATEGORY));
} else {
category = metaData.getString(META_DATA_PREFERENCE_CATEGORY);
}
} else {
LOG.d("no category.");
}
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
LOG.d("Couldn't find info", e);
}
Icon icon = null;
if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
int iconRes = metaData.getInt(META_DATA_PREFERENCE_ICON);
icon = Icon.createWithResource(activityInfo.packageName, iconRes);
} else {
icon = Icon.createWithResource(mContext, R.drawable.ic_settings_gear);
LOG.d("use default icon.");
}
Intent extraSettingIntent =
new Intent().setClassName(activityInfo.packageName, activityInfo.name);
if (category == null) {
// If category is not specified or not supported, default to device.
category = CATEGORY_DEVICE;
}
if (!TextUtils.equals(extraCategory, category)) {
continue;
}
CarUiPreference preference = new CarUiPreference(mContext);
preference.setTitle(title);
preference.setSummary(summary);
if (icon != null) {
preference.setIcon(icon.loadDrawable(mContext));
preference.getIcon().setTintList(
Themes.getAttrColorStateList(mContext, R.attr.iconColor));
}
preference.setIntent(extraSettingIntent);
mPreferenceBundleMap.put(preference, metaData);
}
return mPreferenceBundleMap;
}
}