17ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk/*
27ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk * Copyright (C) 2016 The Android Open Source Project
37ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk *
47ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
57ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk * except in compliance with the License. You may obtain a copy of the License at
67ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk *
77ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk *      http://www.apache.org/licenses/LICENSE-2.0
87ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk *
97ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk * Unless required by applicable law or agreed to in writing, software distributed under the
107ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
117ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk * KIND, either express or implied. See the License for the specific language governing
127ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk * permissions and limitations under the License.
137ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk */
147ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
157ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkpackage com.android.settings.applications;
167ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
177ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.ComponentName;
187ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.Context;
197ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.Intent;
207ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.IntentFilter;
217ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.pm.ActivityInfo;
227ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.pm.ApplicationInfo;
237ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.pm.PackageManager;
247ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.pm.ResolveInfo;
257ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.content.pm.UserInfo;
267ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.os.Build;
277ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.os.UserManager;
287ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport android.util.AttributeSet;
29233daf469da553474338f485661419db695075d7Fan Zhang
307ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport com.android.settings.AppListPreference;
317ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport com.android.settings.R;
327ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
337ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport java.util.ArrayList;
347ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkimport java.util.List;
357ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
367ea14c5625c988a81c09625f54faed846fc07ec7Jason Monkpublic class DefaultHomePreference extends AppListPreference {
377ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
387ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    private final ArrayList<ComponentName> mAllHomeComponents = new ArrayList<>();
397ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    private final IntentFilter mHomeFilter;
40233daf469da553474338f485661419db695075d7Fan Zhang    private final String mPackageName;
417ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
427ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    public DefaultHomePreference(Context context, AttributeSet attrs) {
437ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        super(context, attrs);
44233daf469da553474338f485661419db695075d7Fan Zhang        mPackageName = getContext().getPackageName();
457ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        mHomeFilter = new IntentFilter(Intent.ACTION_MAIN);
467ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        mHomeFilter.addCategory(Intent.CATEGORY_HOME);
477ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        mHomeFilter.addCategory(Intent.CATEGORY_DEFAULT);
487ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        refreshHomeOptions();
497ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    }
507ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
517ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    @Override
527ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    public void performClick() {
537ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        refreshHomeOptions();
547ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        super.performClick();
557ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    }
567ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
577ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    @Override
587ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    protected boolean persistString(String value) {
597ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        if (value != null) {
607ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            ComponentName component = ComponentName.unflattenFromString(value);
617ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            getContext().getPackageManager().replacePreferredActivity(mHomeFilter,
627ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk                    IntentFilter.MATCH_CATEGORY_EMPTY,
637ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk                    mAllHomeComponents.toArray(new ComponentName[0]), component);
647ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            setSummary(getEntry());
65233daf469da553474338f485661419db695075d7Fan Zhang        } else {
66233daf469da553474338f485661419db695075d7Fan Zhang            // If there is only 1 launcher, use its label as summary text.
67233daf469da553474338f485661419db695075d7Fan Zhang            setSoleAppLabelAsSummary();
687ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        }
697ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        return super.persistString(value);
707ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    }
717ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
72233daf469da553474338f485661419db695075d7Fan Zhang    @Override
73233daf469da553474338f485661419db695075d7Fan Zhang    protected CharSequence getSoleAppLabel() {
74233daf469da553474338f485661419db695075d7Fan Zhang        final PackageManager pm = getContext().getPackageManager();
75233daf469da553474338f485661419db695075d7Fan Zhang        final List<ResolveInfo> homeActivities = new ArrayList<>();
76233daf469da553474338f485661419db695075d7Fan Zhang        final List<CharSequence> appLabels = new ArrayList<>();
77233daf469da553474338f485661419db695075d7Fan Zhang
78233daf469da553474338f485661419db695075d7Fan Zhang        pm.getHomeActivities(homeActivities);
79233daf469da553474338f485661419db695075d7Fan Zhang        for (ResolveInfo candidate : homeActivities) {
80233daf469da553474338f485661419db695075d7Fan Zhang            final ActivityInfo info = candidate.activityInfo;
81233daf469da553474338f485661419db695075d7Fan Zhang            if (info.packageName.equals(mPackageName)) {
82233daf469da553474338f485661419db695075d7Fan Zhang                continue;
83233daf469da553474338f485661419db695075d7Fan Zhang            }
84233daf469da553474338f485661419db695075d7Fan Zhang            appLabels.add(info.loadLabel(pm));
85233daf469da553474338f485661419db695075d7Fan Zhang        }
86233daf469da553474338f485661419db695075d7Fan Zhang        return appLabels.size() == 1 ? appLabels.get(0) : null;
87233daf469da553474338f485661419db695075d7Fan Zhang    }
88233daf469da553474338f485661419db695075d7Fan Zhang
897ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    public void refreshHomeOptions() {
90233daf469da553474338f485661419db695075d7Fan Zhang        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
917ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        PackageManager pm = getContext().getPackageManager();
92233daf469da553474338f485661419db695075d7Fan Zhang        ComponentName currentDefaultHome = pm.getHomeActivities(homeActivities);
937ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        ArrayList<ComponentName> components = new ArrayList<>();
947ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        mAllHomeComponents.clear();
957ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        List<CharSequence> summaries = new ArrayList<>();
967ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
977ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        boolean mustSupportManagedProfile = hasManagedProfile();
98233daf469da553474338f485661419db695075d7Fan Zhang        for (ResolveInfo candidate : homeActivities) {
997ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            final ActivityInfo info = candidate.activityInfo;
1007ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            ComponentName activityName = new ComponentName(info.packageName, info.name);
1017ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            mAllHomeComponents.add(activityName);
102233daf469da553474338f485661419db695075d7Fan Zhang            if (info.packageName.equals(mPackageName)) {
1037ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk                continue;
1047ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            }
1057ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            components.add(activityName);
1067ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            if (mustSupportManagedProfile && !launcherHasManagedProfilesFeature(candidate, pm)) {
1077ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk                summaries.add(getContext().getString(R.string.home_work_profile_not_supported));
1087ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            } else {
1097ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk                summaries.add(null);
1107ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            }
1117ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        }
1127ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        setComponentNames(components.toArray(new ComponentName[0]), currentDefaultHome,
1137ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk                summaries.toArray(new CharSequence[0]));
1147ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    }
1157ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
1167ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    private boolean launcherHasManagedProfilesFeature(ResolveInfo resolveInfo, PackageManager pm) {
1177ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        try {
1187ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            ApplicationInfo appInfo = pm.getApplicationInfo(
1197ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk                    resolveInfo.activityInfo.packageName, 0 /* default flags */);
1207ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            return versionNumberAtLeastL(appInfo.targetSdkVersion);
1217ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        } catch (PackageManager.NameNotFoundException e) {
1227ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            return false;
1237ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        }
1247ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    }
1257ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
1267ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    private boolean versionNumberAtLeastL(int versionNumber) {
1277ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        return versionNumber >= Build.VERSION_CODES.LOLLIPOP;
1287ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    }
1297ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk
1307ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    private boolean hasManagedProfile() {
1317ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        UserManager userManager = getContext().getSystemService(UserManager.class);
1327ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        List<UserInfo> profiles = userManager.getProfiles(getContext().getUserId());
1337ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        for (UserInfo userInfo : profiles) {
1347ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk            if (userInfo.isManagedProfile()) return true;
1357ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        }
1367ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk        return false;
1377ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk    }
1382108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk
1392108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk    public static boolean hasHomePreference(String pkg, Context context) {
1402108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
1412108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        PackageManager pm = context.getPackageManager();
1422108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        pm.getHomeActivities(homeActivities);
1432108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        for (int i = 0; i < homeActivities.size(); i++) {
1442108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk            if (homeActivities.get(i).activityInfo.packageName.equals(pkg)) {
1452108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk                return true;
1462108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk            }
1472108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        }
1482108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        return false;
1492108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk    }
1502108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk
1512108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk    public static boolean isHomeDefault(String pkg, Context context) {
1522108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
1532108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        PackageManager pm = context.getPackageManager();
1542108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        ComponentName def = pm.getHomeActivities(homeActivities);
1552108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk
1562108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk        return def != null && def.getPackageName().equals(pkg);
1572108d361bb1c4113d2250711d9ac8e6bc0de9245Jason Monk    }
1587ea14c5625c988a81c09625f54faed846fc07ec7Jason Monk}
159