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