lowpan: Make various data classes Parcelable

This change updates several of the data classes in
`android.net.lowpan` to be parcelable. This allows them to be used
directly for inter-process communication.

Bug: b/63707448 b/63708348
Change-Id: Ib5e8cad153534948ff4b43a2fda82f3db250839e
Test: Confirmed with unit tests from change id
      I41d590b1e77dc41873c4b9e9bf1b7f1bf859f74e
This commit is contained in:
Robert Quattlebaum
2017-07-14 12:02:19 -07:00
parent ccd0a151a9
commit 80aca1e3b3
10 changed files with 685 additions and 162 deletions

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.lowpan;
parcelable LowpanBeaconInfo cpp_header "android/net/lowpan/LowpanBeaconInfo.h";

View File

@@ -16,9 +16,12 @@
package android.net.lowpan;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.HexDump;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.TreeSet;
/**
@@ -27,70 +30,93 @@ import java.util.TreeSet;
* @hide
*/
// @SystemApi
public class LowpanBeaconInfo extends LowpanIdentity {
public class LowpanBeaconInfo implements Parcelable {
public static final int UNKNOWN_RSSI = Integer.MAX_VALUE;
public static final int UNKNOWN_LQI = 0;
private int mRssi = UNKNOWN;
private int mLqi = UNKNOWN;
private LowpanIdentity mIdentity;
private int mRssi = UNKNOWN_RSSI;
private int mLqi = UNKNOWN_LQI;
private byte[] mBeaconAddress = null;
private final TreeSet<Integer> mFlags = new TreeSet<>();
public static final int FLAG_CAN_ASSIST = 1;
static class Builder extends LowpanIdentity.Builder {
private final LowpanBeaconInfo identity = new LowpanBeaconInfo();
/** @hide */
public static class Builder {
final LowpanIdentity.Builder mIdentityBuilder = new LowpanIdentity.Builder();
final LowpanBeaconInfo mBeaconInfo = new LowpanBeaconInfo();
public Builder setLowpanIdentity(LowpanIdentity x) {
mIdentityBuilder.setLowpanIdentity(x);
return this;
}
public Builder setName(String x) {
mIdentityBuilder.setName(x);
return this;
}
public Builder setXpanid(byte x[]) {
mIdentityBuilder.setXpanid(x);
return this;
}
public Builder setPanid(int x) {
mIdentityBuilder.setPanid(x);
return this;
}
public Builder setChannel(int x) {
mIdentityBuilder.setChannel(x);
return this;
}
public Builder setType(String x) {
mIdentityBuilder.setType(x);
return this;
}
public Builder setRssi(int x) {
identity.mRssi = x;
mBeaconInfo.mRssi = x;
return this;
}
public Builder setLqi(int x) {
identity.mLqi = x;
mBeaconInfo.mLqi = x;
return this;
}
public Builder setBeaconAddress(byte x[]) {
identity.mBeaconAddress = x.clone();
mBeaconInfo.mBeaconAddress = (x != null ? x.clone() : null);
return this;
}
public Builder setFlag(int x) {
identity.mFlags.add(x);
mBeaconInfo.mFlags.add(x);
return this;
}
public Builder setFlags(Collection<Integer> x) {
identity.mFlags.addAll(x);
return this;
}
/** @hide */
Builder updateFromMap(Map map) {
if (map.containsKey(LowpanProperties.KEY_RSSI.getName())) {
setRssi(LowpanProperties.KEY_RSSI.getFromMap(map));
}
if (map.containsKey(LowpanProperties.KEY_LQI.getName())) {
setLqi(LowpanProperties.KEY_LQI.getFromMap(map));
}
if (map.containsKey(LowpanProperties.KEY_BEACON_ADDRESS.getName())) {
setBeaconAddress(LowpanProperties.KEY_BEACON_ADDRESS.getFromMap(map));
}
identity.mFlags.clear();
if (map.containsKey(LowpanProperties.KEY_BEACON_CAN_ASSIST.getName())
&& LowpanProperties.KEY_BEACON_CAN_ASSIST.getFromMap(map).booleanValue()) {
setFlag(FLAG_CAN_ASSIST);
}
super.updateFromMap(map);
mBeaconInfo.mFlags.addAll(x);
return this;
}
public LowpanBeaconInfo build() {
return identity;
mBeaconInfo.mIdentity = mIdentityBuilder.build();
if (mBeaconInfo.mBeaconAddress == null) {
mBeaconInfo.mBeaconAddress = new byte[0];
}
return mBeaconInfo;
}
}
private LowpanBeaconInfo() {}
public LowpanIdentity getLowpanIdentity() {
return mIdentity;
}
public int getRssi() {
return mRssi;
}
@@ -111,27 +137,22 @@ public class LowpanBeaconInfo extends LowpanIdentity {
return mFlags.contains(flag);
}
@Override
void addToMap(Map<String, Object> parameters) {
super.addToMap(parameters);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString());
sb.append(mIdentity.toString());
if (mRssi != UNKNOWN) {
sb.append(", RSSI: ").append(mRssi);
if (mRssi != UNKNOWN_RSSI) {
sb.append(", RSSI:").append(mRssi).append("dBm");
}
if (mLqi != UNKNOWN) {
sb.append(", LQI: ").append(mLqi);
if (mLqi != UNKNOWN_LQI) {
sb.append(", LQI:").append(mLqi);
}
if (mBeaconAddress != null) {
sb.append(", BeaconAddress: ").append(HexDump.toHexString(mBeaconAddress));
if (mBeaconAddress.length > 0) {
sb.append(", BeaconAddress:").append(HexDump.toHexString(mBeaconAddress));
}
for (Integer flag : mFlags) {
@@ -147,4 +168,67 @@ public class LowpanBeaconInfo extends LowpanIdentity {
return sb.toString();
}
@Override
public int hashCode() {
return Objects.hash(mIdentity, mRssi, mLqi, Arrays.hashCode(mBeaconAddress), mFlags);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanBeaconInfo)) {
return false;
}
LowpanBeaconInfo rhs = (LowpanBeaconInfo) obj;
return mIdentity.equals(rhs.mIdentity)
&& Arrays.equals(mBeaconAddress, rhs.mBeaconAddress)
&& mRssi == rhs.mRssi
&& mLqi == rhs.mLqi
&& mFlags.equals(rhs.mFlags);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
mIdentity.writeToParcel(dest, flags);
dest.writeInt(mRssi);
dest.writeInt(mLqi);
dest.writeByteArray(mBeaconAddress);
dest.writeInt(mFlags.size());
for (Integer val : mFlags) {
dest.writeInt(val);
}
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanBeaconInfo> CREATOR =
new Creator<LowpanBeaconInfo>() {
public LowpanBeaconInfo createFromParcel(Parcel in) {
Builder builder = new Builder();
builder.setLowpanIdentity(LowpanIdentity.CREATOR.createFromParcel(in));
builder.setRssi(in.readInt());
builder.setLqi(in.readInt());
builder.setBeaconAddress(in.createByteArray());
for (int i = in.readInt(); i > 0; i--) {
builder.setFlag(in.readInt());
}
return builder.build();
}
public LowpanBeaconInfo[] newArray(int size) {
return new LowpanBeaconInfo[size];
}
};
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.lowpan;
parcelable LowpanChannelInfo cpp_header "android/net/lowpan/LowpanChannelInfo.h";

View File

@@ -16,22 +16,66 @@
package android.net.lowpan;
/** Provides detailed information about a given channel. */
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Provides detailed information about a given channel.
*
* @hide
*/
// @SystemApi
public class LowpanChannelInfo {
public class LowpanChannelInfo implements Parcelable {
public static final int UNKNOWN_POWER = Integer.MAX_VALUE;
public static final float UNKNOWN_FREQUENCY = 0.0f;
public static final float UNKNOWN_BANDWIDTH = 0.0f;
// Instance Variables
private String mName = null;
private int mIndex = 0;
private boolean mIsMaskedByRegulatoryDomain = false;
private float mSpectrumCenterFrequency = 0.0f;
private float mSpectrumBandwidth = 0.0f;
private String mName = null;
private float mSpectrumCenterFrequency = UNKNOWN_FREQUENCY;
private float mSpectrumBandwidth = UNKNOWN_BANDWIDTH;
private int mMaxTransmitPower = UNKNOWN_POWER;
private boolean mIsMaskedByRegulatoryDomain = false;
// Public Getters and Setters
/** @hide */
public static LowpanChannelInfo getChannelInfoForIeee802154Page0(int index) {
LowpanChannelInfo info = new LowpanChannelInfo();
if (index < 0) {
info = null;
} else if (index == 0) {
info.mSpectrumCenterFrequency = 868300000.0f;
info.mSpectrumBandwidth = 600000.0f;
} else if (index < 11) {
info.mSpectrumCenterFrequency = 906000000.0f - (2000000.0f * 1) + 2000000.0f * (index);
info.mSpectrumBandwidth = 0; // Unknown
} else if (index < 26) {
info.mSpectrumCenterFrequency =
2405000000.0f - (5000000.0f * 11) + 5000000.0f * (index);
info.mSpectrumBandwidth = 2000000.0f;
} else {
info = null;
}
info.mName = Integer.toString(index);
return info;
}
private LowpanChannelInfo() {}
private LowpanChannelInfo(int index, String name, float cf, float bw) {
mIndex = index;
mName = name;
mSpectrumCenterFrequency = cf;
mSpectrumBandwidth = bw;
}
public String getName() {
return mName;
@@ -63,22 +107,110 @@ public class LowpanChannelInfo {
sb.append("Channel ").append(mIndex);
if (mName != null) {
if (mName != null && !mName.equals(Integer.toString(mIndex))) {
sb.append(" (").append(mName).append(")");
}
if (mSpectrumCenterFrequency > 0.0f) {
sb.append(", SpectrumCenterFrequency: ").append(mSpectrumCenterFrequency).append("Hz");
if (mSpectrumCenterFrequency > 1000000000.0f) {
sb.append(", SpectrumCenterFrequency: ")
.append(mSpectrumCenterFrequency / 1000000000.0f)
.append("GHz");
} else if (mSpectrumCenterFrequency > 1000000.0f) {
sb.append(", SpectrumCenterFrequency: ")
.append(mSpectrumCenterFrequency / 1000000.0f)
.append("MHz");
} else {
sb.append(", SpectrumCenterFrequency: ")
.append(mSpectrumCenterFrequency / 1000.0f)
.append("kHz");
}
}
if (mSpectrumBandwidth > 0.0f) {
sb.append(", SpectrumBandwidth: ").append(mSpectrumBandwidth).append("Hz");
if (mSpectrumBandwidth > 1000000000.0f) {
sb.append(", SpectrumBandwidth: ")
.append(mSpectrumBandwidth / 1000000000.0f)
.append("GHz");
} else if (mSpectrumBandwidth > 1000000.0f) {
sb.append(", SpectrumBandwidth: ")
.append(mSpectrumBandwidth / 1000000.0f)
.append("MHz");
} else {
sb.append(", SpectrumBandwidth: ")
.append(mSpectrumBandwidth / 1000.0f)
.append("kHz");
}
}
if (mMaxTransmitPower != UNKNOWN_POWER) {
sb.append(", MaxTransmitPower: ").append(mMaxTransmitPower);
sb.append(", MaxTransmitPower: ").append(mMaxTransmitPower).append("dBm");
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanChannelInfo)) {
return false;
}
LowpanChannelInfo rhs = (LowpanChannelInfo) obj;
return Objects.equals(mName, rhs.mName)
&& mIndex == rhs.mIndex
&& mIsMaskedByRegulatoryDomain == rhs.mIsMaskedByRegulatoryDomain
&& mSpectrumCenterFrequency == rhs.mSpectrumCenterFrequency
&& mSpectrumBandwidth == rhs.mSpectrumBandwidth
&& mMaxTransmitPower == rhs.mMaxTransmitPower;
}
@Override
public int hashCode() {
return Objects.hash(
mName,
mIndex,
mIsMaskedByRegulatoryDomain,
mSpectrumCenterFrequency,
mSpectrumBandwidth,
mMaxTransmitPower);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mIndex);
dest.writeString(mName);
dest.writeFloat(mSpectrumCenterFrequency);
dest.writeFloat(mSpectrumBandwidth);
dest.writeInt(mMaxTransmitPower);
dest.writeBoolean(mIsMaskedByRegulatoryDomain);
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanChannelInfo> CREATOR =
new Creator<LowpanChannelInfo>() {
public LowpanChannelInfo createFromParcel(Parcel in) {
LowpanChannelInfo info = new LowpanChannelInfo();
info.mIndex = in.readInt();
info.mName = in.readString();
info.mSpectrumCenterFrequency = in.readFloat();
info.mSpectrumBandwidth = in.readFloat();
info.mMaxTransmitPower = in.readInt();
info.mIsMaskedByRegulatoryDomain = in.readBoolean();
return info;
}
public LowpanChannelInfo[] newArray(int size) {
return new LowpanChannelInfo[size];
}
};
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.lowpan;
parcelable LowpanCredential cpp_header "android/net/lowpan/LowpanCredential.h";

View File

@@ -16,7 +16,11 @@
package android.net.lowpan;
import java.util.Map;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.HexDump;
import java.util.Arrays;
import java.util.Objects;
/**
* Describes a credential for a LoWPAN network.
@@ -24,7 +28,7 @@ import java.util.Map;
* @hide
*/
// @SystemApi
public class LowpanCredential {
public class LowpanCredential implements Parcelable {
public static final int UNSPECIFIED_KEY_INDEX = 0;
@@ -49,18 +53,18 @@ public class LowpanCredential {
return new LowpanCredential(masterKey, keyIndex);
}
public void setMasterKey(byte[] masterKey) {
void setMasterKey(byte[] masterKey) {
if (masterKey != null) {
masterKey = masterKey.clone();
}
mMasterKey = masterKey;
}
public void setMasterKeyIndex(int keyIndex) {
void setMasterKeyIndex(int keyIndex) {
mMasterKeyIndex = keyIndex;
}
public void setMasterKey(byte[] masterKey, int keyIndex) {
void setMasterKey(byte[] masterKey, int keyIndex) {
setMasterKey(masterKey);
setMasterKeyIndex(keyIndex);
}
@@ -80,12 +84,89 @@ public class LowpanCredential {
return mMasterKey != null;
}
void addToMap(Map<String, Object> parameters) throws LowpanException {
public String toSensitiveString() {
StringBuffer sb = new StringBuffer();
sb.append("<LowpanCredential");
if (isMasterKey()) {
LowpanProperties.KEY_NETWORK_MASTER_KEY.putInMap(parameters, getMasterKey());
LowpanProperties.KEY_NETWORK_MASTER_KEY_INDEX.putInMap(parameters, getMasterKeyIndex());
sb.append(" MasterKey:").append(HexDump.toHexString(mMasterKey));
if (mMasterKeyIndex != UNSPECIFIED_KEY_INDEX) {
sb.append(", Index:").append(mMasterKeyIndex);
}
} else {
throw new LowpanException("Unsupported Network Credential");
sb.append(" empty");
}
sb.append(">");
return sb.toString();
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("<LowpanCredential");
if (isMasterKey()) {
// We don't print out the contents of the key here,
// we only do that in toSensitiveString.
sb.append(" MasterKey");
if (mMasterKeyIndex != UNSPECIFIED_KEY_INDEX) {
sb.append(", Index:").append(mMasterKeyIndex);
}
} else {
sb.append(" empty");
}
sb.append(">");
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanCredential)) {
return false;
}
LowpanCredential rhs = (LowpanCredential) obj;
return Arrays.equals(mMasterKey, rhs.mMasterKey) && mMasterKeyIndex == rhs.mMasterKeyIndex;
}
@Override
public int hashCode() {
return Objects.hash(Arrays.hashCode(mMasterKey), mMasterKeyIndex);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByteArray(mMasterKey);
dest.writeInt(mMasterKeyIndex);
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanCredential> CREATOR =
new Creator<LowpanCredential>() {
public LowpanCredential createFromParcel(Parcel in) {
LowpanCredential credential = new LowpanCredential();
credential.mMasterKey = in.createByteArray();
credential.mMasterKeyIndex = in.readInt();
return credential;
}
public LowpanCredential[] newArray(int size) {
return new LowpanCredential[size];
}
};
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.lowpan;
parcelable LowpanIdentity cpp_header "android/net/lowpan/LowpanIdentity.h";

View File

@@ -16,8 +16,16 @@
package android.net.lowpan;
import android.annotation.NonNull;
import android.icu.text.StringPrep;
import android.icu.text.StringPrepParseException;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import com.android.internal.util.HexDump;
import java.util.Map;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
/**
* Describes an instance of a LoWPAN network.
@@ -25,76 +33,100 @@ import java.util.Map;
* @hide
*/
// @SystemApi
public class LowpanIdentity {
public class LowpanIdentity implements Parcelable {
private static final String TAG = LowpanIdentity.class.getSimpleName();
// Constants
/** @hide */
public static final int TYPE_ZIGBEE = 1;
/** @hide */
public static final int TYPE_ZIGBEE_IP = 2;
/** @hide */
public static final int TYPE_THREAD = 3;
public static final int UNKNOWN = Integer.MAX_VALUE;
public static final int UNSPECIFIED_CHANNEL = -1;
public static final int UNSPECIFIED_PANID = 0xFFFFFFFF;
// Builder
/** @hide */
// @SystemApi
public static class Builder {
private final LowpanIdentity identity = new LowpanIdentity();
private static final StringPrep stringPrep =
StringPrep.getInstance(StringPrep.RFC3920_RESOURCEPREP);
final LowpanIdentity mIdentity = new LowpanIdentity();
private static String escape(@NonNull byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (byte b : bytes) {
if (b >= 32 && b <= 126) {
sb.append((char) b);
} else {
sb.append(String.format("\\0x%02x", b & 0xFF));
}
}
return sb.toString();
}
public Builder setLowpanIdentity(@NonNull LowpanIdentity x) {
Objects.requireNonNull(x);
setRawName(x.getRawName());
setXpanid(x.getXpanid());
setPanid(x.getPanid());
setChannel(x.getChannel());
setType(x.getType());
return this;
}
public Builder setName(@NonNull String name) {
Objects.requireNonNull(name);
try {
mIdentity.mName = stringPrep.prepare(name, StringPrep.DEFAULT);
mIdentity.mRawName = mIdentity.mName.getBytes(StandardCharsets.UTF_8);
mIdentity.mIsNameValid = true;
} catch (StringPrepParseException x) {
Log.w(TAG, x.toString());
setRawName(name.getBytes(StandardCharsets.UTF_8));
}
return this;
}
public Builder setRawName(@NonNull byte[] name) {
Objects.requireNonNull(name);
mIdentity.mRawName = name.clone();
mIdentity.mName = new String(name, StandardCharsets.UTF_8);
try {
String nameCheck = stringPrep.prepare(mIdentity.mName, StringPrep.DEFAULT);
mIdentity.mIsNameValid =
Arrays.equals(nameCheck.getBytes(StandardCharsets.UTF_8), name);
} catch (StringPrepParseException x) {
Log.w(TAG, x.toString());
mIdentity.mIsNameValid = false;
}
// Non-normal names must be rendered differently to avoid confusion.
if (!mIdentity.mIsNameValid) {
mIdentity.mName = "«" + escape(name) + "»";
}
public Builder setName(String x) {
identity.mName = x;
return this;
}
public Builder setXpanid(byte x[]) {
identity.mXpanid = (x != null ? x.clone() : null);
mIdentity.mXpanid = (x != null ? x.clone() : null);
return this;
}
public Builder setPanid(int x) {
identity.mPanid = x;
mIdentity.mPanid = x;
return this;
}
/** @hide */
public Builder setType(int x) {
identity.mType = x;
public Builder setType(@NonNull String x) {
mIdentity.mType = x;
return this;
}
public Builder setChannel(int x) {
identity.mChannel = x;
return this;
}
/** @hide */
Builder updateFromMap(Map map) {
if (map.containsKey(ILowpanInterface.KEY_NETWORK_NAME)) {
setName(LowpanProperties.KEY_NETWORK_NAME.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_NETWORK_PANID)) {
setPanid(LowpanProperties.KEY_NETWORK_PANID.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_NETWORK_XPANID)) {
setXpanid(LowpanProperties.KEY_NETWORK_XPANID.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_CHANNEL)) {
setChannel(LowpanProperties.KEY_CHANNEL.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_NETWORK_TYPE)) {
setType(LowpanProperties.KEY_NETWORK_TYPE.getFromMap(map));
}
mIdentity.mChannel = x;
return this;
}
public LowpanIdentity build() {
return identity;
return mIdentity;
}
}
@@ -102,28 +134,37 @@ public class LowpanIdentity {
// Instance Variables
private String mName = null;
private byte[] mXpanid = null;
private int mType = UNKNOWN;
private int mPanid = UNKNOWN;
private int mChannel = UNKNOWN;
private String mName = "";
private boolean mIsNameValid = true;
private byte[] mRawName = new byte[0];
private String mType = "";
private byte[] mXpanid = new byte[0];
private int mPanid = UNSPECIFIED_PANID;
private int mChannel = UNSPECIFIED_CHANNEL;
// Public Getters and Setters
// Public Getters
public String getName() {
return mName;
}
public boolean isNameValid() {
return mIsNameValid;
}
public byte[] getRawName() {
return mRawName.clone();
}
public byte[] getXpanid() {
return mXpanid != null ? mXpanid.clone() : null;
return mXpanid.clone();
}
public int getPanid() {
return mPanid;
}
/** @hide */
public int getType() {
public String getType() {
return mType;
}
@@ -131,43 +172,84 @@ public class LowpanIdentity {
return mChannel;
}
static void addToMap(Map<String, Object> parameters, LowpanIdentity networkInfo) {
if (networkInfo.getName() != null) {
LowpanProperties.KEY_NETWORK_NAME.putInMap(parameters, networkInfo.getName());
}
if (networkInfo.getPanid() != LowpanIdentity.UNKNOWN) {
LowpanProperties.KEY_NETWORK_PANID.putInMap(parameters, networkInfo.getPanid());
}
if (networkInfo.getChannel() != LowpanIdentity.UNKNOWN) {
LowpanProperties.KEY_CHANNEL.putInMap(parameters, networkInfo.getChannel());
}
if (networkInfo.getXpanid() != null) {
LowpanProperties.KEY_NETWORK_XPANID.putInMap(parameters, networkInfo.getXpanid());
}
}
void addToMap(Map<String, Object> parameters) {
addToMap(parameters, this);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Name: ").append(mName == null ? "<none>" : mName);
sb.append("Name:").append(getName());
if (mXpanid != null) {
sb.append(", XPANID: ").append(HexDump.toHexString(mXpanid));
if (mType.length() > 0) {
sb.append(", Type:").append(mType);
}
if (mPanid != UNKNOWN) {
sb.append(", PANID: ").append(String.format("0x%04X", mPanid));
if (mXpanid.length > 0) {
sb.append(", XPANID:").append(HexDump.toHexString(mXpanid));
}
if (mChannel != UNKNOWN) {
sb.append(", Channel: ").append(mChannel);
if (mPanid != UNSPECIFIED_PANID) {
sb.append(", PANID:").append(String.format("0x%04X", mPanid));
}
if (mChannel != UNSPECIFIED_CHANNEL) {
sb.append(", Channel:").append(mChannel);
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanIdentity)) {
return false;
}
LowpanIdentity rhs = (LowpanIdentity) obj;
return Arrays.equals(mRawName, rhs.mRawName)
&& Arrays.equals(mXpanid, rhs.mXpanid)
&& mType.equals(rhs.mType)
&& mPanid == rhs.mPanid
&& mChannel == rhs.mChannel;
}
@Override
public int hashCode() {
return Objects.hash(
Arrays.hashCode(mRawName), mType, Arrays.hashCode(mXpanid), mPanid, mChannel);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByteArray(mRawName);
dest.writeString(mType);
dest.writeByteArray(mXpanid);
dest.writeInt(mPanid);
dest.writeInt(mChannel);
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanIdentity> CREATOR =
new Creator<LowpanIdentity>() {
public LowpanIdentity createFromParcel(Parcel in) {
Builder builder = new Builder();
builder.setRawName(in.createByteArray());
builder.setType(in.readString());
builder.setXpanid(in.createByteArray());
builder.setPanid(in.readInt());
builder.setChannel(in.readInt());
return builder.build();
}
public LowpanIdentity[] newArray(int size) {
return new LowpanIdentity[size];
}
};
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.lowpan;
parcelable LowpanProvision cpp_header "android/net/lowpan/LowpanProvision.h";

View File

@@ -18,7 +18,9 @@ package android.net.lowpan;
import android.annotation.NonNull;
import android.annotation.Nullable;
import java.util.Map;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Describes the information needed to describe a network
@@ -26,7 +28,7 @@ import java.util.Map;
* @hide
*/
// @SystemApi
public class LowpanProvision {
public class LowpanProvision implements Parcelable {
// Builder
@@ -69,20 +71,6 @@ public class LowpanProvision {
return mCredential;
}
// LoWPAN-Internal Methods
static void addToMap(Map<String, Object> parameters, LowpanProvision provision)
throws LowpanException {
provision.mIdentity.addToMap(parameters);
if (provision.mCredential != null) {
provision.mCredential.addToMap(parameters);
}
}
void addToMap(Map<String, Object> parameters) throws LowpanException {
addToMap(parameters, this);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -90,11 +78,72 @@ public class LowpanProvision {
sb.append("LowpanProvision { identity => ").append(mIdentity.toString());
if (mCredential != null) {
sb.append(", credential: ").append(mCredential.toString());
sb.append(", credential => ").append(mCredential.toString());
}
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
return Objects.hash(mIdentity, mCredential);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanProvision)) {
return false;
}
LowpanProvision rhs = (LowpanProvision) obj;
if (!mIdentity.equals(rhs.mIdentity)) {
return false;
}
if (!Objects.equals(mCredential, rhs.mCredential)) {
return false;
}
return true;
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
mIdentity.writeToParcel(dest, flags);
if (mCredential == null) {
dest.writeBoolean(false);
} else {
dest.writeBoolean(true);
mCredential.writeToParcel(dest, flags);
}
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanProvision> CREATOR =
new Creator<LowpanProvision>() {
public LowpanProvision createFromParcel(Parcel in) {
Builder builder = new Builder();
builder.setLowpanIdentity(LowpanIdentity.CREATOR.createFromParcel(in));
if (in.readBoolean()) {
builder.setLowpanCredential(LowpanCredential.CREATOR.createFromParcel(in));
}
return builder.build();
}
public LowpanProvision[] newArray(int size) {
return new LowpanProvision[size];
}
};
};