1 /*
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 
17 package com.android.server.pm;
18 
19 import android.content.Context;
20 import android.content.pm.UserInfo;
21 import android.content.pm.UserProperties;
22 import android.util.ArraySet;
23 
24 /**
25  * Helper class to manage {@link com.android.server.pm.CrossProfileIntentFilter}s.
26  */
27 public class CrossProfileIntentFilterHelper {
28     private final Context mContext;
29     private final UserManagerInternal mUserManagerInternal;
30     private final Settings mSettings;
31     private final UserManagerService mUserManagerService;
32     private final PackageManagerTracedLock mLock;
33 
CrossProfileIntentFilterHelper(Settings settings, UserManagerService userManagerService, PackageManagerTracedLock lock, UserManagerInternal userManagerInternal, Context context)34     public CrossProfileIntentFilterHelper(Settings settings, UserManagerService userManagerService,
35             PackageManagerTracedLock lock, UserManagerInternal userManagerInternal,
36             Context context) {
37         mSettings = settings;
38         mUserManagerService = userManagerService;
39         mLock = lock;
40         mContext = context;
41         mUserManagerInternal = userManagerInternal;
42     }
43 
44     /**
45      * For users that have
46      * {@link android.content.pm.UserProperties#getUpdateCrossProfileIntentFiltersOnOTA} set, this
47      * task will update default {@link com.android.server.pm.CrossProfileIntentFilter} between that
48      * user and its parent. This will only update CrossProfileIntentFilters set by system package.
49      * The new default are configured in {@link UserTypeDetails}.
50      */
updateDefaultCrossProfileIntentFilter()51     public void updateDefaultCrossProfileIntentFilter() {
52         for (UserInfo userInfo : mUserManagerInternal.getUsers(false)) {
53 
54             UserProperties currentUserProperties = mUserManagerInternal
55                     .getUserProperties(userInfo.id);
56 
57             if (currentUserProperties != null
58                     && currentUserProperties.getUpdateCrossProfileIntentFiltersOnOTA()) {
59                 int parentUserId = mUserManagerInternal.getProfileParentId(userInfo.id);
60                 if (parentUserId != userInfo.id) {
61                     clearCrossProfileIntentFilters(userInfo.id,
62                             mContext.getOpPackageName(), parentUserId);
63                     clearCrossProfileIntentFilters(parentUserId,
64                             mContext.getOpPackageName(),  userInfo.id);
65 
66                     mUserManagerInternal.setDefaultCrossProfileIntentFilters(parentUserId,
67                             userInfo.id);
68                 }
69             }
70         }
71     }
72 
73     /**
74      * Clear {@link CrossProfileIntentFilter}s configured on source user by ownerPackage
75      * targeting the targetUserId. If targetUserId is null then it will clear
76      * {@link CrossProfileIntentFilter} for any target user.
77      * @param sourceUserId source user for whom CrossProfileIntentFilter would be configured
78      * @param ownerPackage package who would have configured CrossProfileIntentFilter
79      * @param targetUserId user id for which CrossProfileIntentFilter will be removed.
80      *                     This can be null in which case it will clear for any target user.
81      */
clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, Integer targetUserId)82     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
83             Integer targetUserId) {
84         synchronized (mLock) {
85             CrossProfileIntentResolver resolver = mSettings
86                     .editCrossProfileIntentResolverLPw(sourceUserId);
87             ArraySet<CrossProfileIntentFilter> set =
88                     new ArraySet<>(resolver.filterSet());
89             for (CrossProfileIntentFilter filter : set) {
90                 //Only remove if calling user is allowed based on access control of
91                 // {@link CrossProfileIntentFilter}
92                 if (filter.getOwnerPackage().equals(ownerPackage)
93                         && (targetUserId == null || filter.mTargetUserId == targetUserId)
94                         && mUserManagerService.isCrossProfileIntentFilterAccessible(sourceUserId,
95                         filter.mTargetUserId, /* addCrossProfileIntentFilter */ false)) {
96                     resolver.removeFilter(filter);
97                 }
98             }
99         }
100     }
101 }
102