Merge "Creating CloneProfileResolver to facilitate intent redirection for clone profile"
This commit is contained in:
committed by
Android (Google) Code Review
commit
a01423b6c0
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
|
||||
import com.android.server.pm.pkg.PackageStateInternal;
|
||||
import com.android.server.pm.resolution.ComponentResolverApi;
|
||||
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Cross Profile intent resolution strategy used for and to clone profile.
|
||||
*/
|
||||
public class CloneProfileResolver extends CrossProfileResolver {
|
||||
|
||||
public CloneProfileResolver(ComponentResolverApi componentResolver,
|
||||
UserManagerService userManagerService) {
|
||||
super(componentResolver, userManagerService);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is resolution strategy for Clone Profile.
|
||||
* In case of clone profile, the profile is supposed to be transparent to end user. To end user
|
||||
* clone and owner profile should be part of same user space. Hence, the resolution strategy
|
||||
* would resolve intent in both profile and return combined result without any filtering of the
|
||||
* results.
|
||||
*
|
||||
* @param computer ComputerEngine instance that would be needed by ComponentResolverApi
|
||||
* @param intent request
|
||||
* @param resolvedType the MIME data type of intent request
|
||||
* @param userId source/initiating user
|
||||
* @param targetUserId target user id
|
||||
* @param flags of intent request
|
||||
* @param pkgName the application package name this Intent is limited to
|
||||
* @param matchingFilters {@link CrossProfileIntentFilter}s configured for source user,
|
||||
* targeting the targetUserId
|
||||
* @param hasNonNegativePriorityResult if source have any non-negative(active and valid)
|
||||
* resolveInfo in their profile.
|
||||
* @param pkgSettingFunction function to find PackageStateInternal for given package
|
||||
* @return list of {@link CrossProfileDomainInfo}
|
||||
*/
|
||||
@Override
|
||||
public List<CrossProfileDomainInfo> resolveIntent(Computer computer, Intent intent,
|
||||
String resolvedType, int userId, int targetUserId, long flags,
|
||||
String pkgName, List<CrossProfileIntentFilter> matchingFilters,
|
||||
boolean hasNonNegativePriorityResult,
|
||||
Function<String, PackageStateInternal> pkgSettingFunction) {
|
||||
List<ResolveInfo> resolveInfos = mComponentResolver.queryActivities(computer,
|
||||
intent, resolvedType, flags, targetUserId);
|
||||
List<CrossProfileDomainInfo> crossProfileDomainInfos = new ArrayList<>();
|
||||
if (resolveInfos != null) {
|
||||
|
||||
for (int index = 0; index < resolveInfos.size(); index++) {
|
||||
crossProfileDomainInfos.add(new CrossProfileDomainInfo(resolveInfos.get(index),
|
||||
DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE,
|
||||
targetUserId));
|
||||
}
|
||||
}
|
||||
return filterIfNotSystemUser(crossProfileDomainInfos, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* As clone and owner profile are going to be part of the same userspace, we need no filtering
|
||||
* out of any clone profile's result
|
||||
* @param intent request
|
||||
* @param crossProfileDomainInfos resolved in target user
|
||||
* @param flags for intent resolution
|
||||
* @param sourceUserId source user
|
||||
* @param targetUserId target user
|
||||
* @param highestApprovalLevel highest level of domain approval
|
||||
* @return list of CrossProfileDomainInfo
|
||||
*/
|
||||
@Override
|
||||
public List<CrossProfileDomainInfo> filterResolveInfoWithDomainPreferredActivity(Intent intent,
|
||||
List<CrossProfileDomainInfo> crossProfileDomainInfos, long flags, int sourceUserId,
|
||||
int targetUserId, int highestApprovalLevel) {
|
||||
// no filtering for clone profile
|
||||
return crossProfileDomainInfos;
|
||||
}
|
||||
}
|
||||
@@ -460,7 +460,7 @@ public class ComputerEngine implements Computer {
|
||||
mBackgroundDexOptService = args.service.mBackgroundDexOptService;
|
||||
mExternalSourcesPolicy = args.service.mExternalSourcesPolicy;
|
||||
mCrossProfileIntentResolverEngine = new CrossProfileIntentResolverEngine(
|
||||
mUserManager, mDomainVerificationManager, mDefaultAppProvider);
|
||||
mUserManager, mDomainVerificationManager, mDefaultAppProvider, mContext);
|
||||
|
||||
// Used to reference PMS attributes that are primitives and which are not
|
||||
// updated under control of the PMS lock.
|
||||
|
||||
@@ -46,6 +46,9 @@ class CrossProfileIntentFilter extends WatchedIntentFilter {
|
||||
private static final String ATTR_FILTER = "filter";
|
||||
private static final String ATTR_ACCESS_CONTROL = "accessControl";
|
||||
|
||||
//flag to decide if intent needs to be resolved cross profile if pkgName is already defined
|
||||
public static final int FLAG_IS_PACKAGE_FOR_FILTER = 0x00000008;
|
||||
|
||||
private static final String TAG = "CrossProfileIntentFilter";
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import static com.android.server.pm.CrossProfileIntentFilter.FLAG_IS_PACKAGE_FOR_FILTER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.IntentFilter;
|
||||
|
||||
@@ -37,7 +39,7 @@ class CrossProfileIntentResolver
|
||||
|
||||
@Override
|
||||
protected boolean isPackageForFilter(String packageName, CrossProfileIntentFilter filter) {
|
||||
return false;
|
||||
return (FLAG_IS_PACKAGE_FOR_FILTER & filter.mFlags) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,12 +25,14 @@ import static com.android.server.pm.PackageManagerService.TAG;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Process;
|
||||
import android.text.TextUtils;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
@@ -54,13 +56,15 @@ public class CrossProfileIntentResolverEngine {
|
||||
private final UserManagerService mUserManager;
|
||||
private final DomainVerificationManagerInternal mDomainVerificationManager;
|
||||
private final DefaultAppProvider mDefaultAppProvider;
|
||||
private final Context mContext;
|
||||
|
||||
public CrossProfileIntentResolverEngine(UserManagerService userManager,
|
||||
DomainVerificationManagerInternal domainVerificationManager,
|
||||
DefaultAppProvider defaultAppProvider) {
|
||||
DefaultAppProvider defaultAppProvider, Context context) {
|
||||
mUserManager = userManager;
|
||||
mDomainVerificationManager = domainVerificationManager;
|
||||
mDefaultAppProvider = defaultAppProvider;
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,6 +200,21 @@ public class CrossProfileIntentResolverEngine {
|
||||
@SuppressWarnings("unused")
|
||||
private CrossProfileResolver chooseCrossProfileResolver(@NonNull Computer computer,
|
||||
UserInfo sourceUserInfo, UserInfo targetUserInfo) {
|
||||
//todo change isCloneProfile to user properties b/241532322
|
||||
/**
|
||||
* If source or target user is clone profile, using {@link CloneProfileResolver}
|
||||
* We would allow CloneProfileResolver only if flag
|
||||
* SETTINGS_ALLOW_INTENT_REDIRECTION_FOR_CLONE_PROFILE is enabled
|
||||
*/
|
||||
if (sourceUserInfo.isCloneProfile() || targetUserInfo.isCloneProfile()) {
|
||||
if (FeatureFlagUtils.isEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_ALLOW_INTENT_REDIRECTION_FOR_CLONE_PROFILE)) {
|
||||
return new CloneProfileResolver(computer.getComponentResolver(),
|
||||
mUserManager);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new DefaultCrossProfileResolver(computer.getComponentResolver(),
|
||||
mUserManager, mDomainVerificationManager);
|
||||
}
|
||||
@@ -313,8 +332,6 @@ public class CrossProfileIntentResolverEngine {
|
||||
}
|
||||
|
||||
if (pkgName == null && intent.hasWebURI()) {
|
||||
// If instant apps are not allowed and there is result only from current or cross
|
||||
// profile return it
|
||||
if (!addInstant && ((candidates.size() <= 1 && crossProfileCandidates.isEmpty())
|
||||
|| (candidates.isEmpty() && !crossProfileCandidates.isEmpty()))) {
|
||||
candidates.addAll(resolveInfoFromCrossProfileDomainInfo(crossProfileCandidates));
|
||||
|
||||
Reference in New Issue
Block a user