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

Commit f01e4b9a authored by Fengjiang Li's avatar Fengjiang Li Committed by Android (Google) Code Review
Browse files

Merge "Extract widget sizes serialization and deserialization to util class...

Merge "Extract widget sizes serialization and deserialization to util class and add unit test" into main
parents 44507756 7b355716
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>())
    }
}