Merge "Creating CloneProfileResolver to facilitate intent redirection for clone profile"

This commit is contained in:
Sarup Dalwani
2022-11-02 05:26:10 +00:00
committed by Android (Google) Code Review
5 changed files with 126 additions and 5 deletions

View File

@@ -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;
}
}

View File

@@ -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.

View File

@@ -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";
/**

View File

@@ -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

View File

@@ -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));