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

Commit 40931ce4 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Merge changes If71fadd2,I42047185 am: 022daeb8 am: 6d1da290 am: 5da014a5"

parents a9b6d9c0 d068b930
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25,6 +25,6 @@ oneway interface IOnNetworkAttributesRetrieved {
     * Network attributes were fetched for the specified L2 key. While the L2 key will never
     * be null, the attributes may be if no data is stored about this L2 key.
     */
     void onL2KeyResponse(in StatusParcelable status, in String l2Key,
     void onNetworkAttributesRetrieved(in StatusParcelable status, in String l2Key,
             in NetworkAttributesParcelable attributes);
}
+59 −1
Original line number Diff line number Diff line
@@ -37,27 +37,57 @@ import java.util.StringJoiner;
public class NetworkAttributes {
    private static final boolean DBG = true;

    // Weight cutoff for grouping. To group, a similarity score is computed with the following
    // algorithm : if both fields are non-null and equals() then add their assigned weight, else if
    // both are null then add a portion of their assigned weight (see NULL_MATCH_WEIGHT),
    // otherwise add nothing.
    // As a guideline, this should be something like 60~75% of the total weights in this class. The
    // design states "in essence a reader should imagine that if two important columns don't match,
    // or one important and several unimportant columns don't match then the two records are
    // considered a different group".
    private static final float TOTAL_WEIGHT_CUTOFF = 520.0f;
    // The portion of the weight that is earned when scoring group-sameness by having both columns
    // being null. This is because some networks rightfully don't have some attributes (e.g. a
    // V6-only network won't have an assigned V4 address) and both being null should count for
    // something, but attributes may also be null just because data is unavailable.
    private static final float NULL_MATCH_WEIGHT = 0.25f;

    // The v4 address that was assigned to this device the last time it joined this network.
    // This typically comes from DHCP but could be something else like static configuration.
    // This does not apply to IPv6.
    // TODO : add a list of v6 prefixes for the v6 case.
    @Nullable
    public final Inet4Address assignedV4Address;
    private static final float WEIGHT_ASSIGNEDV4ADDR = 300.0f;

    // Optionally supplied by the client if it has an opinion on L3 network. For example, this
    // could be a hash of the SSID + security type on WiFi.
    @Nullable
    public final String groupHint;
    private static final float WEIGHT_GROUPHINT = 300.0f;

    // The list of DNS server addresses.
    @Nullable
    public final List<InetAddress> dnsAddresses;
    private static final float WEIGHT_DNSADDRESSES = 200.0f;

    // The mtu on this network.
    @Nullable
    public final Integer mtu;
    private static final float WEIGHT_MTU = 50.0f;

    // The sum of all weights in this class. Tests ensure that this stays equal to the total of
    // all weights.
    /** @hide */
    @VisibleForTesting
    public static final float TOTAL_WEIGHT = WEIGHT_ASSIGNEDV4ADDR
            + WEIGHT_GROUPHINT
            + WEIGHT_DNSADDRESSES
            + WEIGHT_MTU;

    NetworkAttributes(
    /** @hide */
    @VisibleForTesting
    public NetworkAttributes(
            @Nullable final Inet4Address assignedV4Address,
            @Nullable final String groupHint,
            @Nullable final List<InetAddress> dnsAddresses,
@@ -126,6 +156,34 @@ public class NetworkAttributes {
        return parcelable;
    }

    private float samenessContribution(final float weight,
            @Nullable final Object o1, @Nullable final Object o2) {
        if (null == o1) {
            return (null == o2) ? weight * NULL_MATCH_WEIGHT : 0f;
        }
        return Objects.equals(o1, o2) ? weight : 0f;
    }

    /** @hide */
    public float getNetworkGroupSamenessConfidence(@NonNull final NetworkAttributes o) {
        final float samenessScore =
                samenessContribution(WEIGHT_ASSIGNEDV4ADDR, assignedV4Address, o.assignedV4Address)
                + samenessContribution(WEIGHT_GROUPHINT, groupHint, o.groupHint)
                + samenessContribution(WEIGHT_DNSADDRESSES, dnsAddresses, o.dnsAddresses)
                + samenessContribution(WEIGHT_MTU, mtu, o.mtu);
        // The minimum is 0, the max is TOTAL_WEIGHT and should be represented by 1.0, and
        // TOTAL_WEIGHT_CUTOFF should represent 0.5, but there is no requirement that
        // TOTAL_WEIGHT_CUTOFF would be half of TOTAL_WEIGHT (indeed, it should not be).
        // So scale scores under the cutoff between 0 and 0.5, and the scores over the cutoff
        // between 0.5 and 1.0.
        if (samenessScore < TOTAL_WEIGHT_CUTOFF) {
            return samenessScore / (TOTAL_WEIGHT_CUTOFF * 2);
        } else {
            return (samenessScore - TOTAL_WEIGHT_CUTOFF) / (TOTAL_WEIGHT - TOTAL_WEIGHT_CUTOFF) / 2
                    + 0.5f;
        }
    }

    /** @hide */
    public static class Builder {
        @Nullable
+2 −1
Original line number Diff line number Diff line
@@ -91,7 +91,8 @@ public class SameL3NetworkResponse {
        return confidence > 0.5 ? NETWORK_SAME : NETWORK_DIFFERENT;
    }

    SameL3NetworkResponse(@NonNull final String l2Key1, @NonNull final String l2Key2,
    /** @hide */
    public SameL3NetworkResponse(@NonNull final String l2Key1, @NonNull final String l2Key2,
            final float confidence) {
        this.l2Key1 = l2Key1;
        this.l2Key2 = l2Key2;
+12 −3
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 * Copyright (C) 2019 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.
@@ -134,12 +134,14 @@ public class IpMemoryStoreDatabase {
        }

        /** Called when the database is created */
        @Override
        public void onCreate(@NonNull final SQLiteDatabase db) {
            db.execSQL(NetworkAttributesContract.CREATE_TABLE);
            db.execSQL(PrivateDataContract.CREATE_TABLE);
        }

        /** Called when the database is upgraded */
        @Override
        public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion,
                final int newVersion) {
            // No upgrade supported yet.
@@ -149,6 +151,7 @@ public class IpMemoryStoreDatabase {
        }

        /** Called when the database is downgraded */
        @Override
        public void onDowngrade(@NonNull final SQLiteDatabase db, final int oldVersion,
                final int newVersion) {
            // Downgrades always nuke all data and recreate an empty table.
@@ -247,7 +250,9 @@ public class IpMemoryStoreDatabase {
        // result here. 0 results means the key was not found.
        if (cursor.getCount() != 1) return EXPIRY_ERROR;
        cursor.moveToFirst();
        return cursor.getLong(0); // index in the EXPIRY_COLUMN array
        final long result = cursor.getLong(0); // index in the EXPIRY_COLUMN array
        cursor.close();
        return result;
    }

    static final int RELEVANCE_ERROR = -1; // Legal values for relevance are positive
@@ -321,6 +326,8 @@ public class IpMemoryStoreDatabase {
        final byte[] dnsAddressesBlob =
                getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES);
        final int mtu = getInt(cursor, NetworkAttributesContract.COLNAME_MTU, -1);
        cursor.close();

        if (0 != assignedV4AddressInt) {
            builder.setAssignedV4Address(NetworkUtils.intToInet4AddressHTH(assignedV4AddressInt));
        }
@@ -353,7 +360,9 @@ public class IpMemoryStoreDatabase {
        // get more than one result here. 0 results means the key was not found.
        if (cursor.getCount() != 1) return null;
        cursor.moveToFirst();
        return cursor.getBlob(0); // index in the DATA_COLUMN array
        final byte[] result = cursor.getBlob(0); // index in the DATA_COLUMN array
        cursor.close();
        return result;
    }

    // Helper methods
+41 −8
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.net.ipmemorystore.IOnSameNetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.NetworkAttributesParcelable;
import android.net.ipmemorystore.SameL3NetworkResponse;
import android.net.ipmemorystore.Status;
import android.net.ipmemorystore.StatusParcelable;
import android.net.ipmemorystore.Utils;
@@ -264,9 +265,40 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub {
     * Through the listener, a SameL3NetworkResponse containing the answer and confidence.
     */
    @Override
    public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2,
            @NonNull final IOnSameNetworkResponseListener listener) {
        // TODO : implement this.
    public void isSameNetwork(@Nullable final String l2Key1, @Nullable final String l2Key2,
            @Nullable final IOnSameNetworkResponseListener listener) {
        if (null == listener) return;
        mExecutor.execute(() -> {
            try {
                if (null == l2Key1 || null == l2Key2) {
                    listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
                    return;
                }
                if (null == mDb) {
                    listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
                    return;
                }
                try {
                    final NetworkAttributes attr1 =
                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key1);
                    final NetworkAttributes attr2 =
                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key2);
                    if (null == attr1 || null == attr2) {
                        listener.onSameNetworkResponse(makeStatus(SUCCESS),
                                new SameL3NetworkResponse(l2Key1, l2Key2,
                                        -1f /* never connected */).toParcelable());
                        return;
                    }
                    final float confidence = attr1.getNetworkGroupSamenessConfidence(attr2);
                    listener.onSameNetworkResponse(makeStatus(SUCCESS),
                            new SameL3NetworkResponse(l2Key1, l2Key2, confidence).toParcelable());
                } catch (Exception e) {
                    listener.onSameNetworkResponse(makeStatus(ERROR_GENERIC), null);
                }
            } catch (final RemoteException e) {
                // Client at the other end died
            }
        });
    }

    /**
@@ -285,21 +317,22 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub {
        mExecutor.execute(() -> {
            try {
                if (null == l2Key) {
                    listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, null);
                    listener.onNetworkAttributesRetrieved(
                            makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, null);
                    return;
                }
                if (null == mDb) {
                    listener.onL2KeyResponse(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key,
                            null);
                    listener.onNetworkAttributesRetrieved(
                            makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key, null);
                    return;
                }
                try {
                    final NetworkAttributes attributes =
                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key);
                    listener.onL2KeyResponse(makeStatus(SUCCESS), l2Key,
                    listener.onNetworkAttributesRetrieved(makeStatus(SUCCESS), l2Key,
                            null == attributes ? null : attributes.toParcelable());
                } catch (final Exception e) {
                    listener.onL2KeyResponse(makeStatus(ERROR_GENERIC), l2Key, null);
                    listener.onNetworkAttributesRetrieved(makeStatus(ERROR_GENERIC), l2Key, null);
                }
            } catch (final RemoteException e) {
                // Client at the other end died
Loading