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

Commit 6e3428c7 authored by Yanting Yang's avatar Yanting Yang Committed by Android (Google) Code Review
Browse files

Merge "Support dynamic search index for App pinning" into main

parents caa9338d 12b8d823
Loading
Loading
Loading
Loading
+34 −7
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.icu.text.MessageFormat;
import android.os.Bundle;
import android.os.UserHandle;
@@ -30,6 +31,7 @@ import android.provider.Settings;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
@@ -45,7 +47,11 @@ import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.widget.FooterPreference;

import java.util.List;

/**
 * Screen pinning settings.
 */
@@ -174,9 +180,8 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
        }
    }

    private int getCurrentSecurityTitle() {
        int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(
                UserHandle.myUserId());
    private static int getCurrentSecurityTitle(LockPatternUtils lockPatternUtils) {
        int quality = lockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId());
        switch (quality) {
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
@@ -187,7 +192,7 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
            case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
                return R.string.screen_pinning_unlock_password;
            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                if (mLockPatternUtils.isLockPatternEnabled(UserHandle.myUserId())) {
                if (lockPatternUtils.isLockPatternEnabled(UserHandle.myUserId())) {
                    return R.string.screen_pinning_unlock_pattern;
                }
        }
@@ -232,7 +237,7 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
                }
            });
            mUseScreenLock.setChecked(isScreenLockUsed());
            mUseScreenLock.setTitle(getCurrentSecurityTitle());
            mUseScreenLock.setTitle(getCurrentSecurityTitle(mLockPatternUtils));
        } else {
            mFooterPreference.setSummary(getAppPinningContent());
            mUseScreenLock.setEnabled(false);
@@ -252,8 +257,30 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
    }

    /**
     * For search
     * For search.
     *
     * This page only provides an index for the toggle preference of using screen lock for
     * unpinning. The preference name will change with various lock configurations. Indexing data
     * from XML isn't suitable since it uses a static title by default. So, we skip XML indexing
     * by omitting the XML argument in the constructor and use a dynamic index method instead.
     */
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.screen_pinning_settings);
            new BaseSearchIndexProvider() {

                @NonNull
                @Override
                public List<SearchIndexableRaw> getDynamicRawDataToIndex(@NonNull Context context,
                        boolean enabled) {
                    List<SearchIndexableRaw> dynamicRaws =
                            super.getDynamicRawDataToIndex(context, enabled);
                    final SearchIndexableRaw raw = new SearchIndexableRaw(context);
                    final Resources res = context.getResources();
                    final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
                    raw.key = KEY_USE_SCREEN_LOCK;
                    raw.title = res.getString(getCurrentSecurityTitle(lockPatternUtils));
                    raw.screenTitle = res.getString(R.string.screen_pinning_title);
                    dynamicRaws.add(raw);
                    return dynamicRaws;
                }
            };
}
+113 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.settings.security;

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

import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserHandle;

import androidx.test.core.app.ApplicationProvider;

import com.android.settings.R;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settingslib.search.SearchIndexableRaw;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import java.util.List;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowLockPatternUtils.class)
public class ScreenPinningSettingsTest {

    private Context mContext;

    @Before
    public void setUp() {
        mContext = ApplicationProvider.getApplicationContext();
    }

    @After
    public void tearDown() {
        ShadowLockPatternUtils.reset();
    }

    @Test
    public void getDynamicRawDataToIndex_numericPassword_shouldIndexUnlockPinTitle() {
        ShadowLockPatternUtils.setKeyguardStoredPasswordQuality(
                DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);

        final List<SearchIndexableRaw> indexRaws =
                ScreenPinningSettings.SEARCH_INDEX_DATA_PROVIDER.getDynamicRawDataToIndex(
                        mContext, /* enabled= */ true);

        assertThat(indexRaws.size()).isEqualTo(1);
        assertThat(indexRaws.get(0).title).isEqualTo(
                mContext.getString(R.string.screen_pinning_unlock_pin));
    }

    @Test
    public void getDynamicRawDataToIndex_alphabeticPassword_shouldIndexUnlockPasswordTitle() {
        ShadowLockPatternUtils.setKeyguardStoredPasswordQuality(
                DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);

        final List<SearchIndexableRaw> indexRaws =
                ScreenPinningSettings.SEARCH_INDEX_DATA_PROVIDER.getDynamicRawDataToIndex(
                        mContext, /* enabled= */ true);

        assertThat(indexRaws.size()).isEqualTo(1);
        assertThat(indexRaws.get(0).title).isEqualTo(
                mContext.getString(R.string.screen_pinning_unlock_password));
    }

    @Test
    public void getDynamicRawDataToIndex_patternPassword_shouldIndexUnlockPatternTitle() {
        ShadowLockPatternUtils.setKeyguardStoredPasswordQuality(
                DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
        ShadowLockPatternUtils.setIsLockPatternEnabled(
                UserHandle.myUserId(), /* isLockPatternEnabled= */ true);

        final List<SearchIndexableRaw> indexRaws =
                ScreenPinningSettings.SEARCH_INDEX_DATA_PROVIDER.getDynamicRawDataToIndex(
                        mContext, /* enabled= */ true);

        assertThat(indexRaws.size()).isEqualTo(1);
        assertThat(indexRaws.get(0).title).isEqualTo(
                mContext.getString(R.string.screen_pinning_unlock_pattern));
    }

    @Test
    public void getDynamicRawDataToIndex_nonePassword_shouldIndexUnlockNoneTitle() {
        ShadowLockPatternUtils.setKeyguardStoredPasswordQuality(
                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);

        final List<SearchIndexableRaw> indexRaws =
                ScreenPinningSettings.SEARCH_INDEX_DATA_PROVIDER.getDynamicRawDataToIndex(
                        mContext, /* enabled= */ true);

        assertThat(indexRaws.size()).isEqualTo(1);
        assertThat(indexRaws.get(0).title).isEqualTo(
                mContext.getString(R.string.screen_pinning_unlock_none));
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ public class ShadowLockPatternUtils {
    private static Map<Integer, Boolean> sUserToVisiblePatternEnabledMap = new HashMap<>();
    private static Map<Integer, Boolean> sUserToBiometricAllowedMap = new HashMap<>();
    private static Map<Integer, Boolean> sUserToLockPatternEnabledMap = new HashMap<>();
    private static Map<Integer, Integer> sKeyguardStoredPasswordQualityMap = new HashMap<>();

    private static boolean sIsUserOwnsFrpCredential;

@@ -66,6 +67,7 @@ public class ShadowLockPatternUtils {
        sUserToLockPatternEnabledMap.clear();
        sDeviceEncryptionEnabled = false;
        sIsUserOwnsFrpCredential = false;
        sKeyguardStoredPasswordQualityMap.clear();
    }

    @Implementation
@@ -97,7 +99,7 @@ public class ShadowLockPatternUtils {

    @Implementation
    protected int getKeyguardStoredPasswordQuality(int userHandle) {
        return 1;
        return sKeyguardStoredPasswordQualityMap.getOrDefault(userHandle, /* defaultValue= */ 1);
    }

    @Implementation
@@ -171,7 +173,7 @@ public class ShadowLockPatternUtils {

    @Implementation
    public boolean isLockPatternEnabled(int userId) {
        return sUserToBiometricAllowedMap.getOrDefault(userId, false);
        return sUserToLockPatternEnabledMap.getOrDefault(userId, false);
    }

    public static void setIsLockPatternEnabled(int userId, boolean isLockPatternEnabled) {
@@ -238,4 +240,8 @@ public class ShadowLockPatternUtils {
    public boolean isSeparateProfileChallengeEnabled(int userHandle) {
        return false;
    }

    public static void setKeyguardStoredPasswordQuality(int quality) {
        sKeyguardStoredPasswordQualityMap.put(UserHandle.myUserId(), quality);
    }
}