• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.permissioncontroller.role.model;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.pm.PackageManager;
22 import android.content.pm.ResolveInfo;
23 import android.net.Uri;
24 import android.os.Process;
25 import android.os.UserHandle;
26 import android.util.ArraySet;
27 
28 import androidx.annotation.NonNull;
29 import androidx.annotation.Nullable;
30 
31 import com.android.permissioncontroller.R;
32 import com.android.permissioncontroller.role.utils.UserUtils;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 /**
38  * Class for behavior of the browser role.
39  *
40  * @see com.android.settings.applications.DefaultAppSettings
41  * @see com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController
42  * @see com.android.settings.applications.defaultapps.DefaultBrowserPicker
43  * @see com.android.server.pm.PackageManagerService#resolveAllBrowserApps(int)
44  */
45 public class BrowserRoleBehavior implements RoleBehavior {
46 
47     private static final Intent BROWSER_INTENT = new Intent()
48             .setAction(Intent.ACTION_VIEW)
49             .addCategory(Intent.CATEGORY_BROWSABLE)
50             .setData(Uri.fromParts("http", "", null));
51 
52     @Nullable
53     @Override
getFallbackHolder(@onNull Role role, @NonNull Context context)54     public String getFallbackHolder(@NonNull Role role, @NonNull Context context) {
55         List<String> packageNames = role.getQualifyingPackagesAsUser(Process.myUserHandle(),
56                 context);
57         if (packageNames.size() == 1) {
58             return packageNames.get(0);
59         }
60         return null;
61     }
62 
63     // PackageManager.queryIntentActivities() will only return the default browser if one was set.
64     // Code in the Settings app passes PackageManager.MATCH_ALL and perform its own filtering, so we
65     // do the same thing here.
66     @Nullable
67     @Override
getQualifyingPackagesAsUser(@onNull Role role, @NonNull UserHandle user, @NonNull Context context)68     public List<String> getQualifyingPackagesAsUser(@NonNull Role role, @NonNull UserHandle user,
69             @NonNull Context context) {
70         return getQualifyingPackagesAsUserInternal(null, user, context);
71     }
72 
73     @Nullable
74     @Override
isPackageQualified(@onNull Role role, @NonNull String packageName, @NonNull Context context)75     public Boolean isPackageQualified(@NonNull Role role, @NonNull String packageName,
76             @NonNull Context context) {
77         List<String> packageNames = getQualifyingPackagesAsUserInternal(packageName,
78                 Process.myUserHandle(), context);
79         return !packageNames.isEmpty();
80     }
81 
82     @NonNull
getQualifyingPackagesAsUserInternal(@ullable String packageName, @NonNull UserHandle user, @NonNull Context context)83     private List<String> getQualifyingPackagesAsUserInternal(@Nullable String packageName,
84             @NonNull UserHandle user, @NonNull Context context) {
85         Context userContext = UserUtils.getUserContext(context, user);
86         PackageManager userPackageManager = userContext.getPackageManager();
87         Intent intent = BROWSER_INTENT;
88         if (packageName != null) {
89             intent = new Intent(intent)
90                     .setPackage(packageName);
91         }
92         List<ResolveInfo> resolveInfos = userPackageManager.queryIntentActivities(intent,
93                 // To one's surprise, MATCH_ALL doesn't include MATCH_DIRECT_BOOT_*.
94                 PackageManager.MATCH_ALL | PackageManager.MATCH_DIRECT_BOOT_AWARE
95                         | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
96         ArraySet<String> packageNames = new ArraySet<>();
97         int resolveInfosSize = resolveInfos.size();
98         for (int i = 0; i < resolveInfosSize; i++) {
99             ResolveInfo resolveInfo = resolveInfos.get(i);
100 
101             if (!resolveInfo.handleAllWebDataURI) {
102                 continue;
103             }
104             packageNames.add(resolveInfo.activityInfo.packageName);
105         }
106         return new ArrayList<>(packageNames);
107     }
108 
109     @Override
isVisibleAsUser(@onNull Role role, @NonNull UserHandle user, @NonNull Context context)110     public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user,
111             @NonNull Context context) {
112         return context.getResources().getBoolean(R.bool.config_showBrowserRole);
113     }
114 }
115