Home | History | Annotate | Download | only in enterprise
      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.UserHandle;
     24 import android.support.v7.preference.Preference;
     25 import android.support.v7.preference.PreferenceCategory;
     26 import android.support.v7.preference.PreferenceGroup;
     27 import android.support.v7.preference.PreferenceScreen;
     28 
     29 import com.android.settings.R;
     30 import com.android.settings.SettingsPreferenceFragment;
     31 import com.android.settings.applications.ApplicationFeatureProvider;
     32 import com.android.settings.applications.EnterpriseDefaultApps;
     33 import com.android.settings.applications.UserAppInfo;
     34 import com.android.settings.core.PreferenceControllerMixin;
     35 import com.android.settings.overlay.FeatureFactory;
     36 import com.android.settings.users.UserFeatureProvider;
     37 import com.android.settingslib.core.AbstractPreferenceController;
     38 import com.android.settingslib.utils.ThreadUtils;
     39 
     40 import java.util.ArrayList;
     41 import java.util.Collections;
     42 import java.util.EnumMap;
     43 import java.util.List;
     44 
     45 
     46 /**
     47  * PreferenceController that builds a dynamic list of default apps set by device or profile owner.
     48  */
     49 public class EnterpriseSetDefaultAppsListPreferenceController extends
     50         AbstractPreferenceController implements PreferenceControllerMixin {
     51     private final PackageManager mPm;
     52     private final SettingsPreferenceFragment mParent;
     53     private final ApplicationFeatureProvider mApplicationFeatureProvider;
     54     private final EnterprisePrivacyFeatureProvider mEnterprisePrivacyFeatureProvider;
     55     private final UserFeatureProvider mUserFeatureProvider;
     56 
     57     private List<UserInfo> mUsers = Collections.emptyList();
     58     private List<EnumMap<EnterpriseDefaultApps, List<ApplicationInfo>>> mApps =
     59             Collections.emptyList();
     60 
     61     public EnterpriseSetDefaultAppsListPreferenceController(Context context,
     62             SettingsPreferenceFragment parent, PackageManager packageManager) {
     63         super(context);
     64         mPm = packageManager;
     65         mParent = parent;
     66         final FeatureFactory factory = FeatureFactory.getFactory(context);
     67         mApplicationFeatureProvider = factory.getApplicationFeatureProvider(context);
     68         mEnterprisePrivacyFeatureProvider = factory.getEnterprisePrivacyFeatureProvider(context);
     69         mUserFeatureProvider = factory.getUserFeatureProvider(context);
     70         buildAppList();
     71     }
     72 
     73     /**
     74      * Builds data for UI. Updates mUsers and mApps so that they contain non-empty list.
     75      */
     76     private void buildAppList() {
     77         mUsers = new ArrayList<>();
     78         mApps = new ArrayList<>();
     79         for (UserHandle user : mUserFeatureProvider.getUserProfiles()) {
     80             boolean hasDefaultsForUser = false;
     81             EnumMap<EnterpriseDefaultApps, List<ApplicationInfo>> userMap = null;
     82 
     83             for (EnterpriseDefaultApps typeOfDefault : EnterpriseDefaultApps.values()) {
     84                 List<UserAppInfo> apps = mApplicationFeatureProvider.
     85                         findPersistentPreferredActivities(user.getIdentifier(),
     86                                 typeOfDefault.getIntents());
     87                 if (apps.isEmpty()) {
     88                     continue;
     89                 }
     90                 if (!hasDefaultsForUser) {
     91                     hasDefaultsForUser = true;
     92                     mUsers.add(apps.get(0).userInfo);
     93                     userMap = new EnumMap<>(EnterpriseDefaultApps.class);
     94                     mApps.add(userMap);
     95                 }
     96                 ArrayList<ApplicationInfo> applicationInfos = new ArrayList<>();
     97                 for (UserAppInfo userAppInfo : apps) {
     98                     applicationInfos.add(userAppInfo.appInfo);
     99                 }
    100                 userMap.put(typeOfDefault, applicationInfos);
    101             }
    102         }
    103         ThreadUtils.postOnMainThread(() -> updateUi());
    104     }
    105 
    106     @Override
    107     public boolean isAvailable() {
    108         return true;
    109     }
    110 
    111     @Override
    112     public String getPreferenceKey() {
    113         return null;
    114     }
    115 
    116     private void updateUi() {
    117         final Context prefContext = mParent.getPreferenceManager().getContext();
    118         final PreferenceScreen screen = mParent.getPreferenceScreen();
    119         if (screen == null) {
    120             return;
    121         }
    122         if (!mEnterprisePrivacyFeatureProvider.isInCompMode() && mUsers.size() == 1) {
    123             createPreferences(prefContext, screen, mApps.get(0));
    124         } else {
    125             for (int i = 0; i < mUsers.size(); i++) {
    126                 final UserInfo userInfo = mUsers.get(i);
    127                 final PreferenceCategory category = new PreferenceCategory(prefContext);
    128                 screen.addPreference(category);
    129                 if (userInfo.isManagedProfile()) {
    130                     category.setTitle(R.string.managed_device_admin_title);
    131                 } else {
    132                     category.setTitle(R.string.personal_device_admin_title);
    133                 }
    134                 category.setOrder(i);
    135                 createPreferences(prefContext, category, mApps.get(i));
    136             }
    137         }
    138     }
    139 
    140     private void createPreferences(Context prefContext, PreferenceGroup group,
    141             EnumMap<EnterpriseDefaultApps, List<ApplicationInfo>> apps) {
    142         if (group == null) {
    143             return;
    144         }
    145         for (EnterpriseDefaultApps typeOfDefault : EnterpriseDefaultApps.values()) {
    146             final List<ApplicationInfo> appsForCategory = apps.get(typeOfDefault);
    147             if (appsForCategory == null || appsForCategory.isEmpty()) {
    148                 continue;
    149             }
    150             final Preference preference = new Preference(prefContext);
    151             preference.setTitle(getTitle(prefContext, typeOfDefault, appsForCategory.size()));
    152             preference.setSummary(buildSummaryString(prefContext, appsForCategory));
    153             preference.setOrder(typeOfDefault.ordinal());
    154             preference.setSelectable(false);
    155             group.addPreference(preference);
    156         }
    157     }
    158 
    159     private CharSequence buildSummaryString(Context context, List<ApplicationInfo> apps) {
    160         final CharSequence[] appNames = new String[apps.size()];
    161         for (int i = 0; i < apps.size(); i++) {
    162             appNames[i] = apps.get(i).loadLabel(mPm);
    163         }
    164         if (apps.size() == 1) {
    165             return appNames[0];
    166         } else if (apps.size() == 2) {
    167             return context.getString(R.string.app_names_concatenation_template_2, appNames[0],
    168                     appNames[1]);
    169         } else {
    170             return context.getString(R.string.app_names_concatenation_template_3, appNames[0],
    171                     appNames[1], appNames[2]);
    172         }
    173     }
    174 
    175     private String getTitle(Context context, EnterpriseDefaultApps typeOfDefault, int appCount) {
    176         switch (typeOfDefault) {
    177             case BROWSER:
    178                 return context.getString(R.string.default_browser_title);
    179             case CALENDAR:
    180                 return context.getString(R.string.default_calendar_app_title);
    181             case CONTACTS:
    182                 return context.getString(R.string.default_contacts_app_title);
    183             case PHONE:
    184                 return context.getResources()
    185                         .getQuantityString(R.plurals.default_phone_app_title, appCount);
    186             case MAP:
    187                 return context.getString(R.string.default_map_app_title);
    188             case EMAIL:
    189                 return context.getResources()
    190                         .getQuantityString(R.plurals.default_email_app_title, appCount);
    191             case CAMERA:
    192                 return context.getResources()
    193                         .getQuantityString(R.plurals.default_camera_app_title, appCount);
    194             default:
    195                 throw new IllegalStateException("Unknown type of default " + typeOfDefault);
    196         }
    197     }
    198 
    199 }
    200