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

Commit de933af7 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN
Browse files

Add API for tethering clients change

Add a onClientsChanged callback to OnTetheringEventCallback.

The callback will provide information on connected clients combining
at least DHCP leases and WiFi AP information (WiFi AP tethering used).

Test: atest TetheringTests
Bug: 135411507
Change-Id: I7065d081c11bc606d691f76ac8b499dd075d6504
parent e8b9d755
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -5198,6 +5198,24 @@ package android.net {
    method public boolean satisfiedBy(android.net.NetworkSpecifier);
  }
  public final class TetheredClient implements android.os.Parcelable {
    ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
    method public int describeContents();
    method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
    method @NonNull public android.net.MacAddress getMacAddress();
    method public int getTetheringType();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
  }
  public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public android.net.LinkAddress getAddress();
    method @Nullable public String getHostname();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
  }
  public class TetheringManager {
    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
@@ -5246,6 +5264,7 @@ package android.net {
  public abstract static class TetheringManager.TetheringEventCallback {
    ctor public TetheringManager.TetheringEventCallback();
    method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
    method public void onError(@NonNull String, int);
    method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
    method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+19 −0
Original line number Diff line number Diff line
@@ -1623,6 +1623,24 @@ package android.net {
    method public void teardownTestNetwork(@NonNull android.net.Network);
  }

  public final class TetheredClient implements android.os.Parcelable {
    ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
    method public int describeContents();
    method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
    method @NonNull public android.net.MacAddress getMacAddress();
    method public int getTetheringType();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
  }

  public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public android.net.LinkAddress getAddress();
    method @Nullable public String getHostname();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
  }

  public class TetheringManager {
    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
    method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
@@ -1671,6 +1689,7 @@ package android.net {

  public abstract static class TetheringManager.TetheringEventCallback {
    ctor public TetheringManager.TetheringEventCallback();
    method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
    method public void onError(@NonNull String, int);
    method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
    method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+12 −1
Original line number Diff line number Diff line
@@ -19,7 +19,15 @@ aidl_interface {
    local_include_dir: "src",
    include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
    srcs: [
        "src/android/net/*.aidl",
        // @JavaOnlyStableParcelable aidl declarations must not be listed here, as this would cause
        // compilation to fail (b/148001843).
        "src/android/net/IIntResultListener.aidl",
        "src/android/net/ITetheringConnector.aidl",
        "src/android/net/ITetheringEventCallback.aidl",
        "src/android/net/TetheringCallbackStartedParcel.aidl",
        "src/android/net/TetheringConfigurationParcel.aidl",
        "src/android/net/TetheringRequestParcel.aidl",
        "src/android/net/TetherStatesParcel.aidl",
    ],
    backend: {
        ndk: {
@@ -35,6 +43,7 @@ java_library {
    name: "framework-tethering",
    sdk_version: "system_current",
    srcs: [
        "src/android/net/TetheredClient.java",
        "src/android/net/TetheringManager.java",
        "src/android/net/TetheringConstants.java",
        ":framework-tethering-annotations",
@@ -63,6 +72,8 @@ java_library {
filegroup {
    name: "framework-tethering-srcs",
    srcs: [
        "src/android/net/TetheredClient.aidl",
        "src/android/net/TetheredClient.java",
        "src/android/net/TetheringManager.java",
        "src/android/net/TetheringConstants.java",
        "src/android/net/IIntResultListener.aidl",
+18 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2020 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;

@JavaOnlyStableParcelable parcelable TetheredClient;
 No newline at end of file
+212 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

/**
 * Information on a tethered downstream client.
 * @hide
 */
@SystemApi
@TestApi
public final class TetheredClient implements Parcelable {
    @NonNull
    private final MacAddress mMacAddress;
    @NonNull
    private final List<AddressInfo> mAddresses;
    // TODO: use an @IntDef here
    private final int mTetheringType;

    public TetheredClient(@NonNull MacAddress macAddress,
            @NonNull Collection<AddressInfo> addresses, int tetheringType) {
        mMacAddress = macAddress;
        mAddresses = new ArrayList<>(addresses);
        mTetheringType = tetheringType;
    }

    private TetheredClient(@NonNull Parcel in) {
        this(in.readParcelable(null), in.createTypedArrayList(AddressInfo.CREATOR), in.readInt());
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeParcelable(mMacAddress, flags);
        dest.writeTypedList(mAddresses);
        dest.writeInt(mTetheringType);
    }

    @NonNull
    public MacAddress getMacAddress() {
        return mMacAddress;
    }

    @NonNull
    public List<AddressInfo> getAddresses() {
        return new ArrayList<>(mAddresses);
    }

    public int getTetheringType() {
        return mTetheringType;
    }

    /**
     * Return a new {@link TetheredClient} that has all the attributes of this instance, plus the
     * {@link AddressInfo} of the provided {@link TetheredClient}.
     *
     * <p>Duplicate addresses are removed.
     * @hide
     */
    public TetheredClient addAddresses(@NonNull TetheredClient other) {
        final HashSet<AddressInfo> newAddresses = new HashSet<>(
                mAddresses.size() + other.mAddresses.size());
        newAddresses.addAll(mAddresses);
        newAddresses.addAll(other.mAddresses);
        return new TetheredClient(mMacAddress, newAddresses, mTetheringType);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mMacAddress, mAddresses, mTetheringType);
    }

    @Override
    public boolean equals(@Nullable Object obj) {
        if (!(obj instanceof TetheredClient)) return false;
        final TetheredClient other = (TetheredClient) obj;
        return mMacAddress.equals(other.mMacAddress)
                && mAddresses.equals(other.mAddresses)
                && mTetheringType == other.mTetheringType;
    }

    /**
     * Information on an lease assigned to a tethered client.
     */
    public static final class AddressInfo implements Parcelable {
        @NonNull
        private final LinkAddress mAddress;
        @Nullable
        private final String mHostname;
        // TODO: use LinkAddress expiration time once it is supported
        private final long mExpirationTime;

        /** @hide */
        public AddressInfo(@NonNull LinkAddress address, @Nullable String hostname) {
            this(address, hostname, 0);
        }

        /** @hide */
        public AddressInfo(@NonNull LinkAddress address, String hostname, long expirationTime) {
            this.mAddress = address;
            this.mHostname = hostname;
            this.mExpirationTime = expirationTime;
        }

        private AddressInfo(Parcel in) {
            this(in.readParcelable(null),  in.readString(), in.readLong());
        }

        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeParcelable(mAddress, flags);
            dest.writeString(mHostname);
            dest.writeLong(mExpirationTime);
        }

        @NonNull
        public LinkAddress getAddress() {
            return mAddress;
        }

        @Nullable
        public String getHostname() {
            return mHostname;
        }

        /** @hide TODO: use expiration time in LinkAddress */
        public long getExpirationTime() {
            return mExpirationTime;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mAddress, mHostname, mExpirationTime);
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (!(obj instanceof AddressInfo)) return false;
            final AddressInfo other = (AddressInfo) obj;
            // Use .equals() for addresses as all changes, including address expiry changes,
            // should be included.
            return other.mAddress.equals(mAddress)
                    && Objects.equals(mHostname, other.mHostname)
                    && mExpirationTime == other.mExpirationTime;
        }

        @NonNull
        public static final Creator<AddressInfo> CREATOR = new Creator<AddressInfo>() {
            @NonNull
            @Override
            public AddressInfo createFromParcel(@NonNull Parcel in) {
                return new AddressInfo(in);
            }

            @NonNull
            @Override
            public AddressInfo[] newArray(int size) {
                return new AddressInfo[size];
            }
        };
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @NonNull
    public static final Creator<TetheredClient> CREATOR = new Creator<TetheredClient>() {
        @NonNull
        @Override
        public TetheredClient createFromParcel(@NonNull Parcel in) {
            return new TetheredClient(in);
        }

        @NonNull
        @Override
        public TetheredClient[] newArray(int size) {
            return new TetheredClient[size];
        }
    };
}
Loading