Define stub and data classes for SharedConnectivity Service
Test: atest SharedConnectivityServiceTest Bug: 257348873 API-Coverage-Bug: 265968015 Change-Id: Idcf42036c73be9dd51416410e6b15ef4c1bb2af7
This commit is contained in:
@@ -9782,6 +9782,133 @@ package android.net.wifi.nl80211 {
|
||||
|
||||
}
|
||||
|
||||
package android.net.wifi.sharedconnectivity.app {
|
||||
|
||||
public final class DeviceInfo implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @IntRange(from=0, to=100) @NonNull public int getBatteryPercentage();
|
||||
method @IntRange(from=0, to=3) @NonNull public int getConnectionStrength();
|
||||
method @NonNull public String getDeviceName();
|
||||
method public int getDeviceType();
|
||||
method @NonNull public String getModelName();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.DeviceInfo> CREATOR;
|
||||
field public static final int DEVICE_TYPE_LAPTOP = 3; // 0x3
|
||||
field public static final int DEVICE_TYPE_PHONE = 1; // 0x1
|
||||
field public static final int DEVICE_TYPE_TABLET = 2; // 0x2
|
||||
field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
|
||||
}
|
||||
|
||||
public static final class DeviceInfo.Builder {
|
||||
ctor public DeviceInfo.Builder();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo build();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setBatteryPercentage(@IntRange(from=0, to=100) int);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setConnectionStrength(@IntRange(from=0, to=3) int);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setDeviceName(@NonNull String);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setDeviceType(int);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setModelName(@NonNull String);
|
||||
}
|
||||
|
||||
public final class KnownNetwork implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo getDeviceInfo();
|
||||
method @NonNull public int getNetworkSource();
|
||||
method @NonNull public int[] getSecurityTypes();
|
||||
method @NonNull public String getSsid();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.KnownNetwork> CREATOR;
|
||||
field public static final int NETWORK_SOURCE_CLOUD_SELF = 1; // 0x1
|
||||
field public static final int NETWORK_SOURCE_NEARBY_SELF = 0; // 0x0
|
||||
}
|
||||
|
||||
public static final class KnownNetwork.Builder {
|
||||
ctor public KnownNetwork.Builder();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork build();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setDeviceInfo(@NonNull android.net.wifi.sharedconnectivity.app.DeviceInfo);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setNetworkSource(int);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setSecurityTypes(@NonNull int[]);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setSsid(@NonNull String);
|
||||
}
|
||||
|
||||
public interface SharedConnectivityClientCallback {
|
||||
method public void onKnownNetworksUpdated(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.KnownNetwork>);
|
||||
method public void onSharedConnectivitySettingsChanged(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState);
|
||||
method public void onTetherNetworksUpdated(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.TetherNetwork>);
|
||||
}
|
||||
|
||||
public class SharedConnectivityManager {
|
||||
ctor public SharedConnectivityManager(@NonNull android.content.Context);
|
||||
method public boolean connectKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
|
||||
method public boolean connectTetherNetwork(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetwork);
|
||||
method public boolean disconnectTetherNetwork();
|
||||
method public boolean forgetKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
|
||||
method public boolean registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback);
|
||||
method public boolean unregisterCallback(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback);
|
||||
}
|
||||
|
||||
public final class SharedConnectivitySettingsState implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @NonNull public android.os.Bundle getExtras();
|
||||
method @NonNull public boolean isInstantTetherEnabled();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState> CREATOR;
|
||||
}
|
||||
|
||||
public static final class SharedConnectivitySettingsState.Builder {
|
||||
ctor public SharedConnectivitySettingsState.Builder();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState build();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.Builder setExtras(@NonNull android.os.Bundle);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.Builder setInstantTetherEnabled(boolean);
|
||||
}
|
||||
|
||||
public final class TetherNetwork implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @NonNull public long getDeviceId();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo getDeviceInfo();
|
||||
method @Nullable public String getHotspotBssid();
|
||||
method @Nullable public int[] getHotspotSecurityTypes();
|
||||
method @Nullable public String getHotspotSsid();
|
||||
method @NonNull public String getNetworkName();
|
||||
method @NonNull public int getNetworkType();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.TetherNetwork> CREATOR;
|
||||
field public static final int NETWORK_TYPE_CELLULAR = 1; // 0x1
|
||||
field public static final int NETWORK_TYPE_ETHERNET = 3; // 0x3
|
||||
field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0
|
||||
field public static final int NETWORK_TYPE_WIFI = 2; // 0x2
|
||||
}
|
||||
|
||||
public static final class TetherNetwork.Builder {
|
||||
ctor public TetherNetwork.Builder();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork build();
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setDeviceId(long);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setDeviceInfo(@NonNull android.net.wifi.sharedconnectivity.app.DeviceInfo);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setHotspotBssid(@NonNull String);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setHotspotSecurityTypes(@NonNull int[]);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setHotspotSsid(@NonNull String);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setNetworkName(@NonNull String);
|
||||
method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setNetworkType(int);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.net.wifi.sharedconnectivity.service {
|
||||
|
||||
public abstract class SharedConnectivityService extends android.app.Service {
|
||||
ctor public SharedConnectivityService();
|
||||
ctor public SharedConnectivityService(@NonNull android.os.Handler);
|
||||
method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
|
||||
method public abstract void onConnectKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
|
||||
method public abstract void onConnectTetherNetwork(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetwork);
|
||||
method public abstract void onDisconnectTetherNetwork();
|
||||
method public abstract void onForgetKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
|
||||
method public final void setKnownNetworks(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.KnownNetwork>);
|
||||
method public final void setSettingsState(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState);
|
||||
method public final void setTetherNetworks(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.TetherNetwork>);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.nfc {
|
||||
|
||||
public final class NfcAdapter {
|
||||
|
||||
@@ -1866,6 +1866,14 @@ package android.net {
|
||||
|
||||
}
|
||||
|
||||
package android.net.wifi.sharedconnectivity.app {
|
||||
|
||||
public class SharedConnectivityManager {
|
||||
method public void setService(@Nullable android.os.IInterface);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.os {
|
||||
|
||||
public final class BatteryStatsManager {
|
||||
|
||||
@@ -27,7 +27,10 @@ package {
|
||||
|
||||
filegroup {
|
||||
name: "framework-wifi-non-updatable-sources-internal",
|
||||
srcs: ["src/**/*.java"],
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
"src/**/*.aidl",
|
||||
],
|
||||
path: "src",
|
||||
visibility: ["//visibility:private"],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
parcelable DeviceInfo;
|
||||
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A data class representing a device providing connectivity.
|
||||
* This class is used in IPC calls between the implementer of {@link SharedConnectivityService} and
|
||||
* the consumers of {@link com.android.wifitrackerlib}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class DeviceInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* Device type providing connectivity is unknown.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* Device providing connectivity is a mobile phone.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_PHONE = 1;
|
||||
|
||||
/**
|
||||
* Device providing connectivity is a tablet.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_TABLET = 2;
|
||||
|
||||
/**
|
||||
* Device providing connectivity is a laptop.
|
||||
*/
|
||||
public static final int DEVICE_TYPE_LAPTOP = 3;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
DEVICE_TYPE_UNKNOWN,
|
||||
DEVICE_TYPE_PHONE,
|
||||
DEVICE_TYPE_TABLET,
|
||||
DEVICE_TYPE_LAPTOP
|
||||
})
|
||||
public @interface DeviceType {}
|
||||
|
||||
@DeviceType private final int mDeviceType;
|
||||
private final String mDeviceName;
|
||||
private final String mModelName;
|
||||
private final int mBatteryPercentage;
|
||||
private final int mConnectionStrength;
|
||||
|
||||
/**
|
||||
* Builder class for {@link DeviceInfo}.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private int mDeviceType;
|
||||
private String mDeviceName;
|
||||
private String mModelName;
|
||||
private int mBatteryPercentage;
|
||||
private int mConnectionStrength;
|
||||
|
||||
public Builder() {}
|
||||
|
||||
/**
|
||||
* Sets the device type that provides connectivity.
|
||||
*
|
||||
* @param deviceType Device type as represented by IntDef {@link DeviceType}.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDeviceType(@DeviceType int deviceType) {
|
||||
mDeviceType = deviceType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the device name of the remote device.
|
||||
*
|
||||
* @param deviceName The user configurable device name.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDeviceName(@NonNull String deviceName) {
|
||||
mDeviceName = deviceName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the model name of the remote device.
|
||||
*
|
||||
* @param modelName The OEM configured name for the device model.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setModelName(@NonNull String modelName) {
|
||||
mModelName = modelName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the battery charge percentage of the remote device.
|
||||
*
|
||||
* @param batteryPercentage The battery charge percentage in the range 0 to 100.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setBatteryPercentage(@IntRange(from = 0, to = 100) int batteryPercentage) {
|
||||
mBatteryPercentage = batteryPercentage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the displayed connection strength of the remote device to the internet.
|
||||
*
|
||||
* @param connectionStrength Connection strength in range 0 to 3.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setConnectionStrength(@IntRange(from = 0, to = 3) int connectionStrength) {
|
||||
mConnectionStrength = connectionStrength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link DeviceInfo} object.
|
||||
*
|
||||
* @return Returns the built {@link DeviceInfo} object.
|
||||
*/
|
||||
@NonNull
|
||||
public DeviceInfo build() {
|
||||
return new DeviceInfo(mDeviceType, mDeviceName, mModelName, mBatteryPercentage,
|
||||
mConnectionStrength);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validate(int deviceType, String deviceName, String modelName,
|
||||
int batteryPercentage, int connectionStrength) {
|
||||
if (deviceType != DEVICE_TYPE_UNKNOWN && deviceType != DEVICE_TYPE_PHONE
|
||||
&& deviceType != DEVICE_TYPE_TABLET && deviceType != DEVICE_TYPE_LAPTOP) {
|
||||
throw new IllegalArgumentException("Illegal device type");
|
||||
}
|
||||
if (Objects.isNull(deviceName)) {
|
||||
throw new IllegalArgumentException("DeviceName must be set");
|
||||
}
|
||||
if (Objects.isNull(modelName)) {
|
||||
throw new IllegalArgumentException("ModelName must be set");
|
||||
}
|
||||
if (batteryPercentage < 0 || batteryPercentage > 100) {
|
||||
throw new IllegalArgumentException("BatteryPercentage must be in range 0-100");
|
||||
}
|
||||
if (connectionStrength < 0 || connectionStrength > 3) {
|
||||
throw new IllegalArgumentException("ConnectionStrength must be in range 0-3");
|
||||
}
|
||||
}
|
||||
|
||||
private DeviceInfo(@DeviceType int deviceType, @NonNull String deviceName,
|
||||
@NonNull String modelName, int batteryPercentage, int connectionStrength) {
|
||||
validate(deviceType, deviceName, modelName, batteryPercentage, connectionStrength);
|
||||
mDeviceType = deviceType;
|
||||
mDeviceName = deviceName;
|
||||
mModelName = modelName;
|
||||
mBatteryPercentage = batteryPercentage;
|
||||
mConnectionStrength = connectionStrength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device type that provides connectivity.
|
||||
*
|
||||
* @return Returns the device type as represented by IntDef {@link DeviceType}.
|
||||
*/
|
||||
@DeviceType
|
||||
public int getDeviceType() {
|
||||
return mDeviceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device name of the remote device.
|
||||
*
|
||||
* @return Returns the user configurable device name.
|
||||
*/
|
||||
@NonNull
|
||||
public String getDeviceName() {
|
||||
return mDeviceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the model name of the remote device.
|
||||
*
|
||||
* @return Returns the OEM configured name for the device model.
|
||||
*/
|
||||
@NonNull
|
||||
public String getModelName() {
|
||||
return mModelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the battery charge percentage of the remote device.
|
||||
*
|
||||
* @return Returns the battery charge percentage in the range 0 to 100.
|
||||
*/
|
||||
@NonNull
|
||||
@IntRange(from = 0, to = 100)
|
||||
public int getBatteryPercentage() {
|
||||
return mBatteryPercentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the displayed connection strength of the remote device to the internet.
|
||||
*
|
||||
* @return Returns the connection strength in range 0 to 3.
|
||||
*/
|
||||
@NonNull
|
||||
@IntRange(from = 0, to = 3)
|
||||
public int getConnectionStrength() {
|
||||
return mConnectionStrength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof DeviceInfo)) return false;
|
||||
DeviceInfo other = (DeviceInfo) obj;
|
||||
return mDeviceType == other.getDeviceType()
|
||||
&& Objects.equals(mDeviceName, other.mDeviceName)
|
||||
&& Objects.equals(mModelName, other.mModelName)
|
||||
&& mBatteryPercentage == other.mBatteryPercentage
|
||||
&& mConnectionStrength == other.mConnectionStrength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mDeviceType, mDeviceName, mModelName, mBatteryPercentage,
|
||||
mConnectionStrength);
|
||||
}
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mDeviceType);
|
||||
dest.writeString(mDeviceName);
|
||||
dest.writeString(mModelName);
|
||||
dest.writeInt(mBatteryPercentage);
|
||||
dest.writeInt(mConnectionStrength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<DeviceInfo> CREATOR = new Creator<DeviceInfo>() {
|
||||
@Override
|
||||
public DeviceInfo createFromParcel(Parcel in) {
|
||||
return new DeviceInfo(in.readInt(), in.readString(), in.readString(), in.readInt(),
|
||||
in.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceInfo[] newArray(int size) {
|
||||
return new DeviceInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("DeviceInfo[")
|
||||
.append("deviceType=").append(mDeviceType)
|
||||
.append(", deviceName=").append(mDeviceName)
|
||||
.append(", modelName=").append(mModelName)
|
||||
.append(", batteryPercentage=").append(mBatteryPercentage)
|
||||
.append(", connectionStrength=").append(mConnectionStrength)
|
||||
.append("]").toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
parcelable KnownNetwork;
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import static android.net.wifi.WifiAnnotations.SecurityType;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A data class representing a known Wifi network.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class KnownNetwork implements Parcelable {
|
||||
/**
|
||||
* Network is known by a nearby device with the same user account.
|
||||
*/
|
||||
public static final int NETWORK_SOURCE_NEARBY_SELF = 0;
|
||||
|
||||
/**
|
||||
* Network is known via cloud storage associated with this device's user account.
|
||||
*/
|
||||
public static final int NETWORK_SOURCE_CLOUD_SELF = 1;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
NETWORK_SOURCE_NEARBY_SELF,
|
||||
NETWORK_SOURCE_CLOUD_SELF
|
||||
})
|
||||
public @interface NetworkSource {}
|
||||
|
||||
@NetworkSource private final int mNetworkSource;
|
||||
private final String mSsid;
|
||||
@SecurityType private final int[] mSecurityTypes;
|
||||
private final DeviceInfo mDeviceInfo;
|
||||
|
||||
/**
|
||||
* Builder class for {@link KnownNetwork}.
|
||||
*/
|
||||
public static final class Builder {
|
||||
@NetworkSource private int mNetworkSource = -1;
|
||||
private String mSsid;
|
||||
@SecurityType private int[] mSecurityTypes;
|
||||
private android.net.wifi.sharedconnectivity.app.DeviceInfo mDeviceInfo;
|
||||
|
||||
public Builder() {}
|
||||
|
||||
/**
|
||||
* Sets the indicated source of the known network.
|
||||
*
|
||||
* @param networkSource The network source as defined by IntDef {@link NetworkSource}.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setNetworkSource(@NetworkSource int networkSource) {
|
||||
mNetworkSource = networkSource;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SSID of the known network.
|
||||
*
|
||||
* @param ssid The SSID of the known network. Surrounded by double quotes if UTF-8.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setSsid(@NonNull String ssid) {
|
||||
mSsid = ssid;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the security types of the known network.
|
||||
*
|
||||
* @param securityTypes The array of security types supported by the known network.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setSecurityTypes(@NonNull @SecurityType int[] securityTypes) {
|
||||
mSecurityTypes = securityTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the device information of the device providing connectivity.
|
||||
*
|
||||
* @param deviceInfo The array of security types supported by the known network.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDeviceInfo(@NonNull DeviceInfo deviceInfo) {
|
||||
mDeviceInfo = deviceInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link KnownNetwork} object.
|
||||
*
|
||||
* @return Returns the built {@link KnownNetwork} object.
|
||||
*/
|
||||
@NonNull
|
||||
public KnownNetwork build() {
|
||||
return new KnownNetwork(
|
||||
mNetworkSource,
|
||||
mSsid,
|
||||
mSecurityTypes,
|
||||
mDeviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validate(int networkSource, String ssid, int [] securityTypes) {
|
||||
if (networkSource != NETWORK_SOURCE_CLOUD_SELF && networkSource
|
||||
!= NETWORK_SOURCE_NEARBY_SELF) {
|
||||
throw new IllegalArgumentException("Illegal network source");
|
||||
}
|
||||
if (TextUtils.isEmpty(ssid)) {
|
||||
throw new IllegalArgumentException("SSID must be set");
|
||||
}
|
||||
if (securityTypes == null || securityTypes.length == 0) {
|
||||
throw new IllegalArgumentException("SecurityTypes must be set");
|
||||
}
|
||||
}
|
||||
|
||||
private KnownNetwork(
|
||||
@NetworkSource int networkSource,
|
||||
@NonNull String ssid,
|
||||
@NonNull @SecurityType int[] securityTypes,
|
||||
@NonNull android.net.wifi.sharedconnectivity.app.DeviceInfo deviceInfo) {
|
||||
validate(networkSource, ssid, securityTypes);
|
||||
mNetworkSource = networkSource;
|
||||
mSsid = ssid;
|
||||
mSecurityTypes = securityTypes;
|
||||
mDeviceInfo = deviceInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the indicated source of the known network.
|
||||
*
|
||||
* @return Returns the network source as defined by IntDef {@link NetworkSource}.
|
||||
*/
|
||||
@NonNull
|
||||
@NetworkSource
|
||||
public int getNetworkSource() {
|
||||
return mNetworkSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SSID of the known network.
|
||||
*
|
||||
* @return Returns the SSID of the known network. Surrounded by double quotes if UTF-8.
|
||||
*/
|
||||
@NonNull
|
||||
public String getSsid() {
|
||||
return mSsid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the security types of the known network.
|
||||
*
|
||||
* @return Returns the array of security types supported by the known network.
|
||||
*/
|
||||
@NonNull
|
||||
@SecurityType
|
||||
public int[] getSecurityTypes() {
|
||||
return mSecurityTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device information of the device providing connectivity.
|
||||
*
|
||||
* @return Returns the array of security types supported by the known network.
|
||||
*/
|
||||
@NonNull
|
||||
public DeviceInfo getDeviceInfo() {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof KnownNetwork)) return false;
|
||||
KnownNetwork other = (KnownNetwork) obj;
|
||||
return mNetworkSource == other.getNetworkSource()
|
||||
&& Objects.equals(mSsid, other.getSsid())
|
||||
&& Arrays.equals(mSecurityTypes, other.getSecurityTypes())
|
||||
&& Objects.equals(mDeviceInfo, other.getDeviceInfo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mNetworkSource, mSsid, Arrays.hashCode(mSecurityTypes),
|
||||
mDeviceInfo.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mNetworkSource);
|
||||
dest.writeString(mSsid);
|
||||
dest.writeIntArray(mSecurityTypes);
|
||||
dest.writeTypedObject(mDeviceInfo, 0);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<KnownNetwork> CREATOR = new Creator<>() {
|
||||
@Override
|
||||
public KnownNetwork createFromParcel(Parcel in) {
|
||||
return new KnownNetwork(in.readInt(), in.readString(), in.createIntArray(),
|
||||
in.readTypedObject(DeviceInfo.CREATOR));
|
||||
}
|
||||
|
||||
@Override
|
||||
public KnownNetwork[] newArray(int size) {
|
||||
return new KnownNetwork[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("KnownNetwork[")
|
||||
.append("NetworkSource=").append(mNetworkSource)
|
||||
.append(", ssid=").append(mSsid)
|
||||
.append(", securityTypes=").append(Arrays.toString(mSecurityTypes))
|
||||
.append(", deviceInfo=").append(mDeviceInfo.toString())
|
||||
.append("]").toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for clients of {@link SharedConnectivityManager} to register for changes in network
|
||||
* status.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public interface SharedConnectivityClientCallback {
|
||||
/**
|
||||
* This method is being called by {@link SharedConnectivityService} to notify of a change in the
|
||||
* list of available Tether Networks.
|
||||
* @param networks Updated Tether Network list.
|
||||
*/
|
||||
void onTetherNetworksUpdated(@NonNull List<TetherNetwork> networks);
|
||||
|
||||
/**
|
||||
* This method is being called by {@link SharedConnectivityService} to notify of a change in the
|
||||
* list of available Known Networks.
|
||||
* @param networks Updated Known Network list.
|
||||
*/
|
||||
void onKnownNetworksUpdated(@NonNull List<KnownNetwork> networks);
|
||||
|
||||
/**
|
||||
* This method is being called by {@link SharedConnectivityService} to notify of a change in the
|
||||
* state of share connectivity settings.
|
||||
* @param state The new state.
|
||||
*/
|
||||
void onSharedConnectivitySettingsChanged(@NonNull SharedConnectivitySettingsState state);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.res.Resources;
|
||||
import android.net.wifi.sharedconnectivity.service.ISharedConnectivityCallback;
|
||||
import android.net.wifi.sharedconnectivity.service.ISharedConnectivityService;
|
||||
import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.IInterface;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* This class is the library used by consumers of Shared Connectivity data to bind to the service,
|
||||
* receive callbacks from, and send user actions to the service.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public class SharedConnectivityManager {
|
||||
private static final String TAG = SharedConnectivityManager.class.getSimpleName();
|
||||
private static final boolean DEBUG = true;
|
||||
private static final String SERVICE_PACKAGE_NAME = "sharedconnectivity_service_package";
|
||||
private static final String SERVICE_CLASS_NAME = "sharedconnectivity_service_class";
|
||||
|
||||
private static final class SharedConnectivityCallbackProxy extends
|
||||
ISharedConnectivityCallback.Stub {
|
||||
private final Executor mExecutor;
|
||||
private final SharedConnectivityClientCallback mCallback;
|
||||
|
||||
SharedConnectivityCallbackProxy(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull SharedConnectivityClientCallback callback) {
|
||||
mExecutor = executor;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTetherNetworksUpdated(@NonNull List<TetherNetwork> networks) {
|
||||
if (mCallback != null) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() -> mCallback.onTetherNetworksUpdated(networks));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKnownNetworksUpdated(@NonNull List<KnownNetwork> networks) {
|
||||
if (mCallback != null) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() -> mCallback.onKnownNetworksUpdated(networks));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedConnectivitySettingsChanged(
|
||||
@NonNull SharedConnectivitySettingsState state) {
|
||||
if (mCallback != null) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() -> mCallback.onSharedConnectivitySettingsChanged(state));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ISharedConnectivityService mService;
|
||||
private final Map<SharedConnectivityClientCallback, SharedConnectivityCallbackProxy>
|
||||
mProxyMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructor for new instance of {@link SharedConnectivityManager}.
|
||||
*
|
||||
* Automatically binds to implementation of {@link SharedConnectivityService} specified in
|
||||
* device overlay.
|
||||
*/
|
||||
@SuppressLint("ManagerConstructor")
|
||||
public SharedConnectivityManager(@NonNull Context context) {
|
||||
ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mService = ISharedConnectivityService.Stub.asInterface(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
if (DEBUG) Log.i(TAG, "onServiceDisconnected");
|
||||
mService = null;
|
||||
mProxyMap.clear();
|
||||
}
|
||||
};
|
||||
bind(context, serviceConnection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void setService(@Nullable IInterface service) {
|
||||
mService = (ISharedConnectivityService) service;
|
||||
}
|
||||
|
||||
private void bind(Context context, ServiceConnection serviceConnection) {
|
||||
Resources resources = context.getResources();
|
||||
int packageNameId = resources.getIdentifier(SERVICE_PACKAGE_NAME, "string",
|
||||
context.getPackageName());
|
||||
int classNameId = resources.getIdentifier(SERVICE_CLASS_NAME, "string",
|
||||
context.getPackageName());
|
||||
if (packageNameId == 0 || classNameId == 0) {
|
||||
throw new Resources.NotFoundException("Package and class names for"
|
||||
+ " shared connectivity service must be defined");
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(new ComponentName(resources.getString(packageNameId),
|
||||
resources.getString(classNameId)));
|
||||
context.bindService(
|
||||
intent,
|
||||
serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback for receiving updates to the list of Tether Networks and Known Networks.
|
||||
*
|
||||
* @param executor The Executor used to invoke the callback.
|
||||
* @param callback The callback of type {@link SharedConnectivityClientCallback} that is invoked
|
||||
* when the service updates either the list of Tether Networks or Known
|
||||
* Networks.
|
||||
* @return Returns true if the registration was successful, false otherwise.
|
||||
*/
|
||||
public boolean registerCallback(@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull SharedConnectivityClientCallback callback) {
|
||||
Objects.requireNonNull(executor, "executor cannot be null");
|
||||
Objects.requireNonNull(callback, "callback cannot be null");
|
||||
if (mService == null || mProxyMap.containsKey(callback)) return false;
|
||||
try {
|
||||
SharedConnectivityCallbackProxy proxy =
|
||||
new SharedConnectivityCallbackProxy(executor, callback);
|
||||
mService.registerCallback(proxy);
|
||||
mProxyMap.put(callback, proxy);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception in registerCallback", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a callback.
|
||||
*
|
||||
* @return Returns true if the callback was successfully unregistered, false otherwise.
|
||||
*/
|
||||
public boolean unregisterCallback(
|
||||
@NonNull SharedConnectivityClientCallback callback) {
|
||||
Objects.requireNonNull(callback, "callback cannot be null");
|
||||
if (mService == null || !mProxyMap.containsKey(callback)) return false;
|
||||
try {
|
||||
mService.unregisterCallback(mProxyMap.get(callback));
|
||||
mProxyMap.remove(callback);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception in unregisterCallback", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command to the implementation of {@link SharedConnectivityService} requesting connection
|
||||
* to the specified Tether Network.
|
||||
*
|
||||
* @param network {@link TetherNetwork} object representing the network the user has requested
|
||||
* a connection to.
|
||||
* @return Returns true if the service received the command. Does not guarantee that the
|
||||
* connection was successful.
|
||||
*/
|
||||
public boolean connectTetherNetwork(@NonNull TetherNetwork network) {
|
||||
if (mService == null) return false;
|
||||
try {
|
||||
mService.connectTetherNetwork(network);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception in connectTetherNetwork", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command to the implementation of {@link SharedConnectivityService} requesting
|
||||
* disconnection from the active Tether Network.
|
||||
*
|
||||
* @return Returns true if the service received the command. Does not guarantee that the
|
||||
* disconnection was successful.
|
||||
*/
|
||||
public boolean disconnectTetherNetwork() {
|
||||
if (mService == null) return false;
|
||||
try {
|
||||
mService.disconnectTetherNetwork();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception in disconnectTetherNetwork", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command to the implementation of {@link SharedConnectivityService} requesting connection
|
||||
* to the specified Known Network.
|
||||
*
|
||||
* @param network {@link KnownNetwork} object representing the network the user has requested
|
||||
* a connection to.
|
||||
* @return Returns true if the service received the command. Does not guarantee that the
|
||||
* connection was successful.
|
||||
*/
|
||||
public boolean connectKnownNetwork(@NonNull KnownNetwork network) {
|
||||
if (mService == null) return false;
|
||||
try {
|
||||
mService.connectKnownNetwork(network);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception in connectKnownNetwork", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command to the implementation of {@link SharedConnectivityService} requesting removal of
|
||||
* the specified Known Network from the list of Known Networks.
|
||||
*
|
||||
* @return Returns true if the service received the command. Does not guarantee that the
|
||||
* forget action was successful.
|
||||
*/
|
||||
public boolean forgetKnownNetwork(@NonNull KnownNetwork network) {
|
||||
if (mService == null) return false;
|
||||
try {
|
||||
mService.forgetKnownNetwork(network);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception in forgetKnownNetwork", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
parcelable SharedConnectivitySettingsState;
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* A data class representing the shared connectivity settings state.
|
||||
*
|
||||
* This class represents a snapshot of the settings and can be out of date if the settings changed
|
||||
* after receiving an object of this class.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class SharedConnectivitySettingsState implements Parcelable {
|
||||
|
||||
private final boolean mInstantTetherEnabled;
|
||||
private final Bundle mExtras;
|
||||
|
||||
/**
|
||||
* Builder class for {@link SharedConnectivitySettingsState}.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private boolean mInstantTetherEnabled;
|
||||
private Bundle mExtras;
|
||||
|
||||
public Builder() {}
|
||||
|
||||
/**
|
||||
* Sets the state of Instant Tether in settings
|
||||
*
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setInstantTetherEnabled(boolean instantTetherEnabled) {
|
||||
mInstantTetherEnabled = instantTetherEnabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the extras bundle
|
||||
*
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setExtras(@NonNull Bundle extras) {
|
||||
mExtras = extras;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link SharedConnectivitySettingsState} object.
|
||||
*
|
||||
* @return Returns the built {@link SharedConnectivitySettingsState} object.
|
||||
*/
|
||||
@NonNull
|
||||
public SharedConnectivitySettingsState build() {
|
||||
return new SharedConnectivitySettingsState(mInstantTetherEnabled, mExtras);
|
||||
}
|
||||
}
|
||||
|
||||
private SharedConnectivitySettingsState(boolean instantTetherEnabled, Bundle extras) {
|
||||
mInstantTetherEnabled = instantTetherEnabled;
|
||||
mExtras = extras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of Instant Tether in settings
|
||||
*
|
||||
* @return Returns true for enabled, false otherwise.
|
||||
*/
|
||||
@NonNull
|
||||
public boolean isInstantTetherEnabled() {
|
||||
return mInstantTetherEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extras Bundle.
|
||||
*
|
||||
* @return Returns a Bundle object.
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getExtras() {
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof SharedConnectivitySettingsState)) return false;
|
||||
SharedConnectivitySettingsState other = (SharedConnectivitySettingsState) obj;
|
||||
return mInstantTetherEnabled == other.isInstantTetherEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mInstantTetherEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeBoolean(mInstantTetherEnabled);
|
||||
dest.writeBundle(mExtras);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<SharedConnectivitySettingsState> CREATOR =
|
||||
new Creator<SharedConnectivitySettingsState>() {
|
||||
@Override
|
||||
public SharedConnectivitySettingsState createFromParcel(Parcel in) {
|
||||
return new SharedConnectivitySettingsState(in.readBoolean(),
|
||||
in.readBundle(getClass().getClassLoader()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SharedConnectivitySettingsState[] newArray(int size) {
|
||||
return new SharedConnectivitySettingsState[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("SharedConnectivitySettingsState[")
|
||||
.append("instantTetherEnabled=").append(mInstantTetherEnabled)
|
||||
.append("extras=").append(mExtras.toString())
|
||||
.append("]").toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
parcelable TetherNetwork;
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import static android.net.wifi.WifiAnnotations.SecurityType;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A data class representing an Instant Tether network.
|
||||
* This class is used in IPC calls between the implementer of {@link SharedConnectivityService} and
|
||||
* the consumers of {@link com.android.wifitrackerlib}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public final class TetherNetwork implements Parcelable {
|
||||
/**
|
||||
* Remote device is connected to the internet via an unknown connection.
|
||||
*/
|
||||
public static final int NETWORK_TYPE_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* Remote device is connected to the internet via a cellular connection.
|
||||
*/
|
||||
public static final int NETWORK_TYPE_CELLULAR = 1;
|
||||
|
||||
/**
|
||||
* Remote device is connected to the internet via a Wi-Fi connection.
|
||||
*/
|
||||
public static final int NETWORK_TYPE_WIFI = 2;
|
||||
|
||||
/**
|
||||
* Remote device is connected to the internet via an ethernet connection.
|
||||
*/
|
||||
public static final int NETWORK_TYPE_ETHERNET = 3;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
NETWORK_TYPE_UNKNOWN,
|
||||
NETWORK_TYPE_CELLULAR,
|
||||
NETWORK_TYPE_WIFI,
|
||||
NETWORK_TYPE_ETHERNET
|
||||
})
|
||||
public @interface NetworkType {}
|
||||
|
||||
private final long mDeviceId;
|
||||
private final DeviceInfo mDeviceInfo;
|
||||
@NetworkType private final int mNetworkType;
|
||||
private final String mNetworkName;
|
||||
@Nullable private final String mHotspotSsid;
|
||||
@Nullable private final String mHotspotBssid;
|
||||
@Nullable @SecurityType private final int[] mHotspotSecurityTypes;
|
||||
|
||||
/**
|
||||
* Builder class for {@link TetherNetwork}.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private long mDeviceId = -1;
|
||||
private DeviceInfo mDeviceInfo;
|
||||
@NetworkType private int mNetworkType;
|
||||
private String mNetworkName;
|
||||
@Nullable private String mHotspotSsid;
|
||||
@Nullable private String mHotspotBssid;
|
||||
@Nullable @SecurityType private int[] mHotspotSecurityTypes;
|
||||
|
||||
public Builder() {}
|
||||
|
||||
/**
|
||||
* Set the remote device ID.
|
||||
*
|
||||
* @param deviceId Locally unique ID for this Instant Tether network.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDeviceId(long deviceId) {
|
||||
mDeviceId = deviceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets information about the device providing connectivity.
|
||||
*
|
||||
* @param deviceInfo The user configurable device name.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDeviceInfo(@NonNull DeviceInfo deviceInfo) {
|
||||
mDeviceInfo = deviceInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the network type that the remote device is connected to.
|
||||
*
|
||||
* @param networkType Network type as represented by IntDef {@link NetworkType}.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setNetworkType(@NetworkType int networkType) {
|
||||
mNetworkType = networkType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the display name of the network the remote device is connected to.
|
||||
*
|
||||
* @param networkName Network display name. (e.g. "Google Fi", "Hotel WiFi", "Ethernet")
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setNetworkName(@NonNull String networkName) {
|
||||
mNetworkName = networkName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hotspot SSID being broadcast by the remote device, or null if hotspot is off.
|
||||
*
|
||||
* @param hotspotSsid The SSID of the hotspot. Surrounded by double quotes if UTF-8.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setHotspotSsid(@NonNull String hotspotSsid) {
|
||||
mHotspotSsid = hotspotSsid;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hotspot BSSID being broadcast by the remote device, or null if hotspot is off.
|
||||
*
|
||||
* @param hotspotBssid The BSSID of the hotspot.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setHotspotBssid(@NonNull String hotspotBssid) {
|
||||
mHotspotBssid = hotspotBssid;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hotspot security types supported by the remote device, or null if hotspot is
|
||||
* off.
|
||||
*
|
||||
* @param hotspotSecurityTypes The array of security types supported by the hotspot.
|
||||
* @return Returns the Builder object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setHotspotSecurityTypes(@NonNull @SecurityType int[] hotspotSecurityTypes) {
|
||||
mHotspotSecurityTypes = hotspotSecurityTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link TetherNetwork} object.
|
||||
*
|
||||
* @return Returns the built {@link TetherNetwork} object.
|
||||
*/
|
||||
@NonNull
|
||||
public TetherNetwork build() {
|
||||
return new TetherNetwork(
|
||||
mDeviceId,
|
||||
mDeviceInfo,
|
||||
mNetworkType,
|
||||
mNetworkName,
|
||||
mHotspotSsid,
|
||||
mHotspotBssid,
|
||||
mHotspotSecurityTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validate(long deviceId, int networkType, String networkName) {
|
||||
if (deviceId < 0) {
|
||||
throw new IllegalArgumentException("DeviceId must be set");
|
||||
}
|
||||
if (networkType != NETWORK_TYPE_CELLULAR && networkType != NETWORK_TYPE_WIFI
|
||||
&& networkType != NETWORK_TYPE_ETHERNET && networkType != NETWORK_TYPE_UNKNOWN) {
|
||||
throw new IllegalArgumentException("Illegal network type");
|
||||
}
|
||||
if (Objects.isNull(networkName)) {
|
||||
throw new IllegalArgumentException("NetworkName must be set");
|
||||
}
|
||||
}
|
||||
|
||||
private TetherNetwork(
|
||||
long deviceId,
|
||||
DeviceInfo deviceInfo,
|
||||
@NetworkType int networkType,
|
||||
@NonNull String networkName,
|
||||
@Nullable String hotspotSsid,
|
||||
@Nullable String hotspotBssid,
|
||||
@Nullable @SecurityType int[] hotspotSecurityTypes) {
|
||||
validate(deviceId,
|
||||
networkType,
|
||||
networkName);
|
||||
mDeviceId = deviceId;
|
||||
mDeviceInfo = deviceInfo;
|
||||
mNetworkType = networkType;
|
||||
mNetworkName = networkName;
|
||||
mHotspotSsid = hotspotSsid;
|
||||
mHotspotBssid = hotspotBssid;
|
||||
mHotspotSecurityTypes = hotspotSecurityTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remote device ID.
|
||||
*
|
||||
* @return Returns the locally unique ID for this Instant Tether network.
|
||||
*/
|
||||
@NonNull
|
||||
public long getDeviceId() {
|
||||
return mDeviceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the device providing connectivity.
|
||||
*
|
||||
* @return Returns the locally unique ID for this Instant Tether network.
|
||||
*/
|
||||
@NonNull
|
||||
public DeviceInfo getDeviceInfo() {
|
||||
return mDeviceInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the network type that the remote device is connected to.
|
||||
*
|
||||
* @return Returns the network type as represented by IntDef {@link NetworkType}.
|
||||
*/
|
||||
@NonNull
|
||||
@NetworkType
|
||||
public int getNetworkType() {
|
||||
return mNetworkType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display name of the network the remote device is connected to.
|
||||
*
|
||||
* @return Returns the network display name. (e.g. "Google Fi", "Hotel WiFi", "Ethernet")
|
||||
*/
|
||||
@NonNull
|
||||
public String getNetworkName() {
|
||||
return mNetworkName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hotspot SSID being broadcast by the remote device, or null if hotspot is off.
|
||||
*
|
||||
* @return Returns the SSID of the hotspot. Surrounded by double quotes if UTF-8.
|
||||
*/
|
||||
@Nullable
|
||||
public String getHotspotSsid() {
|
||||
return mHotspotSsid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hotspot BSSID being broadcast by the remote device, or null if hotspot is off.
|
||||
*
|
||||
* @return Returns the BSSID of the hotspot.
|
||||
*/
|
||||
@Nullable
|
||||
public String getHotspotBssid() {
|
||||
return mHotspotBssid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hotspot security types supported by the remote device.
|
||||
*
|
||||
* @return Returns the array of security types supported by the hotspot.
|
||||
*/
|
||||
@Nullable
|
||||
@SecurityType
|
||||
public int[] getHotspotSecurityTypes() {
|
||||
return mHotspotSecurityTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof TetherNetwork)) return false;
|
||||
TetherNetwork other = (TetherNetwork) obj;
|
||||
return mDeviceId == other.getDeviceId()
|
||||
&& Objects.equals(mDeviceInfo, other.getDeviceInfo())
|
||||
&& mNetworkType == other.getNetworkType()
|
||||
&& Objects.equals(mNetworkName, other.getNetworkName())
|
||||
&& Objects.equals(mHotspotSsid, other.getHotspotSsid())
|
||||
&& Objects.equals(mHotspotBssid, other.getHotspotBssid())
|
||||
&& Arrays.equals(mHotspotSecurityTypes, other.getHotspotSecurityTypes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mDeviceId, mDeviceInfo, mNetworkName, mHotspotSsid, mHotspotBssid,
|
||||
Arrays.hashCode(mHotspotSecurityTypes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeLong(mDeviceId);
|
||||
dest.writeTypedObject(mDeviceInfo, 0);
|
||||
dest.writeInt(mNetworkType);
|
||||
dest.writeString(mNetworkName);
|
||||
dest.writeString(mHotspotSsid);
|
||||
dest.writeString(mHotspotBssid);
|
||||
dest.writeIntArray(mHotspotSecurityTypes);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<TetherNetwork> CREATOR = new Creator<>() {
|
||||
@Override
|
||||
public TetherNetwork createFromParcel(Parcel in) {
|
||||
return new TetherNetwork(in.readLong(), in.readTypedObject(
|
||||
android.net.wifi.sharedconnectivity.app.DeviceInfo.CREATOR),
|
||||
in.readInt(), in.readString(), in.readString(), in.readString(),
|
||||
in.createIntArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TetherNetwork[] newArray(int size) {
|
||||
return new TetherNetwork[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder("TetherNetwork[")
|
||||
.append("deviceId=").append(mDeviceId)
|
||||
.append(", networkType=").append(mNetworkType)
|
||||
.append(", deviceInfo=").append(mDeviceInfo.toString())
|
||||
.append(", networkName=").append(mNetworkName)
|
||||
.append(", hotspotSsid=").append(mHotspotSsid)
|
||||
.append(", hotspotBssid=").append(mHotspotBssid)
|
||||
.append(", hotspotSecurityTypes=").append(Arrays.toString(mHotspotSecurityTypes))
|
||||
.append("]").toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.service;
|
||||
|
||||
import android.net.wifi.sharedconnectivity.app.KnownNetwork;
|
||||
import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState;
|
||||
import android.net.wifi.sharedconnectivity.app.TetherNetwork;
|
||||
|
||||
/*
|
||||
* @hide
|
||||
*/
|
||||
interface ISharedConnectivityCallback {
|
||||
oneway void onTetherNetworksUpdated(in List<TetherNetwork> networks);
|
||||
oneway void onKnownNetworksUpdated(in List<KnownNetwork> networks);
|
||||
oneway void onSharedConnectivitySettingsChanged(in SharedConnectivitySettingsState state);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.service;
|
||||
|
||||
import android.net.wifi.sharedconnectivity.app.KnownNetwork;
|
||||
import android.net.wifi.sharedconnectivity.app.TetherNetwork;
|
||||
import android.net.wifi.sharedconnectivity.service.ISharedConnectivityCallback;
|
||||
|
||||
/*
|
||||
* @hide
|
||||
*/
|
||||
interface ISharedConnectivityService {
|
||||
void registerCallback(in ISharedConnectivityCallback callback);
|
||||
void unregisterCallback(in ISharedConnectivityCallback callback);
|
||||
void connectTetherNetwork(in TetherNetwork network);
|
||||
void disconnectTetherNetwork();
|
||||
void connectKnownNetwork(in KnownNetwork network);
|
||||
void forgetKnownNetwork(in KnownNetwork network);
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.service;
|
||||
|
||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||
import static android.Manifest.permission.NETWORK_SETUP_WIZARD;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.wifi.sharedconnectivity.app.KnownNetwork;
|
||||
import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager;
|
||||
import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState;
|
||||
import android.net.wifi.sharedconnectivity.app.TetherNetwork;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* This class is the partly implemented service for injecting Shared Connectivity networks into the
|
||||
* Wi-Fi Pickers and other relevant UI surfaces.
|
||||
*
|
||||
* Implementing application should extend this service and override the indicated methods.
|
||||
* Callers to the service should use {@link SharedConnectivityManager} to bind to the implemented
|
||||
* service as specified in the configuration overlay.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public abstract class SharedConnectivityService extends Service {
|
||||
private static final String TAG = SharedConnectivityService.class.getSimpleName();
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
private final Handler mHandler;
|
||||
private final List<ISharedConnectivityCallback> mCallbacks = new ArrayList<>();
|
||||
// Used to find DeathRecipient when unregistering a callback to call unlinkToDeath.
|
||||
private final Map<ISharedConnectivityCallback, DeathRecipient> mDeathRecipientMap =
|
||||
new HashMap<>();
|
||||
|
||||
private List<TetherNetwork> mTetherNetworks = Collections.emptyList();
|
||||
private List<KnownNetwork> mKnownNetworks = Collections.emptyList();
|
||||
private SharedConnectivitySettingsState mSettingsState;
|
||||
|
||||
public SharedConnectivityService() {
|
||||
mHandler = new Handler(getMainLooper());
|
||||
}
|
||||
|
||||
public SharedConnectivityService(@NonNull Handler handler) {
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
private final class DeathRecipient implements IBinder.DeathRecipient {
|
||||
ISharedConnectivityCallback mCallback;
|
||||
|
||||
DeathRecipient(ISharedConnectivityCallback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void binderDied() {
|
||||
mCallbacks.remove(mCallback);
|
||||
mDeathRecipientMap.remove(mCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public IBinder onBind(@NonNull Intent intent) {
|
||||
if (DEBUG) Log.i(TAG, "onBind intent=" + intent);
|
||||
return new ISharedConnectivityService.Stub() {
|
||||
@Override
|
||||
public void registerCallback(ISharedConnectivityCallback callback) {
|
||||
checkPermissions();
|
||||
mHandler.post(() -> registerCallback(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterCallback(ISharedConnectivityCallback callback) {
|
||||
checkPermissions();
|
||||
mHandler.post(() -> unregisterCallback(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectTetherNetwork(TetherNetwork network) {
|
||||
checkPermissions();
|
||||
mHandler.post(() -> onConnectTetherNetwork(network));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnectTetherNetwork() {
|
||||
checkPermissions();
|
||||
mHandler.post(() -> onDisconnectTetherNetwork());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectKnownNetwork(KnownNetwork network) {
|
||||
checkPermissions();
|
||||
mHandler.post(() -> onConnectKnownNetwork(network));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forgetKnownNetwork(KnownNetwork network) {
|
||||
checkPermissions();
|
||||
mHandler.post(() -> onForgetKnownNetwork(network));
|
||||
}
|
||||
|
||||
@RequiresPermission(anyOf = {android.Manifest.permission.NETWORK_SETTINGS,
|
||||
android.Manifest.permission.NETWORK_SETUP_WIZARD})
|
||||
private void checkPermissions() {
|
||||
if (checkCallingPermission(NETWORK_SETTINGS) != PackageManager.PERMISSION_GRANTED
|
||||
&& checkCallingPermission(NETWORK_SETUP_WIZARD)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
throw new SecurityException("Calling process must have NETWORK_SETTINGS or"
|
||||
+ " NETWORK_SETUP_WIZARD permission");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void registerCallback(ISharedConnectivityCallback callback) {
|
||||
// Listener gets triggered on first register using cashed data
|
||||
if (!notifyTetherNetworkUpdate(callback) || !notifyKnownNetworkUpdate(callback)) {
|
||||
if (DEBUG) Log.w(TAG, "Failed to notify client");
|
||||
return;
|
||||
}
|
||||
|
||||
DeathRecipient deathRecipient = new DeathRecipient(callback);
|
||||
try {
|
||||
callback.asBinder().linkToDeath(deathRecipient, 0);
|
||||
mCallbacks.add(callback);
|
||||
mDeathRecipientMap.put(callback, deathRecipient);
|
||||
} catch (RemoteException e) {
|
||||
if (DEBUG) Log.w(TAG, "Exception in registerCallback", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterCallback(ISharedConnectivityCallback callback) {
|
||||
DeathRecipient deathRecipient = mDeathRecipientMap.get(callback);
|
||||
if (deathRecipient != null) {
|
||||
callback.asBinder().unlinkToDeath(deathRecipient, 0);
|
||||
mDeathRecipientMap.remove(callback);
|
||||
}
|
||||
mCallbacks.remove(callback);
|
||||
}
|
||||
|
||||
private boolean notifyTetherNetworkUpdate(ISharedConnectivityCallback callback) {
|
||||
try {
|
||||
callback.onTetherNetworksUpdated(mTetherNetworks);
|
||||
} catch (RemoteException e) {
|
||||
if (DEBUG) Log.w(TAG, "Exception in notifyTetherNetworkUpdate", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean notifyKnownNetworkUpdate(ISharedConnectivityCallback callback) {
|
||||
try {
|
||||
callback.onKnownNetworksUpdated(mKnownNetworks);
|
||||
} catch (RemoteException e) {
|
||||
if (DEBUG) Log.w(TAG, "Exception in notifyKnownNetworkUpdate", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean notifySettingsStateUpdate(ISharedConnectivityCallback callback) {
|
||||
try {
|
||||
callback.onSharedConnectivitySettingsChanged(mSettingsState);
|
||||
} catch (RemoteException e) {
|
||||
if (DEBUG) Log.w(TAG, "Exception in notifySettingsStateUpdate", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementing application should call this method to provide an up-to-date list of Tether
|
||||
* Networks to be displayed to the user.
|
||||
*
|
||||
* This method updates the cached list and notifies all registered callbacks. Any callbacks that
|
||||
* are inaccessible will be unregistered.
|
||||
*
|
||||
* @param networks The updated list of {@link TetherNetwork} objects.
|
||||
*/
|
||||
public final void setTetherNetworks(@NonNull List<TetherNetwork> networks) {
|
||||
mTetherNetworks = networks;
|
||||
|
||||
for (ISharedConnectivityCallback callback:mCallbacks) {
|
||||
notifyTetherNetworkUpdate(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementing application should call this method to provide an up-to-date list of Known
|
||||
* Networks to be displayed to the user.
|
||||
*
|
||||
* This method updates the cached list and notifies all registered callbacks. Any callbacks that
|
||||
* are inaccessible will be unregistered.
|
||||
*
|
||||
* @param networks The updated list of {@link KnownNetwork} objects.
|
||||
*/
|
||||
public final void setKnownNetworks(@NonNull List<KnownNetwork> networks) {
|
||||
mKnownNetworks = networks;
|
||||
|
||||
for (ISharedConnectivityCallback callback:mCallbacks) {
|
||||
notifyKnownNetworkUpdate(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementing application should call this method to provide an up-to-date state of Shared
|
||||
* connectivity settings state.
|
||||
*
|
||||
* This method updates the cached state and notifies all registered callbacks. Any callbacks
|
||||
* that are inaccessible will be unregistered.
|
||||
*
|
||||
* @param settingsState The updated state {@link SharedConnectivitySettingsState}
|
||||
* objects.
|
||||
*/
|
||||
public final void setSettingsState(@NonNull SharedConnectivitySettingsState settingsState) {
|
||||
mSettingsState = settingsState;
|
||||
|
||||
for (ISharedConnectivityCallback callback:mCallbacks) {
|
||||
notifySettingsStateUpdate(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementing application should implement this method.
|
||||
*
|
||||
* Implementation should initiate a connection to the Tether Network indicated.
|
||||
*
|
||||
* @param network Object identifying the Tether Network the user has requested a connection to.
|
||||
*/
|
||||
public abstract void onConnectTetherNetwork(@NonNull TetherNetwork network);
|
||||
|
||||
/**
|
||||
* Implementing application should implement this method.
|
||||
*
|
||||
* Implementation should initiate a disconnection from the active Tether Network.
|
||||
*/
|
||||
public abstract void onDisconnectTetherNetwork();
|
||||
|
||||
/**
|
||||
* Implementing application should implement this method.
|
||||
*
|
||||
* Implementation should initiate a connection to the Known Network indicated.
|
||||
*
|
||||
* @param network Object identifying the Known Network the user has requested a connection to.
|
||||
*/
|
||||
public abstract void onConnectKnownNetwork(@NonNull KnownNetwork network);
|
||||
|
||||
/**
|
||||
* Implementing application should implement this method.
|
||||
*
|
||||
* Implementation should remove the Known Network indicated from the synced list of networks.
|
||||
*
|
||||
* @param network Object identifying the Known Network the user has requested to forget.
|
||||
*/
|
||||
public abstract void onForgetKnownNetwork(@NonNull KnownNetwork network);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_LAPTOP;
|
||||
import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_PHONE;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link android.app.sharedconnectivity.DeviceInfo}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class DeviceInfoTest {
|
||||
|
||||
private static final int DEVICE_TYPE = DEVICE_TYPE_PHONE;
|
||||
private static final String DEVICE_NAME = "TEST_NAME";
|
||||
private static final String DEVICE_MODEL = "TEST_MODEL";
|
||||
private static final int BATTERY_PERCENTAGE = 50;
|
||||
private static final int CONNECTION_STRENGTH = 2;
|
||||
|
||||
private static final int DEVICE_TYPE_1 = DEVICE_TYPE_LAPTOP;
|
||||
private static final String DEVICE_NAME_1 = "TEST_NAME1";
|
||||
private static final String DEVICE_MODEL_1 = "TEST_MODEL1";
|
||||
private static final int BATTERY_PERCENTAGE_1 = 30;
|
||||
private static final int CONNECTION_STRENGTH_1 = 1;
|
||||
|
||||
/**
|
||||
* Verifies parcel serialization/deserialization.
|
||||
*/
|
||||
@Test
|
||||
public void testParcelOperation() {
|
||||
DeviceInfo info = buildDeviceInfoBuilder().build();
|
||||
|
||||
Parcel parcelW = Parcel.obtain();
|
||||
info.writeToParcel(parcelW, 0);
|
||||
byte[] bytes = parcelW.marshall();
|
||||
parcelW.recycle();
|
||||
|
||||
Parcel parcelR = Parcel.obtain();
|
||||
parcelR.unmarshall(bytes, 0, bytes.length);
|
||||
parcelR.setDataPosition(0);
|
||||
DeviceInfo fromParcel = DeviceInfo.CREATOR.createFromParcel(parcelR);
|
||||
|
||||
assertEquals(info, fromParcel);
|
||||
assertEquals(info.hashCode(), fromParcel.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the Equals operation
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsOperation() {
|
||||
DeviceInfo info1 = buildDeviceInfoBuilder().build();
|
||||
DeviceInfo info2 = buildDeviceInfoBuilder().build();
|
||||
assertEquals(info1, info2);
|
||||
|
||||
DeviceInfo.Builder builder = buildDeviceInfoBuilder().setDeviceType(DEVICE_TYPE_1);
|
||||
assertNotEquals(info1, builder.build());
|
||||
|
||||
builder = buildDeviceInfoBuilder().setDeviceName(DEVICE_NAME_1);
|
||||
assertNotEquals(info1, builder.build());
|
||||
|
||||
builder = buildDeviceInfoBuilder().setModelName(DEVICE_MODEL_1);
|
||||
assertNotEquals(info1, builder.build());
|
||||
|
||||
builder = buildDeviceInfoBuilder()
|
||||
.setBatteryPercentage(BATTERY_PERCENTAGE_1);
|
||||
assertNotEquals(info1, builder.build());
|
||||
|
||||
builder = buildDeviceInfoBuilder()
|
||||
.setConnectionStrength(CONNECTION_STRENGTH_1);
|
||||
assertNotEquals(info1, builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the get methods return the expected data.
|
||||
*/
|
||||
@Test
|
||||
public void testGetMethods() {
|
||||
DeviceInfo info = buildDeviceInfoBuilder().build();
|
||||
assertEquals(info.getDeviceType(), DEVICE_TYPE);
|
||||
assertEquals(info.getDeviceName(), DEVICE_NAME);
|
||||
assertEquals(info.getModelName(), DEVICE_MODEL);
|
||||
assertEquals(info.getBatteryPercentage(), BATTERY_PERCENTAGE);
|
||||
assertEquals(info.getConnectionStrength(), CONNECTION_STRENGTH);
|
||||
assertEquals(info.getConnectionStrength(), CONNECTION_STRENGTH);
|
||||
}
|
||||
|
||||
private DeviceInfo.Builder buildDeviceInfoBuilder() {
|
||||
return new DeviceInfo.Builder().setDeviceType(DEVICE_TYPE).setDeviceName(DEVICE_NAME)
|
||||
.setModelName(DEVICE_MODEL).setBatteryPercentage(BATTERY_PERCENTAGE)
|
||||
.setConnectionStrength(CONNECTION_STRENGTH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK;
|
||||
import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
|
||||
import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_PHONE;
|
||||
import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_TABLET;
|
||||
import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_CLOUD_SELF;
|
||||
import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_NEARBY_SELF;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link android.app.sharedconnectivity.KnownNetwork}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class KnownNetworkTest {
|
||||
|
||||
private static final int NETWORK_SOURCE = NETWORK_SOURCE_NEARBY_SELF;
|
||||
private static final String SSID = "TEST_SSID";
|
||||
private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP};
|
||||
private static final DeviceInfo DEVICE_INFO = new DeviceInfo.Builder()
|
||||
.setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
|
||||
.setConnectionStrength(2).setBatteryPercentage(50).build();
|
||||
private static final int NETWORK_SOURCE_1 = NETWORK_SOURCE_CLOUD_SELF;
|
||||
private static final String SSID_1 = "TEST_SSID1";
|
||||
private static final int[] SECURITY_TYPES_1 = {SECURITY_TYPE_PSK};
|
||||
private static final DeviceInfo DEVICE_INFO_1 = new DeviceInfo.Builder()
|
||||
.setDeviceType(DEVICE_TYPE_PHONE).setDeviceName("TEST_NAME_1")
|
||||
.setModelName("TEST_MODEL_1").setConnectionStrength(3).setBatteryPercentage(33).build();
|
||||
|
||||
/**
|
||||
* Verifies parcel serialization/deserialization.
|
||||
*/
|
||||
@Test
|
||||
public void testParcelOperation() {
|
||||
KnownNetwork network = buildKnownNetworkBuilder().build();
|
||||
|
||||
Parcel parcelW = Parcel.obtain();
|
||||
network.writeToParcel(parcelW, 0);
|
||||
byte[] bytes = parcelW.marshall();
|
||||
parcelW.recycle();
|
||||
|
||||
Parcel parcelR = Parcel.obtain();
|
||||
parcelR.unmarshall(bytes, 0, bytes.length);
|
||||
parcelR.setDataPosition(0);
|
||||
KnownNetwork fromParcel = KnownNetwork.CREATOR.createFromParcel(parcelR);
|
||||
|
||||
assertEquals(network, fromParcel);
|
||||
assertEquals(network.hashCode(), fromParcel.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the Equals operation
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsOperation() {
|
||||
KnownNetwork network1 = buildKnownNetworkBuilder().build();
|
||||
KnownNetwork network2 = buildKnownNetworkBuilder().build();
|
||||
assertEquals(network1, network2);
|
||||
|
||||
KnownNetwork.Builder builder = buildKnownNetworkBuilder()
|
||||
.setNetworkSource(NETWORK_SOURCE_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildKnownNetworkBuilder().setSsid(SSID_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildKnownNetworkBuilder().setSecurityTypes(SECURITY_TYPES_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildKnownNetworkBuilder().setDeviceInfo(DEVICE_INFO_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the get methods return the expected data.
|
||||
*/
|
||||
@Test
|
||||
public void testGetMethods() {
|
||||
KnownNetwork network = buildKnownNetworkBuilder().build();
|
||||
assertEquals(network.getNetworkSource(), NETWORK_SOURCE);
|
||||
assertEquals(network.getSsid(), SSID);
|
||||
assertArrayEquals(network.getSecurityTypes(), SECURITY_TYPES);
|
||||
assertEquals(network.getDeviceInfo(), DEVICE_INFO);
|
||||
}
|
||||
|
||||
private KnownNetwork.Builder buildKnownNetworkBuilder() {
|
||||
return new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE).setSsid(SSID)
|
||||
.setSecurityTypes(SECURITY_TYPES).setDeviceInfo(DEVICE_INFO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import static android.net.wifi.WifiInfo.SECURITY_TYPE_EAP;
|
||||
import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
|
||||
import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_TABLET;
|
||||
import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_NEARBY_SELF;
|
||||
import static android.net.wifi.sharedconnectivity.app.TetherNetwork.NETWORK_TYPE_CELLULAR;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.wifi.sharedconnectivity.service.ISharedConnectivityService;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SharedConnectivityManager}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class SharedConnectivityManagerTest {
|
||||
private static final long DEVICE_ID = 11L;
|
||||
private static final DeviceInfo DEVICE_INFO = new DeviceInfo.Builder()
|
||||
.setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
|
||||
.setConnectionStrength(2).setBatteryPercentage(50).build();
|
||||
private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR;
|
||||
private static final String NETWORK_NAME = "TEST_NETWORK";
|
||||
private static final String HOTSPOT_SSID = "TEST_SSID";
|
||||
private static final int[] HOTSPOT_SECURITY_TYPES = {SECURITY_TYPE_WEP, SECURITY_TYPE_EAP};
|
||||
|
||||
private static final int NETWORK_SOURCE = NETWORK_SOURCE_NEARBY_SELF;
|
||||
private static final String SSID = "TEST_SSID";
|
||||
private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP};
|
||||
|
||||
private static final int SERVICE_PACKAGE_ID = 1;
|
||||
private static final int SERVICE_CLASS_ID = 2;
|
||||
|
||||
private static final String SERVICE_PACKAGE_NAME = "TEST_PACKAGE";
|
||||
private static final String SERVICE_CLASS_NAME = "TEST_CLASS";
|
||||
private static final String PACKAGE_NAME = "TEST_PACKAGE";
|
||||
|
||||
@Mock Context mContext;
|
||||
@Mock
|
||||
ISharedConnectivityService mService;
|
||||
@Mock Executor mExecutor;
|
||||
@Mock
|
||||
SharedConnectivityClientCallback mClientCallback;
|
||||
@Mock Resources mResources;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
setResources(mContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies constructor is binding to service.
|
||||
*/
|
||||
@Test
|
||||
public void testBindingToService() {
|
||||
new SharedConnectivityManager(mContext);
|
||||
verify(mContext).bindService(any(), any(), anyInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies callback is registered in the service only once and only when service is not null.
|
||||
*/
|
||||
@Test
|
||||
public void testRegisterCallback() throws Exception {
|
||||
SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(null);
|
||||
assertFalse(manager.registerCallback(mExecutor, mClientCallback));
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
assertTrue(manager.registerCallback(mExecutor, mClientCallback));
|
||||
verify(mService).registerCallback(any());
|
||||
|
||||
// Registering the same callback twice should fail.
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
manager.registerCallback(mExecutor, mClientCallback);
|
||||
assertFalse(manager.registerCallback(mExecutor, mClientCallback));
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
doThrow(new RemoteException()).when(mService).registerCallback(any());
|
||||
assertFalse(manager.registerCallback(mExecutor, mClientCallback));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies callback is unregistered from the service if it was registered before and only when
|
||||
* service is not null.
|
||||
*/
|
||||
@Test
|
||||
public void testUnregisterCallback() throws Exception {
|
||||
SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(null);
|
||||
assertFalse(manager.unregisterCallback(mClientCallback));
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
manager.registerCallback(mExecutor, mClientCallback);
|
||||
assertTrue(manager.unregisterCallback(mClientCallback));
|
||||
verify(mService).unregisterCallback(any());
|
||||
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
manager.registerCallback(mExecutor, mClientCallback);
|
||||
manager.unregisterCallback(mClientCallback);
|
||||
assertFalse(manager.unregisterCallback(mClientCallback));
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
doThrow(new RemoteException()).when(mService).unregisterCallback(any());
|
||||
assertFalse(manager.unregisterCallback(mClientCallback));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies service is called when not null and exceptions are handles when calling
|
||||
* connectTetherNetwork.
|
||||
*/
|
||||
@Test
|
||||
public void testConnectTetherNetwork() throws RemoteException {
|
||||
TetherNetwork network = buildTetherNetwork();
|
||||
|
||||
SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(null);
|
||||
assertFalse(manager.connectTetherNetwork(network));
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
manager.connectTetherNetwork(network);
|
||||
verify(mService).connectTetherNetwork(network);
|
||||
|
||||
doThrow(new RemoteException()).when(mService).connectTetherNetwork(network);
|
||||
assertFalse(manager.connectTetherNetwork(network));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies service is called when not null and exceptions are handles when calling
|
||||
* disconnectTetherNetwork.
|
||||
*/
|
||||
@Test
|
||||
public void testDisconnectTetherNetwork() throws RemoteException {
|
||||
SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(null);
|
||||
assertFalse(manager.disconnectTetherNetwork());
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
manager.disconnectTetherNetwork();
|
||||
verify(mService).disconnectTetherNetwork();
|
||||
|
||||
doThrow(new RemoteException()).when(mService).disconnectTetherNetwork();
|
||||
assertFalse(manager.disconnectTetherNetwork());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies service is called when not null and exceptions are handles when calling
|
||||
* connectKnownNetwork.
|
||||
*/
|
||||
@Test
|
||||
public void testConnectKnownNetwork() throws RemoteException {
|
||||
KnownNetwork network = buildKnownNetwork();
|
||||
|
||||
SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(null);
|
||||
assertFalse(manager.connectKnownNetwork(network));
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
manager.connectKnownNetwork(network);
|
||||
verify(mService).connectKnownNetwork(network);
|
||||
|
||||
doThrow(new RemoteException()).when(mService).connectKnownNetwork(network);
|
||||
assertFalse(manager.connectKnownNetwork(network));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies service is called when not null and exceptions are handles when calling
|
||||
* forgetKnownNetwork.
|
||||
*/
|
||||
@Test
|
||||
public void testForgetKnownNetwork() throws RemoteException {
|
||||
KnownNetwork network = buildKnownNetwork();
|
||||
|
||||
SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(null);
|
||||
assertFalse(manager.forgetKnownNetwork(network));
|
||||
|
||||
manager = new SharedConnectivityManager(mContext);
|
||||
manager.setService(mService);
|
||||
manager.forgetKnownNetwork(network);
|
||||
verify(mService).forgetKnownNetwork(network);
|
||||
|
||||
doThrow(new RemoteException()).when(mService).forgetKnownNetwork(network);
|
||||
assertFalse(manager.forgetKnownNetwork(network));
|
||||
}
|
||||
|
||||
private void setResources(@Mock Context context) {
|
||||
when(context.getResources()).thenReturn(mResources);
|
||||
when(context.getPackageName()).thenReturn(PACKAGE_NAME);
|
||||
when(mResources.getIdentifier(anyString(), anyString(), anyString()))
|
||||
.thenReturn(SERVICE_PACKAGE_ID, SERVICE_CLASS_ID);
|
||||
when(mResources.getString(SERVICE_PACKAGE_ID)).thenReturn(SERVICE_PACKAGE_NAME);
|
||||
when(mResources.getString(SERVICE_CLASS_ID)).thenReturn(SERVICE_CLASS_NAME);
|
||||
}
|
||||
|
||||
private TetherNetwork buildTetherNetwork() {
|
||||
return new TetherNetwork.Builder()
|
||||
.setDeviceId(DEVICE_ID)
|
||||
.setDeviceInfo(DEVICE_INFO)
|
||||
.setNetworkType(NETWORK_TYPE)
|
||||
.setNetworkName(NETWORK_NAME)
|
||||
.setHotspotSsid(HOTSPOT_SSID)
|
||||
.setHotspotSecurityTypes(HOTSPOT_SECURITY_TYPES)
|
||||
.build();
|
||||
}
|
||||
|
||||
private KnownNetwork buildKnownNetwork() {
|
||||
return new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE).setSsid(SSID)
|
||||
.setSecurityTypes(SECURITY_TYPES).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class SharedConnectivitySettingsStateTest {
|
||||
private static final boolean INSTANT_TETHER_STATE = true;
|
||||
|
||||
private static final boolean INSTANT_TETHER_STATE_1 = false;
|
||||
/**
|
||||
* Verifies parcel serialization/deserialization.
|
||||
*/
|
||||
@Test
|
||||
public void testParcelOperation() {
|
||||
SharedConnectivitySettingsState state = buildSettingsStateBuilder().build();
|
||||
|
||||
Parcel parcelW = Parcel.obtain();
|
||||
state.writeToParcel(parcelW, 0);
|
||||
byte[] bytes = parcelW.marshall();
|
||||
parcelW.recycle();
|
||||
|
||||
Parcel parcelR = Parcel.obtain();
|
||||
parcelR.unmarshall(bytes, 0, bytes.length);
|
||||
parcelR.setDataPosition(0);
|
||||
SharedConnectivitySettingsState fromParcel =
|
||||
SharedConnectivitySettingsState.CREATOR.createFromParcel(parcelR);
|
||||
|
||||
assertEquals(state, fromParcel);
|
||||
assertEquals(state.hashCode(), fromParcel.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the Equals operation
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsOperation() {
|
||||
SharedConnectivitySettingsState state1 = buildSettingsStateBuilder().build();
|
||||
SharedConnectivitySettingsState state2 = buildSettingsStateBuilder().build();
|
||||
assertEquals(state1, state2);
|
||||
|
||||
SharedConnectivitySettingsState.Builder builder = buildSettingsStateBuilder()
|
||||
.setInstantTetherEnabled(INSTANT_TETHER_STATE_1);
|
||||
assertNotEquals(state1, builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the get methods return the expected data.
|
||||
*/
|
||||
@Test
|
||||
public void testGetMethods() {
|
||||
SharedConnectivitySettingsState state = buildSettingsStateBuilder().build();
|
||||
assertEquals(state.isInstantTetherEnabled(), INSTANT_TETHER_STATE);
|
||||
}
|
||||
|
||||
private SharedConnectivitySettingsState.Builder buildSettingsStateBuilder() {
|
||||
return new SharedConnectivitySettingsState.Builder()
|
||||
.setInstantTetherEnabled(INSTANT_TETHER_STATE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.app;
|
||||
|
||||
import static android.net.wifi.WifiInfo.SECURITY_TYPE_EAP;
|
||||
import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK;
|
||||
import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
|
||||
import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_PHONE;
|
||||
import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_TABLET;
|
||||
import static android.net.wifi.sharedconnectivity.app.TetherNetwork.NETWORK_TYPE_CELLULAR;
|
||||
import static android.net.wifi.sharedconnectivity.app.TetherNetwork.NETWORK_TYPE_WIFI;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link android.net.wifi.sharedconnectivity.app.TetherNetwork}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class TetherNetworkTest {
|
||||
private static final long DEVICE_ID = 11L;
|
||||
private static final DeviceInfo DEVICE_INFO = new DeviceInfo.Builder()
|
||||
.setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
|
||||
.setConnectionStrength(2).setBatteryPercentage(50).build();
|
||||
private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR;
|
||||
private static final String NETWORK_NAME = "TEST_NETWORK";
|
||||
private static final String HOTSPOT_SSID = "TEST_SSID";
|
||||
private static final String HOTSPOT_BSSID = "TEST _BSSID";
|
||||
private static final int[] HOTSPOT_SECURITY_TYPES = {SECURITY_TYPE_WEP, SECURITY_TYPE_EAP};
|
||||
|
||||
private static final long DEVICE_ID_1 = 111L;
|
||||
private static final DeviceInfo DEVICE_INFO_1 = new DeviceInfo.Builder()
|
||||
.setDeviceType(DEVICE_TYPE_PHONE).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
|
||||
.setConnectionStrength(2).setBatteryPercentage(50).build();
|
||||
private static final int NETWORK_TYPE_1 = NETWORK_TYPE_WIFI;
|
||||
private static final String NETWORK_NAME_1 = "TEST_NETWORK1";
|
||||
private static final String HOTSPOT_SSID_1 = "TEST_SSID1";
|
||||
private static final String HOTSPOT_BSSID_1 = "TEST _BSSID1";
|
||||
private static final int[] HOTSPOT_SECURITY_TYPES_1 = {SECURITY_TYPE_PSK, SECURITY_TYPE_EAP};
|
||||
|
||||
/**
|
||||
* Verifies parcel serialization/deserialization.
|
||||
*/
|
||||
@Test
|
||||
public void testParcelOperation() {
|
||||
TetherNetwork network = buildTetherNetworkBuilder().build();
|
||||
|
||||
Parcel parcelW = Parcel.obtain();
|
||||
network.writeToParcel(parcelW, 0);
|
||||
byte[] bytes = parcelW.marshall();
|
||||
parcelW.recycle();
|
||||
|
||||
Parcel parcelR = Parcel.obtain();
|
||||
parcelR.unmarshall(bytes, 0, bytes.length);
|
||||
parcelR.setDataPosition(0);
|
||||
TetherNetwork fromParcel = TetherNetwork.CREATOR.createFromParcel(parcelR);
|
||||
|
||||
assertEquals(network, fromParcel);
|
||||
assertEquals(network.hashCode(), fromParcel.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the Equals operation
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsOperation() {
|
||||
TetherNetwork network1 = buildTetherNetworkBuilder().build();
|
||||
TetherNetwork network2 = buildTetherNetworkBuilder().build();
|
||||
assertEquals(network1, network2);
|
||||
|
||||
TetherNetwork.Builder builder = buildTetherNetworkBuilder().setDeviceId(DEVICE_ID_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildTetherNetworkBuilder().setDeviceInfo(DEVICE_INFO_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildTetherNetworkBuilder().setNetworkType(NETWORK_TYPE_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildTetherNetworkBuilder().setNetworkName(NETWORK_NAME_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildTetherNetworkBuilder().setHotspotSsid(HOTSPOT_SSID_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildTetherNetworkBuilder().setHotspotBssid(HOTSPOT_BSSID_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
|
||||
builder = buildTetherNetworkBuilder().setHotspotSecurityTypes(HOTSPOT_SECURITY_TYPES_1);
|
||||
assertNotEquals(network1, builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the get methods return the expected data.
|
||||
*/
|
||||
@Test
|
||||
public void testGetMethods() {
|
||||
TetherNetwork network = buildTetherNetworkBuilder().build();
|
||||
assertEquals(network.getDeviceId(), DEVICE_ID);
|
||||
assertEquals(network.getDeviceInfo(), DEVICE_INFO);
|
||||
assertEquals(network.getNetworkType(), NETWORK_TYPE);
|
||||
assertEquals(network.getNetworkName(), NETWORK_NAME);
|
||||
assertEquals(network.getHotspotSsid(), HOTSPOT_SSID);
|
||||
assertEquals(network.getHotspotBssid(), HOTSPOT_BSSID);
|
||||
assertArrayEquals(network.getHotspotSecurityTypes(), HOTSPOT_SECURITY_TYPES);
|
||||
}
|
||||
|
||||
private TetherNetwork.Builder buildTetherNetworkBuilder() {
|
||||
return new TetherNetwork.Builder()
|
||||
.setDeviceId(DEVICE_ID)
|
||||
.setDeviceInfo(DEVICE_INFO)
|
||||
.setNetworkType(NETWORK_TYPE)
|
||||
.setNetworkName(NETWORK_NAME)
|
||||
.setHotspotSsid(HOTSPOT_SSID)
|
||||
.setHotspotBssid(HOTSPOT_BSSID)
|
||||
.setHotspotSecurityTypes(HOTSPOT_SECURITY_TYPES);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.wifi.sharedconnectivity.service;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.wifi.sharedconnectivity.app.KnownNetwork;
|
||||
import android.net.wifi.sharedconnectivity.app.TetherNetwork;
|
||||
import android.os.Handler;
|
||||
import android.os.test.TestLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link android.net.wifi.sharedconnectivity.service.SharedConnectivityService}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class SharedConnectivityServiceTest {
|
||||
|
||||
/**
|
||||
* Verifies service returns
|
||||
*/
|
||||
@Test
|
||||
public void testOnBind() {
|
||||
SharedConnectivityService service = createService();
|
||||
assertNotNull(service.onBind(new Intent()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallbacks() {
|
||||
SharedConnectivityService service = createService();
|
||||
ISharedConnectivityService.Stub binder =
|
||||
(ISharedConnectivityService.Stub) service.onBind(new Intent());
|
||||
}
|
||||
|
||||
private SharedConnectivityService createService() {
|
||||
return new SharedConnectivityService(new Handler(new TestLooper().getLooper())) {
|
||||
@Override
|
||||
public void onConnectTetherNetwork(TetherNetwork network) {}
|
||||
|
||||
@Override
|
||||
public void onDisconnectTetherNetwork() {}
|
||||
|
||||
@Override
|
||||
public void onConnectKnownNetwork(KnownNetwork network) {}
|
||||
|
||||
@Override
|
||||
public void onForgetKnownNetwork(KnownNetwork network) {}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user