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

Commit 650ee7a1 authored by Junyu Lai's avatar Junyu Lai
Browse files

[MS01] Move NetworkTemplate cloud backup functions to NetworkPolicy

Since NetworkTemplate will be moved into the mainline module.
It is necessary to remove hidden BackupUtil usage from
NetworkTemplate. Also, it is also a hazard to maintain
compatibility for byte buffer interfaces.

Thus, move out these cloud backup functions to NetworkPolicy
to address these concerns.

Test: atest NetworkPolicyTest NetworkPolicyManagerServiceTest
Bug: 204830222
Change-Id: I3ec55f7e419ea13db535acff2457d8e7aaebdce8
parent fa86f6ab
Loading
Loading
Loading
Loading
+82 −2
Original line number Diff line number Diff line
@@ -16,11 +16,19 @@

package android.net;

import static android.net.NetworkStats.METERED_ALL;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkTemplate.MATCH_CARRIER;
import static android.net.NetworkTemplate.MATCH_MOBILE;
import static android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.BackupUtils;
import android.util.Log;
import android.util.Range;
import android.util.RecurrenceRule;

@@ -42,10 +50,25 @@ import java.util.Objects;
 * @hide
 */
public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
    private static final String TAG = NetworkPolicy.class.getSimpleName();
    private static final int VERSION_INIT = 1;
    private static final int VERSION_RULE = 2;
    private static final int VERSION_RAPID = 3;

    /**
     * Initial Version of the NetworkTemplate backup serializer.
     */
    private static final int TEMPLATE_BACKUP_VERSION_1_INIT = 1;
    /**
     * Version of the NetworkTemplate backup serializer that added carrier template support.
     */
    private static final int TEMPLATE_BACKUP_VERSION_2_SUPPORT_CARRIER_TEMPLATE = 2;
    /**
     * Latest Version of the NetworkTemplate Backup Serializer.
     */
    private static final int TEMPLATE_BACKUP_VERSION_LATEST =
            TEMPLATE_BACKUP_VERSION_2_SUPPORT_CARRIER_TEMPLATE;

    public static final int CYCLE_NONE = -1;
    public static final long WARNING_DISABLED = -1;
    public static final long LIMIT_DISABLED = -1;
@@ -255,7 +278,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
        DataOutputStream out = new DataOutputStream(baos);

        out.writeInt(VERSION_RAPID);
        out.write(template.getBytesForBackup());
        out.write(getNetworkTemplateBytesForBackup());
        cycleRule.writeToStream(out);
        out.writeLong(warningBytes);
        out.writeLong(limitBytes);
@@ -274,7 +297,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
            throw new BackupUtils.BadVersionException("Unknown backup version: " + version);
        }

        final NetworkTemplate template = NetworkTemplate.getNetworkTemplateFromBackup(in);
        final NetworkTemplate template = getNetworkTemplateFromBackup(in);
        final RecurrenceRule cycleRule;
        if (version >= VERSION_RULE) {
            cycleRule = new RecurrenceRule(in);
@@ -298,4 +321,61 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
        return new NetworkPolicy(template, cycleRule, warningBytes, limitBytes, lastWarningSnooze,
                lastLimitSnooze, lastRapidSnooze, metered, inferred);
    }

    @NonNull
    private byte[] getNetworkTemplateBytesForBackup() throws IOException {
        if (!template.isPersistable()) {
            Log.wtf(TAG, "Trying to backup non-persistable template: " + this);
        }

        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final DataOutputStream out = new DataOutputStream(baos);

        out.writeInt(TEMPLATE_BACKUP_VERSION_LATEST);

        out.writeInt(template.getMatchRule());
        BackupUtils.writeString(out, template.getSubscriberId());
        BackupUtils.writeString(out, template.getNetworkId());
        out.writeInt(template.getMeteredness());
        out.writeInt(template.getSubscriberIdMatchRule());

        return baos.toByteArray();
    }

    @NonNull
    private static NetworkTemplate getNetworkTemplateFromBackup(DataInputStream in)
            throws IOException, BackupUtils.BadVersionException {
        int version = in.readInt();
        if (version < TEMPLATE_BACKUP_VERSION_1_INIT || version > TEMPLATE_BACKUP_VERSION_LATEST) {
            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
        }

        int matchRule = in.readInt();
        final String subscriberId = BackupUtils.readString(in);
        final String networkId = BackupUtils.readString(in);

        final int metered;
        final int subscriberIdMatchRule;
        if (version >= TEMPLATE_BACKUP_VERSION_2_SUPPORT_CARRIER_TEMPLATE) {
            metered = in.readInt();
            subscriberIdMatchRule = in.readInt();
        } else {
            // For backward compatibility, fill the missing filters from match rules.
            metered = (matchRule == MATCH_MOBILE
                    || matchRule == NetworkTemplate.MATCH_MOBILE_WILDCARD
                    || matchRule == MATCH_CARRIER) ? METERED_YES : METERED_ALL;
            subscriberIdMatchRule = SUBSCRIBER_ID_MATCH_RULE_EXACT;
        }

        try {
            return new NetworkTemplate(matchRule,
                    subscriberId, new String[]{subscriberId},
                    networkId, metered, NetworkStats.ROAMING_ALL,
                    NetworkStats.DEFAULT_NETWORK_ALL, NetworkTemplate.NETWORK_TYPE_ALL,
                    NetworkTemplate.OEM_MANAGED_ALL, subscriberIdMatchRule);
        } catch (IllegalArgumentException e) {
            throw new BackupUtils.BadVersionException(
                    "Restored network template contains unknown match rule " + matchRule, e);
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ android_test {
        "androidx.test.ext.junit",
        "androidx.test.runner",
        "androidx.test.rules",
        "kotlin-test",
        "mockito-target-minus-junit4",
        "ub-uiautomator",
        "platform-test-annotations",
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 android.net

import android.text.format.Time.TIMEZONE_UTC
import androidx.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import java.io.ByteArrayInputStream
import java.io.DataInputStream
import java.time.ZoneId
import kotlin.test.assertEquals

private const val TEST_IMSI1 = "TESTIMSI1"
private const val TEST_SSID1 = "TESTISSID1"

@RunWith(AndroidJUnit4::class)
class NetworkPolicyTest {
    @Test
    fun testTemplateBackupRestore() {
        assertPolicyBackupRestore(createTestPolicyForTemplate(
                NetworkTemplate.buildTemplateWifi(TEST_SSID1)))
        assertPolicyBackupRestore(createTestPolicyForTemplate(
                NetworkTemplate.buildTemplateMobileAll(TEST_IMSI1)))
        assertPolicyBackupRestore(createTestPolicyForTemplate(
                NetworkTemplate.buildTemplateCarrierMetered(TEST_IMSI1)))
    }

    private fun createTestPolicyForTemplate(template: NetworkTemplate): NetworkPolicy {
        return NetworkPolicy(template, NetworkPolicy.buildRule(5, ZoneId.of(TIMEZONE_UTC)),
                NetworkPolicy.WARNING_DISABLED, NetworkPolicy.LIMIT_DISABLED,
                NetworkPolicy.SNOOZE_NEVER, NetworkPolicy.SNOOZE_NEVER, NetworkPolicy.SNOOZE_NEVER,
                /*metered*/ false, /*inferred*/ true)
    }

    private fun assertPolicyBackupRestore(policy: NetworkPolicy) {
        val bytes = policy.bytesForBackup
        val stream = DataInputStream(ByteArrayInputStream(bytes))
        val restored = NetworkPolicy.getNetworkPolicyFromBackup(stream)
        assertEquals(policy, restored)
    }
}
 No newline at end of file
+0 −73
Original line number Diff line number Diff line
@@ -44,16 +44,10 @@ import android.os.Parcelable;
import android.telephony.Annotation.NetworkType;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.BackupUtils;
import android.util.Log;

import com.android.internal.util.ArrayUtils;
import com.android.net.module.util.NetworkIdentityUtils;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@@ -69,19 +63,6 @@ import java.util.Objects;
public class NetworkTemplate implements Parcelable {
    private static final String TAG = "NetworkTemplate";

    /**
     * Initial Version of the backup serializer.
     */
    public static final int BACKUP_VERSION_1_INIT = 1;
    /**
     * Version of the backup serializer that added carrier template support.
     */
    public static final int BACKUP_VERSION_2_SUPPORT_CARRIER_TEMPLATE = 2;
    /**
     * Current Version of the Backup Serializer.
     */
    private static final int BACKUP_VERSION = BACKUP_VERSION_2_SUPPORT_CARRIER_TEMPLATE;

    public static final int MATCH_MOBILE = 1;
    public static final int MATCH_WIFI = 4;
    public static final int MATCH_ETHERNET = 5;
@@ -849,58 +830,4 @@ public class NetworkTemplate implements Parcelable {
            return new NetworkTemplate[size];
        }
    };

    public byte[] getBytesForBackup() throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(baos);

        if (!isPersistable()) {
            Log.wtf(TAG, "Trying to backup non-persistable template: " + this);
        }

        out.writeInt(BACKUP_VERSION);

        out.writeInt(mMatchRule);
        BackupUtils.writeString(out, mSubscriberId);
        BackupUtils.writeString(out, mNetworkId);
        out.writeInt(mMetered);
        out.writeInt(mSubscriberIdMatchRule);

        return baos.toByteArray();
    }

    public static NetworkTemplate getNetworkTemplateFromBackup(DataInputStream in)
            throws IOException, BackupUtils.BadVersionException {
        int version = in.readInt();
        if (version < BACKUP_VERSION_1_INIT || version > BACKUP_VERSION) {
            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
        }

        int matchRule = in.readInt();
        String subscriberId = BackupUtils.readString(in);
        String networkId = BackupUtils.readString(in);

        final int metered;
        final int subscriberIdMatchRule;
        if (version >= BACKUP_VERSION_2_SUPPORT_CARRIER_TEMPLATE) {
            metered = in.readInt();
            subscriberIdMatchRule = in.readInt();
        } else {
            // For backward compatibility, fill the missing filters from match rules.
            metered = (matchRule == MATCH_MOBILE || matchRule == MATCH_MOBILE_WILDCARD
                    || matchRule == MATCH_CARRIER) ? METERED_YES : METERED_ALL;
            subscriberIdMatchRule = SUBSCRIBER_ID_MATCH_RULE_EXACT;
        }

        try {
            return new NetworkTemplate(matchRule,
                    subscriberId, new String[] { subscriberId },
                    networkId, metered, NetworkStats.ROAMING_ALL,
                    NetworkStats.DEFAULT_NETWORK_ALL, NetworkTemplate.NETWORK_TYPE_ALL,
                    NetworkTemplate.OEM_MANAGED_ALL, subscriberIdMatchRule);
        } catch (IllegalArgumentException e) {
            throw new BackupUtils.BadVersionException(
                    "Restored network template contains unknown match rule " + matchRule, e);
        }
    }
}