Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80ba8c26 authored by Jigar Thakkar's avatar Jigar Thakkar Committed by Android (Google) Code Review
Browse files

Merge "Add flag to control changes to disable contacts syncs in clone"

parents 3cfe8251 a627d753
Loading
Loading
Loading
Loading
+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;
    }
}
+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
+19 −1
Original line number Diff line number Diff line
@@ -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);
@@ -827,6 +831,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
@@ -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);
    }
+3 −1
Original line number Diff line number Diff line
@@ -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 */,