diff options
| author | 2023-01-17 00:40:00 +0000 | |
|---|---|---|
| committer | 2023-01-17 00:40:00 +0000 | |
| commit | 80ba8c26519acb90af0af1af5b6527e4035e2002 (patch) | |
| tree | e36a3767e7e604aa669d7db91babb5d8742a8c27 | |
| parent | 3cfe825173f94bf65945a6ac2823d226663b7505 (diff) | |
| parent | a627d753a46d4d87efcf14ef1d426e5e0d12e433 (diff) | |
Merge "Add flag to control changes to disable contacts syncs in clone"
4 files changed, 132 insertions, 2 deletions
diff --git a/core/java/com/android/internal/config/appcloning/AppCloningDeviceConfigHelper.java b/core/java/com/android/internal/config/appcloning/AppCloningDeviceConfigHelper.java new file mode 100644 index 000000000000..ddd3d2cf3aed --- /dev/null +++ b/core/java/com/android/internal/config/appcloning/AppCloningDeviceConfigHelper.java @@ -0,0 +1,107 @@ +/* + * 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; + } +} diff --git a/core/java/com/android/internal/config/appcloning/OWNERS b/core/java/com/android/internal/config/appcloning/OWNERS new file mode 100644 index 000000000000..0645a8c54414 --- /dev/null +++ b/core/java/com/android/internal/config/appcloning/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 1207885 +jigarthakkar@google.com +saumyap@google.com
\ No newline at end of file diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index dcc98e17fadf..5b696c2b253b 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -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; @@ -264,6 +265,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); @@ -627,6 +630,7 @@ public class SyncManager { }, mSyncHandler); mConstants = new SyncManagerConstants(context); + mAppCloningDeviceConfigHelper = AppCloningDeviceConfigHelper.getInstance(context); IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); context.registerReceiver(mConnectivityIntentReceiver, intentFilter); @@ -828,6 +832,18 @@ public class SyncManager { } /** + * Check whether the feature flag controlling contacts sharing for clone profile is set. If + * true, the contact syncs for clone profile should be disabled. + * + * @return true/false if contact sharing is enabled/disabled + */ + protected boolean isContactSharingAllowedForCloneProfile() { + // TODO(b/253449368): This method should also check for the config controlling + // all app-cloning features. + return mAppCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks(); + } + + /** * Check if account sync should be disabled for the given user and provider. * @param userInfo * @param providerName @@ -836,7 +852,9 @@ public class SyncManager { */ @VisibleForTesting protected boolean shouldDisableSyncForUser(UserInfo userInfo, String providerName) { - if (userInfo == null || providerName == null) return false; + if (userInfo == null || providerName == null || !isContactSharingAllowedForCloneProfile()) { + return false; + } return providerName.equals(ContactsContract.AUTHORITY) && !areContactWritesEnabledForUser(userInfo); } diff --git a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java index d4e3d4418c43..0dd60b8779af 100644 --- a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java @@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -95,7 +96,7 @@ public class SyncManagerTest extends TestCase { when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); doNothing().when(mAccountManagerInternal).addOnAppPermissionChangeListener(any()); when(mJobSchedulerInternal.getSystemScheduledPendingJobs()).thenReturn(new ArrayList<>()); - mSyncManager = new SyncManagerWithMockedServices(mContext, true); + mSyncManager = spy(new SyncManagerWithMockedServices(mContext, true)); } public void testSyncExtrasEquals_WithNull() throws Exception { @@ -233,6 +234,7 @@ public class SyncManagerTest extends TestCase { } public void testShouldDisableSync() { + doReturn(true).when(mSyncManager).isContactSharingAllowedForCloneProfile(); UserInfo primaryUserInfo = createUserInfo("primary", 0 /* id */, 0 /* groupId */, UserInfo.FLAG_PRIMARY | UserInfo.FLAG_ADMIN); UserInfo cloneUserInfo = createUserInfo("clone", 10 /* id */, 0 /* groupId */, |