/* * Copyright (C) 2017 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.enterprise; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.UserHandle; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.EnterpriseDefaultApps; import com.android.settings.applications.UserAppInfo; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.overlay.FeatureFactory; import com.android.settings.users.UserFeatureProvider; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; import java.util.Collections; import java.util.EnumMap; import java.util.List; /** * PreferenceController that builds a dynamic list of default apps set by device or profile owner. */ public class EnterpriseSetDefaultAppsListPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin { private final PackageManager mPm; private final SettingsPreferenceFragment mParent; private final ApplicationFeatureProvider mApplicationFeatureProvider; private final EnterprisePrivacyFeatureProvider mEnterprisePrivacyFeatureProvider; private final UserFeatureProvider mUserFeatureProvider; private List mUsers = Collections.emptyList(); private List>> mApps = Collections.emptyList(); public EnterpriseSetDefaultAppsListPreferenceController(Context context, SettingsPreferenceFragment parent, PackageManager packageManager) { super(context); mPm = packageManager; mParent = parent; final FeatureFactory factory = FeatureFactory.getFactory(context); mApplicationFeatureProvider = factory.getApplicationFeatureProvider(context); mEnterprisePrivacyFeatureProvider = factory.getEnterprisePrivacyFeatureProvider(context); mUserFeatureProvider = factory.getUserFeatureProvider(context); buildAppList(); } /** * Builds data for UI. Updates mUsers and mApps so that they contain non-empty list. */ private void buildAppList() { mUsers = new ArrayList<>(); mApps = new ArrayList<>(); for (UserHandle user : mUserFeatureProvider.getUserProfiles()) { boolean hasDefaultsForUser = false; EnumMap> userMap = null; for (EnterpriseDefaultApps typeOfDefault : EnterpriseDefaultApps.values()) { List apps = mApplicationFeatureProvider. findPersistentPreferredActivities(user.getIdentifier(), typeOfDefault.getIntents()); if (apps.isEmpty()) { continue; } if (!hasDefaultsForUser) { hasDefaultsForUser = true; mUsers.add(apps.get(0).userInfo); userMap = new EnumMap<>(EnterpriseDefaultApps.class); mApps.add(userMap); } ArrayList applicationInfos = new ArrayList<>(); for (UserAppInfo userAppInfo : apps) { applicationInfos.add(userAppInfo.appInfo); } userMap.put(typeOfDefault, applicationInfos); } } ThreadUtils.postOnMainThread(() -> updateUi()); } @Override public boolean isAvailable() { return true; } @Override public String getPreferenceKey() { return null; } private void updateUi() { final Context prefContext = mParent.getPreferenceManager().getContext(); final PreferenceScreen screen = mParent.getPreferenceScreen(); if (screen == null) { return; } if (!mEnterprisePrivacyFeatureProvider.isInCompMode() && mUsers.size() == 1) { createPreferences(prefContext, screen, mApps.get(0)); } else { for (int i = 0; i < mUsers.size(); i++) { final UserInfo userInfo = mUsers.get(i); final PreferenceCategory category = new PreferenceCategory(prefContext); screen.addPreference(category); if (userInfo.isManagedProfile()) { category.setTitle(R.string.category_work); } else { category.setTitle(R.string.category_personal); } category.setOrder(i); createPreferences(prefContext, category, mApps.get(i)); } } } private void createPreferences(Context prefContext, PreferenceGroup group, EnumMap> apps) { if (group == null) { return; } for (EnterpriseDefaultApps typeOfDefault : EnterpriseDefaultApps.values()) { final List appsForCategory = apps.get(typeOfDefault); if (appsForCategory == null || appsForCategory.isEmpty()) { continue; } final Preference preference = new Preference(prefContext); preference.setTitle(getTitle(prefContext, typeOfDefault, appsForCategory.size())); preference.setSummary(buildSummaryString(prefContext, appsForCategory)); preference.setOrder(typeOfDefault.ordinal()); preference.setSelectable(false); group.addPreference(preference); } } private CharSequence buildSummaryString(Context context, List apps) { final CharSequence[] appNames = new String[apps.size()]; for (int i = 0; i < apps.size(); i++) { appNames[i] = apps.get(i).loadLabel(mPm); } if (apps.size() == 1) { return appNames[0]; } else if (apps.size() == 2) { return context.getString(R.string.app_names_concatenation_template_2, appNames[0], appNames[1]); } else { return context.getString(R.string.app_names_concatenation_template_3, appNames[0], appNames[1], appNames[2]); } } private String getTitle(Context context, EnterpriseDefaultApps typeOfDefault, int appCount) { switch (typeOfDefault) { case BROWSER: return context.getString(R.string.default_browser_title); case CALENDAR: return context.getString(R.string.default_calendar_app_title); case CONTACTS: return context.getString(R.string.default_contacts_app_title); case PHONE: return context.getResources() .getQuantityString(R.plurals.default_phone_app_title, appCount); case MAP: return context.getString(R.string.default_map_app_title); case EMAIL: return context.getResources() .getQuantityString(R.plurals.default_email_app_title, appCount); case CAMERA: return context.getResources() .getQuantityString(R.plurals.default_camera_app_title, appCount); default: throw new IllegalStateException("Unknown type of default " + typeOfDefault); } } }