chromium/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubModuleDelegateImpl.java

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.safety_hub;

import static org.chromium.chrome.browser.password_manager.PasswordManagerUtilBridge.usesSplitStoresAndUPMForLocal;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.chromium.base.supplier.Supplier;
import org.chromium.build.BuildConfig;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.omaha.UpdateStatusProvider;
import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
import org.chromium.chrome.browser.password_manager.PasswordStoreBridge;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.sync.SyncServiceFactory;
import org.chromium.chrome.browser.ui.signin.SigninAndHistorySyncActivityLauncher;
import org.chromium.chrome.browser.ui.signin.SigninAndHistorySyncCoordinator;
import org.chromium.chrome.browser.ui.signin.SyncConsentActivityLauncher;
import org.chromium.chrome.browser.ui.signin.account_picker.AccountPickerBottomSheetStrings;
import org.chromium.components.signin.metrics.SigninAccessPoint;
import org.chromium.components.sync.SyncService;
import org.chromium.components.user_prefs.UserPrefs;
import org.chromium.content_public.common.ContentUrlConstants;
import org.chromium.ui.modaldialog.ModalDialogManager;

/** An implementation of {@link SafetyHubModuleDelegate} */
public class SafetyHubModuleDelegateImpl implements SafetyHubModuleDelegate {
    private static final int INVALID_PASSWORD_COUNT = -1;
    private final @NonNull Profile mProfile;
    private final @NonNull Supplier<ModalDialogManager> mModalDialogManagerSupplier;
    private final @NonNull SigninAndHistorySyncActivityLauncher mSigninLauncher;
    private final @NonNull SyncConsentActivityLauncher mSyncLauncher;

    /**
     * @param profile A supplier for {@link Profile} that owns the data being deleted.
     * @param modalDialogManagerSupplier A supplier for {@link ModalDialogManager} that will be used
     *     to launch the password check UI.
     */
    public SafetyHubModuleDelegateImpl(
            @NonNull Profile profile,
            @NonNull Supplier<ModalDialogManager> modalDialogManagerSupplier,
            @NonNull SigninAndHistorySyncActivityLauncher signinLauncher,
            @NonNull SyncConsentActivityLauncher syncLauncher) {
        mProfile = profile;
        mModalDialogManagerSupplier = modalDialogManagerSupplier;
        mSigninLauncher = signinLauncher;
        mSyncLauncher = syncLauncher;
    }

    @Override
    public void showPasswordCheckUI(Context context) {
        SafetyHubUtils.showPasswordCheckUI(context, mProfile, mModalDialogManagerSupplier);
    }

    @Override
    public @Nullable UpdateStatusProvider.UpdateStatus getUpdateStatus() {
        return SafetyHubFetchServiceFactory.getForProfile(mProfile).getUpdateStatus();
    }

    @Override
    public void openGooglePlayStore(Context context) {
        if (!BuildConfig.IS_CHROME_BRANDED) {
            return;
        }

        String chromeAppId = context.getPackageName();
        Intent intent =
                new Intent(
                        Intent.ACTION_VIEW,
                        Uri.parse(ContentUrlConstants.PLAY_STORE_URL_PREFIX + chromeAppId));

        context.startActivity(intent);
    }

    @Override
    public int getAccountPasswordsCount(@Nullable PasswordStoreBridge passwordStoreBridge) {
        PasswordManagerHelper passwordManagerHelper = PasswordManagerHelper.getForProfile(mProfile);
        SyncService syncService = SyncServiceFactory.getForProfile(mProfile);
        if (passwordStoreBridge == null
                || !PasswordManagerHelper.hasChosenToSyncPasswords(syncService)
                || !passwordManagerHelper.canUseUpm()) return INVALID_PASSWORD_COUNT;

        if (usesSplitStoresAndUPMForLocal(UserPrefs.get(mProfile))) {
            return passwordStoreBridge.getPasswordStoreCredentialsCountForAccountStore();
        }
        // If using split stores is disabled, all passwords reside in the profile store.
        return passwordStoreBridge.getPasswordStoreCredentialsCountForProfileStore();
    }

    @Override
    public void launchSyncOrSigninPromo(Context context) {
        assert !SafetyHubUtils.isSignedIn(mProfile);
        if (ChromeFeatureList.isEnabled(
                ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)) {
            AccountPickerBottomSheetStrings strings =
                    new AccountPickerBottomSheetStrings.Builder(
                                    R.string.signin_account_picker_bottom_sheet_title)
                            .setSubtitleStringId(R.string.safety_check_passwords_error_signed_out)
                            .build();
            // Open the sign-in page.
            mSigninLauncher.launchActivityIfAllowed(
                    context,
                    mProfile,
                    strings,
                    SigninAndHistorySyncCoordinator.NoAccountSigninMode.BOTTOM_SHEET,
                    SigninAndHistorySyncCoordinator.WithAccountSigninMode
                            .DEFAULT_ACCOUNT_BOTTOM_SHEET,
                    SigninAndHistorySyncCoordinator.HistoryOptInMode.NONE,
                    SigninAccessPoint.SAFETY_CHECK);
        } else {
            // Open the sync page.
            mSyncLauncher.launchActivityIfAllowed(context, SigninAccessPoint.SAFETY_CHECK);
        }
    }
}