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

Commit 7b355716 authored by Fengjiang Li's avatar Fengjiang Li
Browse files

Extract widget sizes serialization and deserialization to util class and

add unit test

Bug: 330491827
Flag: NONE
Test: Added unit test
Change-Id: I38ba1116bfac5025a0530d57030531c0cc485295
parent 4086de65
Loading
Loading
Loading
Loading
+6 −14
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.res.Resources.ID_NULL;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;

import static com.android.server.appwidget.AppWidgetXmlUtil.deserializeWidgetSizesStr;
import static com.android.server.appwidget.AppWidgetXmlUtil.serializeWidgetSizes;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;

import android.Manifest;
@@ -164,7 +166,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.LongSupplier;
import java.util.stream.Collectors;

class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider,
        OnCrossProfileWidgetProvidersChangeListener {
@@ -179,7 +180,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    private static final String STATE_FILENAME = "appwidgets.xml";

    private static final String KEY_SIZES = "sizes";
    private static final String SIZE_SEPARATOR = ",";

    private static final int MIN_UPDATE_PERIOD = DEBUG ? 0 : 30 * 60 * 1000; // 30 minutes

@@ -2718,9 +2718,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            List<SizeF> sizes = widget.options.getParcelableArrayList(
                    AppWidgetManager.OPTION_APPWIDGET_SIZES, SizeF.class);
            if (sizes != null) {
                String sizeStr = sizes.stream().map(SizeF::toString)
                        .collect(Collectors.joining(SIZE_SEPARATOR));
                out.attribute(null, KEY_SIZES, sizeStr);
                out.attribute(null, KEY_SIZES, serializeWidgetSizes(sizes));
            }
            if (saveRestoreCompleted) {
                boolean restoreCompleted = widget.options.getBoolean(
@@ -2754,15 +2752,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight);
        }
        String sizesStr = parser.getAttributeValue(null, KEY_SIZES);
        if (sizesStr != null) {
            try {
                ArrayList<SizeF> sizes = Arrays.stream(sizesStr.split(SIZE_SEPARATOR))
                        .map(SizeF::parseSizeF)
                        .collect(Collectors.toCollection(ArrayList::new));
        ArrayList<SizeF> sizes = deserializeWidgetSizesStr(sizesStr);
        if (sizes != null) {
            options.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, sizes);
            } catch (NumberFormatException e) {
                Slog.e(TAG, "Error parsing widget sizes", e);
            }
        }
        int category = parser.getAttributeIntHex(null, "host_category",
                AppWidgetProviderInfo.WIDGET_CATEGORY_UNKNOWN);
+28 −0
Original line number Diff line number Diff line
@@ -22,12 +22,18 @@ import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.os.Build;
import android.text.TextUtils;
import android.util.SizeF;
import android.util.Slog;

import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @hide
@@ -59,6 +65,7 @@ public class AppWidgetXmlUtil {
    private static final String ATTR_DESCRIPTION_RES = "description_res";
    private static final String ATTR_PROVIDER_INHERITANCE = "provider_inheritance";
    private static final String ATTR_OS_FINGERPRINT = "os_fingerprint";
    private static final String SIZE_SEPARATOR = ",";

    /**
     * @hide
@@ -137,4 +144,25 @@ public class AppWidgetXmlUtil {
            ATTR_PROVIDER_INHERITANCE, false);
        return info;
    }

    @NonNull
    static String serializeWidgetSizes(@NonNull List<SizeF> sizes) {
        return sizes.stream().map(SizeF::toString)
                .collect(Collectors.joining(SIZE_SEPARATOR));
    }

    @Nullable
    static ArrayList<SizeF> deserializeWidgetSizesStr(@Nullable String sizesStr) {
        if (sizesStr == null || sizesStr.isEmpty()) {
            return null;
        }
        try {
            return Arrays.stream(sizesStr.split(SIZE_SEPARATOR))
                    .map(SizeF::parseSizeF)
                    .collect(Collectors.toCollection(ArrayList::new));
        } catch (NumberFormatException e) {
            Slog.e(TAG, "Error parsing widget sizes", e);
            return null;
        }
    }
}
+86 −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.appwidget

import android.util.SizeF
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.server.appwidget.AppWidgetXmlUtil.deserializeWidgetSizesStr
import com.android.server.appwidget.AppWidgetXmlUtil.serializeWidgetSizes
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class AppWidgetXmlUtilTest {

    private val sizes = ArrayList<SizeF>()
    private val sizeStr = "1.0x2.1,-9.91x6291.134,0.0x0.0"

    @Before
    fun setup() {
        sizes.add(SizeF(1.0f, 2.1f))
        sizes.add(SizeF(-9.91f, 6291.134f))
        sizes.add(SizeF(0f, 0f))
    }

    @Test
    fun serializeWidgetSizes() {
        val serializedSizeStr = serializeWidgetSizes(sizes)

        assertThat(serializedSizeStr).isEqualTo(sizeStr)
    }

    @Test
    fun deserializeWidgetSizesStr() {
        val deserializedSizes = deserializeWidgetSizesStr(sizeStr)

        assertThat(deserializedSizes).isEqualTo(sizes)
    }

    @Test
    fun deserializeInvalidWidgetSizesStr1() {
        assertThat(deserializeWidgetSizesStr("abc,def")).isEqualTo(null)
    }

    @Test
    fun deserializeInvalidWidgetSizesStr2() {
        assertThat(deserializeWidgetSizesStr("+30x9,90")).isEqualTo(null)
    }

    @Test
    fun deserializeNullWidgetSizesStr1() {
        assertThat(deserializeWidgetSizesStr(null)).isEqualTo(null)
    }

    @Test
    fun deserializeEmptyWidgetSizesStr1() {
        assertThat(deserializeWidgetSizesStr("")).isEqualTo(null)
    }

    @Test
    fun deserializeEmptyWidgetSizesStr2() {
        assertThat(deserializeWidgetSizesStr(",")).isEqualTo(ArrayList<SizeF>())
    }

    @Test
    fun deserializeEmptyWidgetSizesStr3() {
        assertThat(deserializeWidgetSizesStr(",,,")).isEqualTo(ArrayList<SizeF>())
    }
}