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

Commit cb2d6e87 authored by Haoran Zhang's avatar Haoran Zhang Committed by Android (Google) Code Review
Browse files

Merge "[Autofill Frameowork] Refactor get save info stats function into...

Merge "[Autofill Frameowork] Refactor get save info stats function into autofill.Helper class" into main
parents 20d8905e 194dd340
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -31,12 +31,14 @@ import android.hardware.display.DisplayManager;
import android.metrics.LogMaker;
import android.os.UserManager;
import android.service.autofill.Dataset;
import android.service.autofill.FillResponse;
import android.service.autofill.InternalSanitizer;
import android.service.autofill.SaveInfo;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
@@ -374,4 +376,50 @@ public final class Helper {
    private interface ViewNodeFilter {
        boolean matches(ViewNode node);
    }

    public static class SaveInfoStats {
        public int saveInfoCount;
        public int saveDataTypeCount;

        public SaveInfoStats(int saveInfoCount, int saveDataTypeCount) {
            this.saveInfoCount = saveInfoCount;
            this.saveDataTypeCount = saveDataTypeCount;
        }
    }

    /**
     * Get statistic information of save info given a sparse array of fill responses.
     *
     * Specifically the statistic includes
     *   1. how many save info the current session has.
     *   2. How many distinct save data types current session has.
     *
     * @return SaveInfoStats returns the above two number in a SaveInfoStats object
     */
    public static SaveInfoStats getSaveInfoStatsFromFillResponses(
            SparseArray<FillResponse> fillResponses) {
        if (fillResponses == null) {
            if (sVerbose) {
                Slog.v(TAG, "getSaveInfoStatsFromFillResponses(): fillResponse sparse array is "
                        + "null");
            }
            return new SaveInfoStats(-1, -1);
        }
        int numSaveInfos = 0;
        int numSaveDataTypes = 0;
        ArraySet<Integer> saveDataTypeSeen = new ArraySet<>();
        final int numResponses = fillResponses.size();
        for (int responseNum = 0; responseNum < numResponses; responseNum++) {
            final FillResponse response = fillResponses.valueAt(responseNum);
            if (response != null && response.getSaveInfo() != null) {
                numSaveInfos += 1;
                int saveDataType = response.getSaveInfo().getType();
                if (!saveDataTypeSeen.contains(saveDataType)) {
                    saveDataTypeSeen.add(saveDataType);
                    numSaveDataTypes += 1;
                }
            }
        }
        return new SaveInfoStats(numSaveInfos, numSaveDataTypes);
    }
}
+3 −36
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import static com.android.server.autofill.FillResponseEventLogger.RESPONSE_STATU
import static com.android.server.autofill.Helper.containsCharsInOrder;
import static com.android.server.autofill.Helper.createSanitizers;
import static com.android.server.autofill.Helper.getNumericValue;
import static com.android.server.autofill.Helper.SaveInfoStats;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
import static com.android.server.autofill.Helper.toArray;
@@ -3203,11 +3204,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        return saveInfo == null ? 0 : saveInfo.getFlags();
    }

    static class SaveInfoStats {
        public int saveInfoCount;
        public int saveDataTypeCount;
    }

    /**
     * Get statistic information of save info in current session. Specifically
     *   1. how many save info the current session has.
@@ -3217,42 +3213,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
     */
    @GuardedBy("mLock")
    private SaveInfoStats getSaveInfoStatsLocked() {
        SaveInfoStats retSaveInfoStats = new SaveInfoStats();
        retSaveInfoStats.saveInfoCount = -1;
        retSaveInfoStats.saveDataTypeCount = -1;

        if (mContexts == null) {
            if (sVerbose) {
                Slog.v(TAG, "getSaveInfoStatsLocked(): mContexts is null");
            }
        } else if (mResponses == null) {
            // Happens when the activity / session was finished before the service replied, or
            // when the service cannot autofill it (and returned a null response).
            if (sVerbose) {
                Slog.v(TAG, "getSaveInfoStatsLocked(): mResponses is null");
            return new SaveInfoStats(-1, -1);
        }
            return retSaveInfoStats;
        } else {
            int numSaveInfos = 0;
            int numSaveDataTypes = 0;
            ArraySet<Integer> saveDataTypeSeen = new ArraySet<>();
            final int numResponses = mResponses.size();
            for (int responseNum = 0; responseNum < numResponses; responseNum++) {
                final FillResponse response = mResponses.valueAt(responseNum);
                if (response != null && response.getSaveInfo() != null) {
                    numSaveInfos += 1;
                    int saveDataType = response.getSaveInfo().getType();
                    if (!saveDataTypeSeen.contains(saveDataType)) {
                        saveDataTypeSeen.add(saveDataType);
                        numSaveDataTypes += 1;
                    }
                }
            }
            retSaveInfoStats.saveInfoCount = numSaveInfos;
            retSaveInfoStats.saveDataTypeCount = numSaveDataTypes;
        }

        return retSaveInfoStats;
        return Helper.getSaveInfoStatsFromFillResponses(mResponses);
    }

    /**
+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.server.autofill;

import static com.android.server.autofill.Helper.SaveInfoStats;
import static com.android.server.autofill.Helper.getSaveInfoStatsFromFillResponses;

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

import android.os.Bundle;
import android.service.autofill.FillResponse;
import android.service.autofill.SaveInfo;
import android.util.SparseArray;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class HelperTest {

    @Test
    public void testGetSaveInfoStatsFromFillResponses_nullFillResponses() {
        SaveInfoStats saveInfoStats = getSaveInfoStatsFromFillResponses(null);

        assertThat(saveInfoStats.saveInfoCount).isEqualTo(-1);
        assertThat(saveInfoStats.saveDataTypeCount).isEqualTo(-1);
    }

    @Test
    public void testGetSaveInfoStatsFromFillResponses_emptyFillResponseSparseArray() {
        SaveInfoStats saveInfoStats = getSaveInfoStatsFromFillResponses(new SparseArray<>());

        assertThat(saveInfoStats.saveInfoCount).isEqualTo(0);
        assertThat(saveInfoStats.saveDataTypeCount).isEqualTo(0);
    }

    @Test
    public void testGetSaveInfoStatsFromFillResponses_singleResponseWithoutSaveInfo() {
        FillResponse.Builder fillResponseBuilder = new FillResponse.Builder();
        // Add client state to satisfy the sanity check in FillResponseBuilder.build()
        Bundle clientState = new Bundle();
        fillResponseBuilder.setClientState(clientState);
        FillResponse testFillResponse = fillResponseBuilder.build();

        SparseArray<FillResponse> testFillResponses = new SparseArray<>();
        testFillResponses.put(0, testFillResponse);

        SaveInfoStats saveInfoStats = getSaveInfoStatsFromFillResponses(testFillResponses);

        assertThat(saveInfoStats.saveInfoCount).isEqualTo(0);
        assertThat(saveInfoStats.saveDataTypeCount).isEqualTo(0);
    }

    @Test
    public void testGetSaveInfoStatsFromFillResponses_singleResponseWithSaveInfo() {
        FillResponse.Builder fillResponseBuilder = new FillResponse.Builder();
        SaveInfo.Builder saveInfoBuilder = new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_GENERIC);
        fillResponseBuilder.setSaveInfo(saveInfoBuilder.build());
        FillResponse testFillResponse = fillResponseBuilder.build();

        SparseArray<FillResponse> testFillResponses = new SparseArray<>();
        testFillResponses.put(0, testFillResponse);

        SaveInfoStats saveInfoStats = getSaveInfoStatsFromFillResponses(testFillResponses);

        assertThat(saveInfoStats.saveInfoCount).isEqualTo(1);
        assertThat(saveInfoStats.saveDataTypeCount).isEqualTo(1);
    }

    @Test
    public void testGetSaveInfoStatsFromFillResponses_multipleResponseWithDifferentTypeSaveInfo() {
        FillResponse.Builder fillResponseBuilder1 = new FillResponse.Builder();
        SaveInfo.Builder saveInfoBuilder1 = new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_GENERIC);
        fillResponseBuilder1.setSaveInfo(saveInfoBuilder1.build());
        FillResponse testFillResponse1 = fillResponseBuilder1.build();

        FillResponse.Builder fillResponseBuilder2 = new FillResponse.Builder();
        SaveInfo.Builder saveInfoBuilder2 = new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_ADDRESS);
        fillResponseBuilder2.setSaveInfo(saveInfoBuilder2.build());
        FillResponse testFillResponse2 = fillResponseBuilder2.build();

        FillResponse.Builder fillResponseBuilder3 = new FillResponse.Builder();
        SaveInfo.Builder saveInfoBuilder3 = new SaveInfo.Builder(SaveInfo.SAVE_DATA_TYPE_ADDRESS);
        fillResponseBuilder3.setSaveInfo(saveInfoBuilder3.build());
        FillResponse testFillResponse3 = fillResponseBuilder3.build();

        SparseArray<FillResponse> testFillResponses = new SparseArray<>();
        testFillResponses.put(0, testFillResponse1);
        testFillResponses.put(1, testFillResponse2);
        testFillResponses.put(2, testFillResponse3);

        SaveInfoStats saveInfoStats = getSaveInfoStatsFromFillResponses(testFillResponses);

        // Save info count is 3. Since two save info share the same save data type, the distinct
        // save data type count is 2.
        assertThat(saveInfoStats.saveInfoCount).isEqualTo(3);
        assertThat(saveInfoStats.saveDataTypeCount).isEqualTo(2);
    }
}