1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.settings.enterprise; 18 19 import android.content.Context; 20 import android.content.pm.ApplicationInfo; 21 import android.content.pm.PackageManager; 22 import android.content.pm.UserInfo; 23 import android.os.Handler; 24 import android.os.UserHandle; 25 import android.support.v7.preference.Preference; 26 import android.support.v7.preference.PreferenceCategory; 27 import android.support.v7.preference.PreferenceGroup; 28 import android.support.v7.preference.PreferenceScreen; 29 30 import com.android.settings.R; 31 import com.android.settings.SettingsPreferenceFragment; 32 import com.android.settings.applications.ApplicationFeatureProvider; 33 import com.android.settings.applications.EnterpriseDefaultApps; 34 import com.android.settings.applications.UserAppInfo; 35 import com.android.settings.core.PreferenceController; 36 import com.android.settings.overlay.FeatureFactory; 37 import com.android.settings.users.UserFeatureProvider; 38 39 import java.util.ArrayList; 40 import java.util.Collections; 41 import java.util.EnumMap; 42 import java.util.List; 43 44 45 /** 46 * PreferenceController that builds a dynamic list of default apps set by device or profile owner. 47 */ 48 public class EnterpriseSetDefaultAppsListPreferenceController extends PreferenceController { 49 private final PackageManager mPm; 50 private final SettingsPreferenceFragment mParent; 51 private final ApplicationFeatureProvider mApplicationFeatureProvider; 52 private final EnterprisePrivacyFeatureProvider mEnterprisePrivacyFeatureProvider; 53 private final UserFeatureProvider mUserFeatureProvider; 54 55 private List<UserInfo> mUsers = Collections.emptyList(); 56 private List<EnumMap<EnterpriseDefaultApps, List<ApplicationInfo>>> mApps = 57 Collections.emptyList(); 58 EnterpriseSetDefaultAppsListPreferenceController(Context context, SettingsPreferenceFragment parent, PackageManager packageManager)59 public EnterpriseSetDefaultAppsListPreferenceController(Context context, 60 SettingsPreferenceFragment parent, PackageManager packageManager) { 61 super(context); 62 mPm = packageManager; 63 mParent = parent; 64 final FeatureFactory factory = FeatureFactory.getFactory(context); 65 mApplicationFeatureProvider = factory.getApplicationFeatureProvider(context); 66 mEnterprisePrivacyFeatureProvider = factory.getEnterprisePrivacyFeatureProvider(context); 67 mUserFeatureProvider = factory.getUserFeatureProvider(context); 68 buildAppList(); 69 } 70 71 /** 72 * Builds data for UI. Updates mUsers and mApps so that they contain non-empty list. 73 */ buildAppList()74 private void buildAppList() { 75 mUsers = new ArrayList<>(); 76 mApps = new ArrayList<>(); 77 for (UserHandle user : mUserFeatureProvider.getUserProfiles()) { 78 boolean hasDefaultsForUser = false; 79 EnumMap<EnterpriseDefaultApps, List<ApplicationInfo>> userMap = null; 80 81 for (EnterpriseDefaultApps typeOfDefault : EnterpriseDefaultApps.values()) { 82 List<UserAppInfo> apps = mApplicationFeatureProvider. 83 findPersistentPreferredActivities(user.getIdentifier(), 84 typeOfDefault.getIntents()); 85 if (apps.isEmpty()) { 86 continue; 87 } 88 if (!hasDefaultsForUser) { 89 hasDefaultsForUser = true; 90 mUsers.add(apps.get(0).userInfo); 91 userMap = new EnumMap<>(EnterpriseDefaultApps.class); 92 mApps.add(userMap); 93 } 94 ArrayList<ApplicationInfo> applicationInfos = new ArrayList<>(); 95 for (UserAppInfo userAppInfo : apps) { 96 applicationInfos.add(userAppInfo.appInfo); 97 } 98 userMap.put(typeOfDefault, applicationInfos); 99 } 100 } 101 new Handler(mContext.getMainLooper()).post(() -> { updateUi(); }); 102 } 103 104 @Override isAvailable()105 public boolean isAvailable() { 106 return true; 107 } 108 109 @Override getPreferenceKey()110 public String getPreferenceKey() { 111 return null; 112 } 113 updateUi()114 private void updateUi() { 115 final Context prefContext = mParent.getPreferenceManager().getContext(); 116 final PreferenceScreen screen = mParent.getPreferenceScreen(); 117 if (screen == null) { 118 return; 119 } 120 if (!mEnterprisePrivacyFeatureProvider.isInCompMode() && mUsers.size() == 1) { 121 createPreferences(prefContext, screen, mApps.get(0)); 122 } else { 123 for (int i = 0; i < mUsers.size(); i++) { 124 final UserInfo userInfo = mUsers.get(i); 125 final PreferenceCategory category = new PreferenceCategory(prefContext); 126 screen.addPreference(category); 127 if (userInfo.isManagedProfile()) { 128 category.setTitle(R.string.managed_device_admin_title); 129 } else { 130 category.setTitle(R.string.personal_device_admin_title); 131 } 132 category.setOrder(i); 133 createPreferences(prefContext, category, mApps.get(i)); 134 } 135 } 136 } 137 createPreferences(Context prefContext, PreferenceGroup group, EnumMap<EnterpriseDefaultApps, List<ApplicationInfo>> apps)138 private void createPreferences(Context prefContext, PreferenceGroup group, 139 EnumMap<EnterpriseDefaultApps, List<ApplicationInfo>> apps) { 140 if (group == null) { 141 return; 142 } 143 for (EnterpriseDefaultApps typeOfDefault : EnterpriseDefaultApps.values()) { 144 final List<ApplicationInfo> appsForCategory = apps.get(typeOfDefault); 145 if (appsForCategory == null || appsForCategory.isEmpty()) { 146 continue; 147 } 148 final Preference preference = new Preference(prefContext); 149 preference.setTitle(getTitle(prefContext, typeOfDefault, appsForCategory.size())); 150 preference.setSummary(buildSummaryString(prefContext, appsForCategory)); 151 preference.setOrder(typeOfDefault.ordinal()); 152 preference.setSelectable(false); 153 group.addPreference(preference); 154 } 155 } 156 buildSummaryString(Context context, List<ApplicationInfo> apps)157 private CharSequence buildSummaryString(Context context, List<ApplicationInfo> apps) { 158 final CharSequence[] appNames = new String[apps.size()]; 159 for (int i = 0; i < apps.size(); i++) { 160 appNames[i] = apps.get(i).loadLabel(mPm); 161 } 162 if (apps.size() == 1) { 163 return appNames[0]; 164 } else if (apps.size() == 2) { 165 return context.getString(R.string.app_names_concatenation_template_2, appNames[0], 166 appNames[1]); 167 } else { 168 return context.getString(R.string.app_names_concatenation_template_3, appNames[0], 169 appNames[1], appNames[2]); 170 } 171 } 172 getTitle(Context context, EnterpriseDefaultApps typeOfDefault, int appCount)173 private String getTitle(Context context, EnterpriseDefaultApps typeOfDefault, int appCount) { 174 switch (typeOfDefault) { 175 case BROWSER: 176 return context.getString(R.string.default_browser_title); 177 case CALENDAR: 178 return context.getString(R.string.default_calendar_app_title); 179 case CONTACTS: 180 return context.getString(R.string.default_contacts_app_title); 181 case PHONE: 182 return context.getResources() 183 .getQuantityString(R.plurals.default_phone_app_title, appCount); 184 case MAP: 185 return context.getString(R.string.default_map_app_title); 186 case EMAIL: 187 return context.getResources() 188 .getQuantityString(R.plurals.default_email_app_title, appCount); 189 case CAMERA: 190 return context.getResources() 191 .getQuantityString(R.plurals.default_camera_app_title, appCount); 192 default: 193 throw new IllegalStateException("Unknown type of default " + typeOfDefault); 194 } 195 } 196 197 } 198