Loading core/java/com/android/internal/config/appcloning/AppCloningDeviceConfigHelper.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.internal.config.appcloning; import android.content.Context; import android.provider.DeviceConfig; import com.android.internal.annotations.GuardedBy; /** * Helper class that holds the flags related to the app_cloning namespace in {@link DeviceConfig}. * * @hide */ public class AppCloningDeviceConfigHelper { @GuardedBy("sLock") private static AppCloningDeviceConfigHelper sInstance; private static final Object sLock = new Object(); private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangeListener; /** * This flag is defined inside {@link DeviceConfig#NAMESPACE_APP_CLONING}. Please check * {@link #mEnableAppCloningBuildingBlocks} for details. */ public static final String ENABLE_APP_CLONING_BUILDING_BLOCKS = "enable_app_cloning_building_blocks"; /** * Checks whether the support for app-cloning building blocks (like contacts * sharing/intent redirection), which are available starting from the U release, is turned on. * The default value is true to ensure the features are always enabled going forward. * * TODO:(b/253449368) Add information about the app-cloning config and mention that the devices * that do not support app-cloning should use the app-cloning config to disable all app-cloning * features. */ private volatile boolean mEnableAppCloningBuildingBlocks = true; private AppCloningDeviceConfigHelper() {} /** * @hide */ public static AppCloningDeviceConfigHelper getInstance(Context context) { synchronized (sLock) { if (sInstance == null) { sInstance = new AppCloningDeviceConfigHelper(); sInstance.init(context); } return sInstance; } } private void init(Context context) { initializeDeviceConfigChangeListener(); DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_CLONING, context.getMainExecutor(), mDeviceConfigChangeListener); } private void initializeDeviceConfigChangeListener() { mDeviceConfigChangeListener = properties -> { if (!DeviceConfig.NAMESPACE_APP_CLONING.equals(properties.getNamespace())) { return; } for (String name : properties.getKeyset()) { if (name == null) { return; } if (ENABLE_APP_CLONING_BUILDING_BLOCKS.equals(name)) { updateEnableAppCloningBuildingBlocks(); } } }; } private void updateEnableAppCloningBuildingBlocks() { mEnableAppCloningBuildingBlocks = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_APP_CLONING, ENABLE_APP_CLONING_BUILDING_BLOCKS, true); } /** * Fetch the feature flag to check whether the support for the app-cloning building blocks * (like contacts sharing/intent redirection) is enabled on the device. * @hide */ public boolean getEnableAppCloningBuildingBlocks() { return mEnableAppCloningBuildingBlocks; } } core/java/com/android/internal/config/appcloning/OWNERS 0 → 100644 +3 −0 Original line number Diff line number Diff line # Bug component: 1207885 jigarthakkar@google.com saumyap@google.com No newline at end of file services/core/java/com/android/server/content/SyncManager.java +6 −1 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BackgroundThread; Loading Loading @@ -256,6 +257,8 @@ public class SyncManager { private final SyncLogger mLogger; private final AppCloningDeviceConfigHelper mAppCloningDeviceConfigHelper; private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) { for (int i = 0, size = pendingJobs.size(); i < size; i++) { JobInfo job = pendingJobs.get(i); Loading Loading @@ -681,6 +684,7 @@ public class SyncManager { }, mSyncHandler); mConstants = new SyncManagerConstants(context); mAppCloningDeviceConfigHelper = AppCloningDeviceConfigHelper.getInstance(context); IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); context.registerReceiver(mConnectivityIntentReceiver, intentFilter); Loading Loading @@ -888,7 +892,8 @@ public class SyncManager { * @return true/false if contact sharing is enabled/disabled */ protected boolean isContactSharingAllowedForCloneProfile() { return mContext.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks); return mContext.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks) && mAppCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks(); } /** Loading services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java +9 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper; import com.android.server.LocalServices; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; Loading @@ -61,6 +62,8 @@ public class CrossProfileIntentResolverEngine { private final Context mContext; private final UserManagerInternal mUserManagerInternal; private AppCloningDeviceConfigHelper mAppCloningDeviceConfigHelper; public CrossProfileIntentResolverEngine(UserManagerService userManager, DomainVerificationManagerInternal domainVerificationManager, DefaultAppProvider defaultAppProvider, Context context) { Loading Loading @@ -250,7 +253,12 @@ public class CrossProfileIntentResolverEngine { * We would return NoFilteringResolver only if it is allowed(feature flag is set). */ if (shouldUseNoFilteringResolver(sourceUserId, targetUserId)) { if (NoFilteringResolver.isIntentRedirectionAllowed(mContext, resolveForStart, flags)) { if (mAppCloningDeviceConfigHelper == null) { //lazy initialization of helper till required, to improve performance. mAppCloningDeviceConfigHelper = AppCloningDeviceConfigHelper.getInstance(mContext); } if (NoFilteringResolver.isIntentRedirectionAllowed(mContext, mAppCloningDeviceConfigHelper, resolveForStart, flags)) { return new NoFilteringResolver(computer.getComponentResolver(), mUserManager); } else { Loading services/core/java/com/android/server/pm/NoFilteringResolver.java +9 −5 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.pm.ResolveInfo; import android.os.Binder; import com.android.internal.R; import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.resolution.ComponentResolverApi; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; Loading Loading @@ -56,9 +57,10 @@ public class NoFilteringResolver extends CrossProfileResolver { * (PackageManager.MATCH_CLONE_PROFILE) bit set. * @return true if resolver would be used for cross profile resolution. */ public static boolean isIntentRedirectionAllowed(Context context, boolean resolveForStart, public static boolean isIntentRedirectionAllowed(Context context, AppCloningDeviceConfigHelper appCloningDeviceConfigHelper, boolean resolveForStart, long flags) { return isAppCloningBuildingBlocksEnabled(context) return isAppCloningBuildingBlocksEnabled(context, appCloningDeviceConfigHelper) && (resolveForStart || (((flags & PackageManager.MATCH_CLONE_PROFILE) != 0) && hasPermission(context, Manifest.permission.QUERY_CLONED_APPS))); } Loading Loading @@ -140,12 +142,14 @@ public class NoFilteringResolver extends CrossProfileResolver { } /** * Checks if the AppCloningBuildingBlocks config is enabled. * Checks if the AppCloningBuildingBlocks flag is enabled. */ private static boolean isAppCloningBuildingBlocksEnabled(Context context) { private static boolean isAppCloningBuildingBlocksEnabled(Context context, AppCloningDeviceConfigHelper appCloningDeviceConfigHelper) { final long token = Binder.clearCallingIdentity(); try { return context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks); return context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks) && appCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks(); } finally { Binder.restoreCallingIdentity(token); } Loading Loading
core/java/com/android/internal/config/appcloning/AppCloningDeviceConfigHelper.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.internal.config.appcloning; import android.content.Context; import android.provider.DeviceConfig; import com.android.internal.annotations.GuardedBy; /** * Helper class that holds the flags related to the app_cloning namespace in {@link DeviceConfig}. * * @hide */ public class AppCloningDeviceConfigHelper { @GuardedBy("sLock") private static AppCloningDeviceConfigHelper sInstance; private static final Object sLock = new Object(); private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangeListener; /** * This flag is defined inside {@link DeviceConfig#NAMESPACE_APP_CLONING}. Please check * {@link #mEnableAppCloningBuildingBlocks} for details. */ public static final String ENABLE_APP_CLONING_BUILDING_BLOCKS = "enable_app_cloning_building_blocks"; /** * Checks whether the support for app-cloning building blocks (like contacts * sharing/intent redirection), which are available starting from the U release, is turned on. * The default value is true to ensure the features are always enabled going forward. * * TODO:(b/253449368) Add information about the app-cloning config and mention that the devices * that do not support app-cloning should use the app-cloning config to disable all app-cloning * features. */ private volatile boolean mEnableAppCloningBuildingBlocks = true; private AppCloningDeviceConfigHelper() {} /** * @hide */ public static AppCloningDeviceConfigHelper getInstance(Context context) { synchronized (sLock) { if (sInstance == null) { sInstance = new AppCloningDeviceConfigHelper(); sInstance.init(context); } return sInstance; } } private void init(Context context) { initializeDeviceConfigChangeListener(); DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_CLONING, context.getMainExecutor(), mDeviceConfigChangeListener); } private void initializeDeviceConfigChangeListener() { mDeviceConfigChangeListener = properties -> { if (!DeviceConfig.NAMESPACE_APP_CLONING.equals(properties.getNamespace())) { return; } for (String name : properties.getKeyset()) { if (name == null) { return; } if (ENABLE_APP_CLONING_BUILDING_BLOCKS.equals(name)) { updateEnableAppCloningBuildingBlocks(); } } }; } private void updateEnableAppCloningBuildingBlocks() { mEnableAppCloningBuildingBlocks = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_APP_CLONING, ENABLE_APP_CLONING_BUILDING_BLOCKS, true); } /** * Fetch the feature flag to check whether the support for the app-cloning building blocks * (like contacts sharing/intent redirection) is enabled on the device. * @hide */ public boolean getEnableAppCloningBuildingBlocks() { return mEnableAppCloningBuildingBlocks; } }
core/java/com/android/internal/config/appcloning/OWNERS 0 → 100644 +3 −0 Original line number Diff line number Diff line # Bug component: 1207885 jigarthakkar@google.com saumyap@google.com No newline at end of file
services/core/java/com/android/server/content/SyncManager.java +6 −1 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BackgroundThread; Loading Loading @@ -256,6 +257,8 @@ public class SyncManager { private final SyncLogger mLogger; private final AppCloningDeviceConfigHelper mAppCloningDeviceConfigHelper; private boolean isJobIdInUseLockedH(int jobId, List<JobInfo> pendingJobs) { for (int i = 0, size = pendingJobs.size(); i < size; i++) { JobInfo job = pendingJobs.get(i); Loading Loading @@ -681,6 +684,7 @@ public class SyncManager { }, mSyncHandler); mConstants = new SyncManagerConstants(context); mAppCloningDeviceConfigHelper = AppCloningDeviceConfigHelper.getInstance(context); IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); context.registerReceiver(mConnectivityIntentReceiver, intentFilter); Loading Loading @@ -888,7 +892,8 @@ public class SyncManager { * @return true/false if contact sharing is enabled/disabled */ protected boolean isContactSharingAllowedForCloneProfile() { return mContext.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks); return mContext.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks) && mAppCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks(); } /** Loading
services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java +9 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper; import com.android.server.LocalServices; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; Loading @@ -61,6 +62,8 @@ public class CrossProfileIntentResolverEngine { private final Context mContext; private final UserManagerInternal mUserManagerInternal; private AppCloningDeviceConfigHelper mAppCloningDeviceConfigHelper; public CrossProfileIntentResolverEngine(UserManagerService userManager, DomainVerificationManagerInternal domainVerificationManager, DefaultAppProvider defaultAppProvider, Context context) { Loading Loading @@ -250,7 +253,12 @@ public class CrossProfileIntentResolverEngine { * We would return NoFilteringResolver only if it is allowed(feature flag is set). */ if (shouldUseNoFilteringResolver(sourceUserId, targetUserId)) { if (NoFilteringResolver.isIntentRedirectionAllowed(mContext, resolveForStart, flags)) { if (mAppCloningDeviceConfigHelper == null) { //lazy initialization of helper till required, to improve performance. mAppCloningDeviceConfigHelper = AppCloningDeviceConfigHelper.getInstance(mContext); } if (NoFilteringResolver.isIntentRedirectionAllowed(mContext, mAppCloningDeviceConfigHelper, resolveForStart, flags)) { return new NoFilteringResolver(computer.getComponentResolver(), mUserManager); } else { Loading
services/core/java/com/android/server/pm/NoFilteringResolver.java +9 −5 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.pm.ResolveInfo; import android.os.Binder; import com.android.internal.R; import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.resolution.ComponentResolverApi; import com.android.server.pm.verify.domain.DomainVerificationManagerInternal; Loading Loading @@ -56,9 +57,10 @@ public class NoFilteringResolver extends CrossProfileResolver { * (PackageManager.MATCH_CLONE_PROFILE) bit set. * @return true if resolver would be used for cross profile resolution. */ public static boolean isIntentRedirectionAllowed(Context context, boolean resolveForStart, public static boolean isIntentRedirectionAllowed(Context context, AppCloningDeviceConfigHelper appCloningDeviceConfigHelper, boolean resolveForStart, long flags) { return isAppCloningBuildingBlocksEnabled(context) return isAppCloningBuildingBlocksEnabled(context, appCloningDeviceConfigHelper) && (resolveForStart || (((flags & PackageManager.MATCH_CLONE_PROFILE) != 0) && hasPermission(context, Manifest.permission.QUERY_CLONED_APPS))); } Loading Loading @@ -140,12 +142,14 @@ public class NoFilteringResolver extends CrossProfileResolver { } /** * Checks if the AppCloningBuildingBlocks config is enabled. * Checks if the AppCloningBuildingBlocks flag is enabled. */ private static boolean isAppCloningBuildingBlocksEnabled(Context context) { private static boolean isAppCloningBuildingBlocksEnabled(Context context, AppCloningDeviceConfigHelper appCloningDeviceConfigHelper) { final long token = Binder.clearCallingIdentity(); try { return context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks); return context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks) && appCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks(); } finally { Binder.restoreCallingIdentity(token); } Loading