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

Commit 00870bff authored by Bernard Chau's avatar Bernard Chau
Browse files

Logging SetNewPasswordActivity events

Every launch of the activity with either ACTION_SET_NEW_PASSWORD
or ACTION_SET_NEW_PARENT_PROFILE_PASSWORD is logged, regardless
of whether extra EXTRA_PASSWORD_COMPLEXITY is used or whether
the caller has the required permisssion or not
- action: ACTION_SET_NEW_PASSWORD or
ACTION_SET_NEW_PARENT_PROFILE_PASSWORD
- pageId: SET_NEW_PASSWORD_ACTIVITY
- key: calling app package name
- value: raw value of intent extra EXTRA_PASSWORD_COMPLEXITY, or
Integer.MIN_VALUE if it does not exist

Bug: 120840632
Test: atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/PasswordUtilsTest.java
      atest packages/apps/Settings/tests/robotests/src/com/android/settings/password/SetNewPasswordActivityTest.java
Change-Id: I57dc55110f7f284ddad7d3fc971d1f2298b46cbd
parent 09c932b2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ public final class PasswordUtils extends com.android.settingslib.Utils {
     * Returns the package name which the activity with {@code activityToken} is launched from.
     */
    @Nullable
    private static String getCallingAppPackageName(IBinder activityToken) {
    public static String getCallingAppPackageName(IBinder activityToken) {
        String pkg = null;
        try {
            pkg = ActivityManager.getService().getLaunchedFromPackage(activityToken);
+38 −6
Original line number Diff line number Diff line
@@ -29,12 +29,15 @@ import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.PasswordMetrics;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

/**
 * Trampolines {@link DevicePolicyManager#ACTION_SET_NEW_PASSWORD} and
@@ -73,19 +76,23 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo
            return;
        }

        IBinder activityToken = getActivityToken();
        logSetNewPasswordIntent();

        final IBinder activityToken = getActivityToken();
        mCallerAppName = (String) PasswordUtils.getCallingAppLabel(this, activityToken);
        if (ACTION_SET_NEW_PASSWORD.equals(mNewPasswordAction)
                && getIntent().hasExtra(EXTRA_PASSWORD_COMPLEXITY)) {
            boolean hasPermission = PasswordUtils.isCallingAppPermitted(
            final boolean hasPermission = PasswordUtils.isCallingAppPermitted(
                    this, activityToken, GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
            if (hasPermission) {
                mRequestedMinComplexity = PasswordMetrics.sanitizeComplexityLevel(getIntent()
                mRequestedMinComplexity =
                        PasswordMetrics.sanitizeComplexityLevel(getIntent()
                                .getIntExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_NONE));
            } else {
                PasswordUtils.crashCallingApplication(activityToken,
                        "Must have permission " + GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY
                                + " to use extra " + EXTRA_PASSWORD_COMPLEXITY);
                        "Must have permission "
                                + GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY + " to use extra "
                                + EXTRA_PASSWORD_COMPLEXITY);
                finish();
                return;
            }
@@ -112,4 +119,29 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo
        startActivity(intent);
        finish();
    }

    private void logSetNewPasswordIntent() {
        final String callingAppPackageName =
                PasswordUtils.getCallingAppPackageName(getActivityToken());

        // use int min value to denote absence of EXTRA_PASSWORD_COMPLEXITY
        final int extraPasswordComplexity = getIntent().hasExtra(EXTRA_PASSWORD_COMPLEXITY)
                ? getIntent().getIntExtra(EXTRA_PASSWORD_COMPLEXITY, PASSWORD_COMPLEXITY_NONE)
                : Integer.MIN_VALUE;

        // this activity is launched by either ACTION_SET_NEW_PASSWORD or
        // ACTION_SET_NEW_PARENT_PROFILE_PASSWORD
        final int action = ACTION_SET_NEW_PASSWORD.equals(mNewPasswordAction)
                ? SettingsEnums.ACTION_SET_NEW_PASSWORD
                : SettingsEnums.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD;

        final MetricsFeatureProvider metricsProvider =
                FeatureFactory.getFactory(this).getMetricsFeatureProvider();
        metricsProvider.action(
                metricsProvider.getAttribution(this),
                action,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                callingAppPackageName,
                extraPasswordComplexity);
    }
}
+20 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import static com.android.settings.password.PasswordUtils.getCallingAppLabel;
import static com.android.settings.password.PasswordUtils.getCallingAppPackageName;
import static com.android.settings.password.PasswordUtils.isCallingAppPermitted;

import static com.google.common.truth.Truth.assertThat;
@@ -77,7 +78,7 @@ public class PasswordUtilsTest {
    }

    @Test
    public void getCallingAppLabel_activityServiceThrowsRemoteException_returnsNull()
    public void getCallingAppLabel_getCallingAppPackageNameReturnsNull_returnsNull()
            throws Exception {
        when(mActivityService.getLaunchedFromPackage(mActivityToken))
                .thenThrow(new RemoteException());
@@ -86,7 +87,7 @@ public class PasswordUtilsTest {
    }

    @Test
    public void getCallingAppLabel_activityServiceReturnsSettingsApp_returnsNull()
    public void getCallingAppLabel_getCallingAppPackageNameReturnsSettingsApp_returnsNull()
            throws Exception {
        when(mActivityService.getLaunchedFromPackage(mActivityToken))
                .thenReturn("com.android.settings");
@@ -115,6 +116,23 @@ public class PasswordUtilsTest {
        assertThat(getCallingAppLabel(mContext, mActivityToken)).isEqualTo("label");
    }

    @Test
    public void getCallingAppPackageName_activityServiceThrowsRemoteException_returnsNull()
            throws Exception {
        when(mActivityService.getLaunchedFromPackage(mActivityToken))
                .thenThrow(new RemoteException());

        assertThat(getCallingAppPackageName(mActivityToken)).isNull();
    }

    @Test
    public void getCallingAppPackageName_returnsPackageName() throws Exception {
        when(mActivityService.getLaunchedFromPackage(mActivityToken))
                .thenReturn(PACKAGE_NAME);

        assertThat(getCallingAppPackageName(mActivityToken)).isEqualTo(PACKAGE_NAME);
    }

    @Test
    public void isCallingAppPermitted_permissionGranted_returnsTrue() throws Exception {
        when(mActivityService.getLaunchedFromUid(mActivityToken)).thenReturn(UID);
+106 −0
Original line number Diff line number Diff line
@@ -28,17 +28,26 @@ import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_R

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;

import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -50,11 +59,19 @@ import org.robolectric.shadows.ShadowActivity;
public class SetNewPasswordActivityTest {

    private static final String APP_LABEL = "label";
    private static final String PKG_NAME = "packageName";

    @Mock
    private MetricsFeatureProvider mockMetricsProvider;
    private int mProvisioned;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest();
        mockMetricsProvider = fakeFeatureFactory.getMetricsFeatureProvider();
        when(mockMetricsProvider.getAttribution(any())).thenReturn(SettingsEnums.PAGE_UNKNOWN);

        mProvisioned = Settings.Global.getInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 0);
    }
@@ -98,6 +115,7 @@ public class SetNewPasswordActivityTest {
    @Config(shadows = {ShadowPasswordUtils.class})
    public void testLaunchChooseLock_setNewPasswordExtraWithoutPermission() {
        ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
        ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME);
        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 1);

@@ -108,12 +126,19 @@ public class SetNewPasswordActivityTest {

        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
        assertThat(shadowActivity.getNextStartedActivityForResult()).isNull();
        verify(mockMetricsProvider).action(
                SettingsEnums.PAGE_UNKNOWN,
                SettingsEnums.ACTION_SET_NEW_PASSWORD,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                PKG_NAME,
                PASSWORD_COMPLEXITY_HIGH);
    }

    @Test
    @Config(shadows = {ShadowPasswordUtils.class})
    public void testLaunchChooseLock_setNewPasswordExtraWithPermission() {
        ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
        ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME);
        ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 1);
@@ -131,12 +156,19 @@ public class SetNewPasswordActivityTest {
                .isEqualTo(PASSWORD_COMPLEXITY_HIGH);
        assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
        assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
        verify(mockMetricsProvider).action(
                SettingsEnums.PAGE_UNKNOWN,
                SettingsEnums.ACTION_SET_NEW_PASSWORD,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                PKG_NAME,
                PASSWORD_COMPLEXITY_HIGH);
    }

    @Test
    @Config(shadows = {ShadowPasswordUtils.class})
    public void testLaunchChooseLock_setNewPasswordExtraInvalidValue() {
        ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
        ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME);
        ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 1);
@@ -152,12 +184,19 @@ public class SetNewPasswordActivityTest {
        assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
        assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
        assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
        verify(mockMetricsProvider).action(
                SettingsEnums.PAGE_UNKNOWN,
                SettingsEnums.ACTION_SET_NEW_PASSWORD,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                PKG_NAME,
                -1);
    }

    @Test
    @Config(shadows = {ShadowPasswordUtils.class})
    public void testLaunchChooseLock_setNewPasswordExtraNoneComplexity() {
        ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
        ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME);
        ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 1);
@@ -173,12 +212,46 @@ public class SetNewPasswordActivityTest {
        assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
        assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
        assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
        verify(mockMetricsProvider).action(
                SettingsEnums.PAGE_UNKNOWN,
                SettingsEnums.ACTION_SET_NEW_PASSWORD,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                PKG_NAME,
                PASSWORD_COMPLEXITY_NONE);
    }

    @Test
    @Config(shadows = {ShadowPasswordUtils.class})
    public void testLaunchChooseLock_setNewPasswordWithoutExtra() {
        ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
        ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME);
        ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 1);

        Intent intent = new Intent(ACTION_SET_NEW_PASSWORD);
        SetNewPasswordActivity activity =
                Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();

        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
        Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent;
        assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PASSWORD);
        assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
        assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
        assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
        verify(mockMetricsProvider).action(
                SettingsEnums.PAGE_UNKNOWN,
                SettingsEnums.ACTION_SET_NEW_PASSWORD,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                PKG_NAME,
                Integer.MIN_VALUE);
    }

    @Test
    @Config(shadows = {ShadowPasswordUtils.class})
    public void testLaunchChooseLock_setNewParentProfilePasswordExtraWithPermission() {
        ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
        ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME);
        ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 1);
@@ -194,5 +267,38 @@ public class SetNewPasswordActivityTest {
        assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
        assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
        assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
        verify(mockMetricsProvider).action(
                SettingsEnums.PAGE_UNKNOWN,
                SettingsEnums.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                PKG_NAME,
                PASSWORD_COMPLEXITY_HIGH);
    }

    @Test
    @Config(shadows = {ShadowPasswordUtils.class})
    public void testLaunchChooseLock_setNewParentProfilePasswordWithoutExtra() {
        ShadowPasswordUtils.setCallingAppLabel(APP_LABEL);
        ShadowPasswordUtils.setCallingAppPackageName(PKG_NAME);
        ShadowPasswordUtils.addGrantedPermission(GET_AND_REQUEST_SCREEN_LOCK_COMPLEXITY);
        Settings.Global.putInt(RuntimeEnvironment.application.getContentResolver(),
                Settings.Global.DEVICE_PROVISIONED, 1);

        Intent intent = new Intent(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD);
        SetNewPasswordActivity activity =
                Robolectric.buildActivity(SetNewPasswordActivity.class, intent).create().get();

        ShadowActivity shadowActivity = Shadows.shadowOf(activity);
        Intent actualIntent = shadowActivity.getNextStartedActivityForResult().intent;
        assertThat(actualIntent.getAction()).isEqualTo(ACTION_SET_NEW_PARENT_PROFILE_PASSWORD);
        assertThat(actualIntent.hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)).isFalse();
        assertThat(actualIntent.hasExtra(EXTRA_KEY_CALLER_APP_NAME)).isTrue();
        assertThat(actualIntent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME)).isEqualTo(APP_LABEL);
        verify(mockMetricsProvider).action(
                SettingsEnums.PAGE_UNKNOWN,
                SettingsEnums.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD,
                SettingsEnums.SET_NEW_PASSWORD_ACTIVITY,
                PKG_NAME,
                Integer.MIN_VALUE);
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -32,11 +32,13 @@ import java.util.Set;
public class ShadowPasswordUtils {

    private static String sCallingAppLabel;
    private static String sCallingAppPackageName;
    private static Set<String> sGrantedPermissions;

    public static void reset() {
        sCallingAppLabel = null;
        sGrantedPermissions = null;
        sCallingAppPackageName = null;
    }

    @Implementation
@@ -63,4 +65,13 @@ public class ShadowPasswordUtils {
    public static void setCallingAppLabel(String label) {
        sCallingAppLabel = label;
    }

    @Implementation
    protected static String getCallingAppPackageName(IBinder activityToken) {
        return sCallingAppPackageName;
    }

    public static void setCallingAppPackageName(String packageName) {
        sCallingAppPackageName = packageName;
    }
}