blob: a8da818932fa0473fc95f9d615f5f5ad3aa0a11b [file] [log] [blame]
Aurimas Liutikas88c7ff12023-08-10 12:42:26 -07001/*
2 * Copyright (C) 2022 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
17package com.android.server.pm;
18
19import android.content.Intent;
20import android.content.pm.ActivityInfo;
21import android.content.pm.ResolveInfo;
22import android.content.pm.UserInfo;
23import android.os.Binder;
24import android.os.UserHandle;
25
26import com.android.internal.util.CollectionUtils;
27import com.android.server.pm.pkg.PackageStateInternal;
28import com.android.server.pm.resolution.ComponentResolverApi;
29
30import java.util.List;
31import java.util.function.Function;
32
33/**
34 * Abstract Class act as base class for Cross Profile strategy.
35 * This will be used by {@link CrossProfileIntentResolverEngine} to resolve intent across profile.
36 */
37public abstract class CrossProfileResolver {
38
39 protected ComponentResolverApi mComponentResolver;
40 protected UserManagerService mUserManager;
41
42 public CrossProfileResolver(ComponentResolverApi componentResolver,
43 UserManagerService userManager) {
44 mComponentResolver = componentResolver;
45 mUserManager = userManager;
46 }
47
48 /**
49 * This method would be overridden by concrete implementation. This method should define how to
50 * resolve given intent request in target profile.
51 * @param computer ComputerEngine instance that would be needed by ComponentResolverApi
52 * @param intent request
53 * @param resolvedType the MIME data type of intent request
54 * @param userId source/initiating user
55 * @param targetUserId target user id
56 * @param flags of intent request
57 * @param pkgName package name if defined.
58 * @param matchingFilters {@link CrossProfileIntentFilter}s configured for source user,
59 * targeting the targetUserId
60 * @param hasNonNegativePriorityResult if source have any non-negative(active and valid)
61 * resolveInfo in their profile.
62 * @param pkgSettingFunction function to find PackageStateInternal for given package
63 * @return list of {@link CrossProfileDomainInfo}
64 */
65 public abstract List<CrossProfileDomainInfo> resolveIntent(Computer computer, Intent intent,
66 String resolvedType, int userId, int targetUserId, long flags,
67 String pkgName, List<CrossProfileIntentFilter> matchingFilters,
68 boolean hasNonNegativePriorityResult,
69 Function<String, PackageStateInternal> pkgSettingFunction);
70
71 /**
72 * Filters the CrossProfileDomainInfos, the filtering technique would be defined by concrete
73 * implementation class
74 * @param intent request
75 * @param crossProfileDomainInfos resolved in target user
76 * @param flags for intent resolution
77 * @param sourceUserId source user
78 * @param targetUserId target user
79 * @param highestApprovalLevel highest level of domain approval
80 * @return filtered list of {@link CrossProfileDomainInfo}
81 */
82 public abstract List<CrossProfileDomainInfo> filterResolveInfoWithDomainPreferredActivity(
83 Intent intent, List<CrossProfileDomainInfo> crossProfileDomainInfos, long flags,
84 int sourceUserId, int targetUserId, int highestApprovalLevel);
85
86 /**
87 * Checks if mentioned user is enabled
88 * @param userId of requested user
89 * @return true if user is enabled
90 */
91 protected final boolean isUserEnabled(int userId) {
92 final long callingId = Binder.clearCallingIdentity();
93 try {
94 UserInfo userInfo = mUserManager.getUserInfo(userId);
95 return userInfo != null && userInfo.isEnabled();
96 } finally {
97 Binder.restoreCallingIdentity(callingId);
98 }
99 }
100
101 /**
102 * Filters out {@link CrossProfileDomainInfo} if they are not for any user apart from system
103 * user. If mentioned user is system user, then returns all responses.
104 * @param crossProfileDomainInfos result from resolution
105 * @param userId source user id
106 * @return filtered list of {@link CrossProfileDomainInfo}
107 */
108 protected final List<CrossProfileDomainInfo> filterIfNotSystemUser(
109 List<CrossProfileDomainInfo> crossProfileDomainInfos, int userId) {
110 if (userId == UserHandle.USER_SYSTEM) {
111 return crossProfileDomainInfos;
112 }
113
114 for (int i = CollectionUtils.size(crossProfileDomainInfos) - 1; i >= 0; i--) {
115 ResolveInfo info = crossProfileDomainInfos.get(i).mResolveInfo;
116 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
117 crossProfileDomainInfos.remove(i);
118 }
119 }
120 return crossProfileDomainInfos;
121 }
122
123 /**
124 * Returns user info of parent profile is applicable
125 * @param userId requested user
126 * @return parent's user info, null if parent is not present
127 */
128 protected final UserInfo getProfileParent(int userId) {
129 final long identity = Binder.clearCallingIdentity();
130 try {
131 return mUserManager.getProfileParent(userId);
132 } finally {
133 Binder.restoreCallingIdentity(identity);
134 }
135 }
136}