1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15package com.android.settings.applications; 16 17import android.content.ComponentName; 18import android.content.Context; 19import android.content.Intent; 20import android.content.IntentFilter; 21import android.content.pm.ActivityInfo; 22import android.content.pm.ApplicationInfo; 23import android.content.pm.PackageManager; 24import android.content.pm.ResolveInfo; 25import android.content.pm.UserInfo; 26import android.os.Build; 27import android.os.UserManager; 28import android.util.AttributeSet; 29 30import com.android.settings.AppListPreference; 31import com.android.settings.R; 32 33import java.util.ArrayList; 34import java.util.List; 35 36public class DefaultHomePreference extends AppListPreference { 37 38 private final ArrayList<ComponentName> mAllHomeComponents = new ArrayList<>(); 39 private final IntentFilter mHomeFilter; 40 private final String mPackageName; 41 42 public DefaultHomePreference(Context context, AttributeSet attrs) { 43 super(context, attrs); 44 mPackageName = getContext().getPackageName(); 45 mHomeFilter = new IntentFilter(Intent.ACTION_MAIN); 46 mHomeFilter.addCategory(Intent.CATEGORY_HOME); 47 mHomeFilter.addCategory(Intent.CATEGORY_DEFAULT); 48 refreshHomeOptions(); 49 } 50 51 @Override 52 public void performClick() { 53 refreshHomeOptions(); 54 super.performClick(); 55 } 56 57 @Override 58 protected boolean persistString(String value) { 59 if (value != null) { 60 ComponentName component = ComponentName.unflattenFromString(value); 61 getContext().getPackageManager().replacePreferredActivity(mHomeFilter, 62 IntentFilter.MATCH_CATEGORY_EMPTY, 63 mAllHomeComponents.toArray(new ComponentName[0]), component); 64 setSummary(getEntry()); 65 } else { 66 // If there is only 1 launcher, use its label as summary text. 67 setSoleAppLabelAsSummary(); 68 } 69 return super.persistString(value); 70 } 71 72 @Override 73 protected CharSequence getSoleAppLabel() { 74 final PackageManager pm = getContext().getPackageManager(); 75 final List<ResolveInfo> homeActivities = new ArrayList<>(); 76 final List<CharSequence> appLabels = new ArrayList<>(); 77 78 pm.getHomeActivities(homeActivities); 79 for (ResolveInfo candidate : homeActivities) { 80 final ActivityInfo info = candidate.activityInfo; 81 if (info.packageName.equals(mPackageName)) { 82 continue; 83 } 84 appLabels.add(info.loadLabel(pm)); 85 } 86 return appLabels.size() == 1 ? appLabels.get(0) : null; 87 } 88 89 public void refreshHomeOptions() { 90 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 91 PackageManager pm = getContext().getPackageManager(); 92 ComponentName currentDefaultHome = pm.getHomeActivities(homeActivities); 93 ArrayList<ComponentName> components = new ArrayList<>(); 94 mAllHomeComponents.clear(); 95 List<CharSequence> summaries = new ArrayList<>(); 96 97 boolean mustSupportManagedProfile = hasManagedProfile(); 98 for (ResolveInfo candidate : homeActivities) { 99 final ActivityInfo info = candidate.activityInfo; 100 ComponentName activityName = new ComponentName(info.packageName, info.name); 101 mAllHomeComponents.add(activityName); 102 if (info.packageName.equals(mPackageName)) { 103 continue; 104 } 105 components.add(activityName); 106 if (mustSupportManagedProfile && !launcherHasManagedProfilesFeature(candidate, pm)) { 107 summaries.add(getContext().getString(R.string.home_work_profile_not_supported)); 108 } else { 109 summaries.add(null); 110 } 111 } 112 setComponentNames(components.toArray(new ComponentName[0]), currentDefaultHome, 113 summaries.toArray(new CharSequence[0])); 114 } 115 116 private boolean launcherHasManagedProfilesFeature(ResolveInfo resolveInfo, PackageManager pm) { 117 try { 118 ApplicationInfo appInfo = pm.getApplicationInfo( 119 resolveInfo.activityInfo.packageName, 0 /* default flags */); 120 return versionNumberAtLeastL(appInfo.targetSdkVersion); 121 } catch (PackageManager.NameNotFoundException e) { 122 return false; 123 } 124 } 125 126 private boolean versionNumberAtLeastL(int versionNumber) { 127 return versionNumber >= Build.VERSION_CODES.LOLLIPOP; 128 } 129 130 private boolean hasManagedProfile() { 131 UserManager userManager = getContext().getSystemService(UserManager.class); 132 List<UserInfo> profiles = userManager.getProfiles(getContext().getUserId()); 133 for (UserInfo userInfo : profiles) { 134 if (userInfo.isManagedProfile()) return true; 135 } 136 return false; 137 } 138 139 public static boolean hasHomePreference(String pkg, Context context) { 140 ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); 141 PackageManager pm = context.getPackageManager(); 142 pm.getHomeActivities(homeActivities); 143 for (int i = 0; i < homeActivities.size(); i++) { 144 if (homeActivities.get(i).activityInfo.packageName.equals(pkg)) { 145 return true; 146 } 147 } 148 return false; 149 } 150 151 public static boolean isHomeDefault(String pkg, Context context) { 152 ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); 153 PackageManager pm = context.getPackageManager(); 154 ComponentName def = pm.getHomeActivities(homeActivities); 155 156 return def != null && def.getPackageName().equals(pkg); 157 } 158} 159