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

Commit d44abe0b authored by Gil Cukierman's avatar Gil Cukierman Committed by Android (Google) Code Review
Browse files

Merge "Have "Learn More" open cellular security help center" into main

parents d5669202 af753ba0
Loading
Loading
Loading
Loading
+73 −40
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import android.annotation.IntDef;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.safetycenter.SafetyCenterManager;
import android.safetycenter.SafetyEvent;
import android.safetycenter.SafetySourceData;
@@ -62,10 +64,6 @@ public class CellularNetworkSecuritySafetySource {

    private static final Intent CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT =
            new Intent("android.settings.CELLULAR_NETWORK_SECURITY");
    // TODO(b/321999913): direct to a help page URL e.g.
    //                    new Intent(Intent.ACTION_VIEW, Uri.parse("https://..."));
    private static final Intent LEARN_MORE_INTENT = new Intent();

    static final int NULL_CIPHER_STATE_ENCRYPTED = 0;
    static final int NULL_CIPHER_STATE_NOTIFY_ENCRYPTED = 1;
    static final int NULL_CIPHER_STATE_NOTIFY_NON_ENCRYPTED = 2;
@@ -223,7 +221,8 @@ public class CellularNetworkSecuritySafetySource {
                builder = new SafetySourceIssue.Builder(
                        NULL_CIPHER_ISSUE_NON_ENCRYPTED_ID + "_" + subId,
                        context.getString(
                            R.string.scNullCipherIssueNonEncryptedTitle, subInfo.getDisplayName()),
                                R.string.scNullCipherIssueNonEncryptedTitle,
                                subInfo.getDisplayName()),
                        context.getString(R.string.scNullCipherIssueNonEncryptedSummary),
                        SEVERITY_LEVEL_RECOMMENDATION,
                        NULL_CIPHER_ISSUE_NON_ENCRYPTED_ID);
@@ -240,10 +239,9 @@ public class CellularNetworkSecuritySafetySource {
            default:
                throw new AssertionError();
        }

        return Optional.of(
        builder
                    .setNotificationBehavior(SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
                .setNotificationBehavior(
                        SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
                .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
                .addAction(
                        new SafetySourceIssue.Action.Builder(
@@ -251,17 +249,23 @@ public class CellularNetworkSecuritySafetySource {
                                context.getString(R.string.scNullCipherIssueActionSettings),
                                mSafetyCenterManagerWrapper.getActivityPendingIntent(
                                        context, CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT))
                            .build())
                    .addAction(
                                .build());

        Intent learnMoreIntent = getLearnMoreIntent(context);
        if (learnMoreIntent != null) {
            builder.addAction(
                    new SafetySourceIssue.Action.Builder(
                            NULL_CIPHER_ACTION_LEARN_MORE_ID,
                                context.getString(R.string.scNullCipherIssueActionLearnMore),
                            context.getString(
                                    R.string.scNullCipherIssueActionLearnMore),
                            mSafetyCenterManagerWrapper.getActivityPendingIntent(
                                        context, LEARN_MORE_INTENT))
                            .build())
                                    context, learnMoreIntent))
                            .build());
        }

        return Optional.of(builder.build());
    }

    /** Builds the identity disclosure issue if it's enabled and there are disclosures to report. */
    private Optional<SafetySourceIssue> getIdentifierDisclosureIssue(
            Context context, int subId, IdentifierDisclosure disclosure) {
@@ -271,7 +275,8 @@ public class CellularNetworkSecuritySafetySource {

        SubscriptionInfoInternal subInfo =
                mSubscriptionManagerService.getSubscriptionInfoInternal(subId);
        return Optional.of(

        SafetySourceIssue.Builder builder =
                new SafetySourceIssue.Builder(
                        IDENTIFIER_DISCLOSURE_ISSUE_ID + "_" + subId,
                        context.getString(R.string.scIdentifierDisclosureIssueTitle),
@@ -283,23 +288,51 @@ public class CellularNetworkSecuritySafetySource {
                                subInfo.getDisplayName()),
                        SEVERITY_LEVEL_RECOMMENDATION,
                        IDENTIFIER_DISCLOSURE_ISSUE_ID)
                    .setNotificationBehavior(SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
                        .setNotificationBehavior(
                                SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY)
                        .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE)
                        .addAction(
                                new SafetySourceIssue.Action.Builder(
                                        NULL_CIPHER_ACTION_SETTINGS_ID,
                                context.getString(R.string.scNullCipherIssueActionSettings),
                                        context.getString(
                                                R.string.scNullCipherIssueActionSettings),
                                        mSafetyCenterManagerWrapper.getActivityPendingIntent(
                                        context, CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT))
                            .build())
                    .addAction(
                                                context,
                                                CELLULAR_NETWORK_SECURITY_SETTINGS_INTENT))
                                        .build());

        Intent learnMoreIntent = getLearnMoreIntent(context);
        if (learnMoreIntent != null) {
            builder.addAction(
                    new SafetySourceIssue.Action.Builder(
                            NULL_CIPHER_ACTION_LEARN_MORE_ID,
                            context.getString(R.string.scNullCipherIssueActionLearnMore),
                            mSafetyCenterManagerWrapper.getActivityPendingIntent(
                                        context, LEARN_MORE_INTENT))
                            .build())
                .build());
                                    context, learnMoreIntent)).build()
            );
        }

        return Optional.of(builder.build());
    }

    /**
     * Return Intent for learn more action, or null if resource associated with the Intent
     * uri is
     * missing or empty.
     */
    private Intent getLearnMoreIntent(Context context) {
        String learnMoreUri;
        try {
            learnMoreUri = context.getString(R.string.scCellularNetworkSecurityLearnMore);
        } catch (Resources.NotFoundException e) {
            return null;
        }

        if (learnMoreUri.isEmpty()) {
            return null;
        }

        return new Intent(Intent.ACTION_VIEW, Uri.parse(learnMoreUri));
    }

    /** A wrapper around {@link SafetyCenterManager} that can be instrumented in tests. */
+24 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.safetycenter.SafetySourceData;
import android.safetycenter.SafetySourceIssue;
import android.util.Singleton;

import com.android.internal.R;
@@ -50,6 +51,7 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;

import java.time.Instant;
import java.util.List;

public final class CellularNetworkSecuritySafetySourceTest extends TelephonyTest {

@@ -76,6 +78,8 @@ public final class CellularNetworkSecuritySafetySourceTest extends TelephonyTest

        mContextFixture.putResource(R.string.scCellularNetworkSecurityTitle, "fake");
        mContextFixture.putResource(R.string.scCellularNetworkSecuritySummary, "fake");
        mContextFixture.putResource(R.string.scCellularNetworkSecurityLearnMore,
                "https://support.google.com/android?p=cellular_security");
        mContextFixture.putResource(R.string.scNullCipherIssueNonEncryptedTitle, "fake %1$s");
        mContextFixture.putResource(R.string.scNullCipherIssueNonEncryptedSummary, "fake");
        mContextFixture.putResource(R.string.scNullCipherIssueEncryptedTitle, "fake %1$s");
@@ -265,4 +269,24 @@ public final class CellularNetworkSecuritySafetySourceTest extends TelephonyTest
        assertThat(data.getAllValues().get(3).getStatus()).isNotNull();
        assertThat(data.getAllValues().get(3).getIssues()).hasSize(2);
    }

    @Test
    public void learnMoreLinkEmpty_learnMoreIsHidden() {
        mContextFixture.putResource(R.string.scCellularNetworkSecurityLearnMore, "");

        ArgumentCaptor<SafetySourceData> data = ArgumentCaptor.forClass(SafetySourceData.class);

        mSafetySource.setNullCipherIssueEnabled(mContext, true);
        mSafetySource.setNullCipherState(mContext, 0, NULL_CIPHER_STATE_NOTIFY_NON_ENCRYPTED);
        mSafetySource.setIdentifierDisclosureIssueEnabled(mContext, true);
        mSafetySource.setIdentifierDisclosure(mContext, 0, 12, Instant.now(), Instant.now());

        verify(mSafetyCenterManagerWrapper, times(4)).setSafetySourceData(data.capture());
        List<SafetySourceIssue.Action> actions = data.getAllValues().get(
                3).getIssues().getFirst().getActions();

        // we only see the action that takes you to the settings page
        assertThat(actions).hasSize(1);
        assertThat(actions.getFirst().getId()).isEqualTo("cellular_security_settings");
    }
}
 No newline at end of file