Merge "Updates and fixes to android.net.lowpan"
This commit is contained in:
committed by
Android (Google) Code Review
commit
af6f67b91f
@@ -37,41 +37,79 @@ interface ILowpanInterface {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Property Key Constants
|
||||
|
||||
/** Type: Boolean */
|
||||
const String KEY_INTERFACE_ENABLED = "android.net.lowpan.property.INTERFACE_ENABLED";
|
||||
|
||||
/** Type: Boolean */
|
||||
const String KEY_INTERFACE_UP = "android.net.lowpan.property.INTERFACE_UP";
|
||||
|
||||
/** Type: Boolean */
|
||||
const String KEY_INTERFACE_COMMISSIONED = "android.net.lowpan.property.INTERFACE_COMMISSIONED";
|
||||
|
||||
/** Type: Boolean */
|
||||
const String KEY_INTERFACE_CONNECTED = "android.net.lowpan.property.INTERFACE_CONNECTED";
|
||||
|
||||
/** Type: String */
|
||||
const String KEY_INTERFACE_STATE = "android.net.lowpan.property.INTERFACE_STATE";
|
||||
|
||||
/** Type: String */
|
||||
const String KEY_NETWORK_NAME = "android.net.lowpan.property.NETWORK_NAME";
|
||||
|
||||
/** Type: Integer */
|
||||
const String KEY_NETWORK_TYPE = "android.net.lowpan.property.NETWORK_TYPE";
|
||||
|
||||
/** Type: Integer */
|
||||
const String KEY_NETWORK_PANID = "android.net.lowpan.property.NETWORK_PANID";
|
||||
|
||||
/** Type: byte[] */
|
||||
const String KEY_NETWORK_XPANID = "android.net.lowpan.property.NETWORK_XPANID";
|
||||
|
||||
/** Type: String */
|
||||
const String KEY_NETWORK_ROLE = "android.net.lowpan.property.NETWORK_ROLE";
|
||||
|
||||
/** Type: byte[] */
|
||||
const String KEY_NETWORK_MASTER_KEY = "android.net.lowpan.property.NETWORK_MASTER_KEY";
|
||||
|
||||
/** Type: Integer */
|
||||
const String KEY_NETWORK_MASTER_KEY_INDEX
|
||||
= "android.net.lowpan.property.NETWORK_MASTER_KEY_INDEX";
|
||||
|
||||
/** Type: int[] */
|
||||
const String KEY_SUPPORTED_CHANNELS = "android.net.lowpan.property.SUPPORTED_CHANNELS";
|
||||
|
||||
/** Type: Integer */
|
||||
const String KEY_CHANNEL = "android.net.lowpan.property.CHANNEL";
|
||||
|
||||
/** Type: int[] */
|
||||
const String KEY_CHANNEL_MASK = "android.net.lowpan.property.CHANNEL_MASK";
|
||||
|
||||
/** Type: Integer */
|
||||
const String KEY_MAX_TX_POWER = "android.net.lowpan.property.MAX_TX_POWER";
|
||||
|
||||
/** Type: Integer */
|
||||
const String KEY_RSSI = "android.net.lowpan.property.RSSI";
|
||||
|
||||
/** Type: Integer */
|
||||
const String KEY_LQI = "android.net.lowpan.property.LQI";
|
||||
|
||||
const String KEY_LINK_ADDRESS_ARRAY = "android.net.lowpan.property.LINK_ADDRESS_ARRAY";
|
||||
const String KEY_ROUTE_INFO_ARRAY = "android.net.lowpan.property.ROUTE_INFO_ARRAY";
|
||||
|
||||
/** Type: byte[] */
|
||||
const String KEY_BEACON_ADDRESS = "android.net.lowpan.property.BEACON_ORIGIN_ADDRESS";
|
||||
|
||||
/** Type: Boolean */
|
||||
const String KEY_BEACON_CAN_ASSIST = "android.net.lowpan.property.BEACON_CAN_ASSIST";
|
||||
|
||||
/** Type: String */
|
||||
const String DRIVER_VERSION = "android.net.lowpan.property.DRIVER_VERSION";
|
||||
|
||||
/** Type: String */
|
||||
const String NCP_VERSION = "android.net.lowpan.property.NCP_VERSION";
|
||||
|
||||
/** @hide */
|
||||
/** Type: byte[]
|
||||
* @hide */
|
||||
const String KEY_EXTENDED_ADDRESS = "android.net.lowpan.property.EXTENDED_ADDRESS";
|
||||
|
||||
/** @hide */
|
||||
/** Type: byte[]
|
||||
* @hide */
|
||||
const String KEY_MAC_ADDRESS = "android.net.lowpan.property.MAC_ADDRESS";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -144,6 +182,9 @@ interface ILowpanInterface {
|
||||
void startEnergyScan(in Map properties, ILowpanEnergyScanCallback listener);
|
||||
oneway void stopEnergyScan();
|
||||
|
||||
String[] copyLinkAddresses();
|
||||
IpPrefix[] copyLinkNetworks();
|
||||
|
||||
void addOnMeshPrefix(in IpPrefix prefix, int flags);
|
||||
oneway void removeOnMeshPrefix(in IpPrefix prefix);
|
||||
|
||||
|
||||
@@ -16,7 +16,15 @@
|
||||
|
||||
package android.net.lowpan;
|
||||
|
||||
import android.net.IpPrefix;
|
||||
|
||||
/** {@hide} */
|
||||
interface ILowpanInterfaceListener {
|
||||
oneway void onPropertiesChanged(in Map properties);
|
||||
|
||||
oneway void onLinkNetworkAdded(in IpPrefix prefix);
|
||||
oneway void onLinkNetworkRemoved(in IpPrefix prefix);
|
||||
|
||||
oneway void onLinkAddressAdded(in String address);
|
||||
oneway void onLinkAddressRemoved(in String address);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.net.lowpan.ILowpanManagerListener;
|
||||
/** {@hide} */
|
||||
interface ILowpanManager {
|
||||
|
||||
/* Keep this in sync with Context.LOWPAN_SERVICE */
|
||||
const String LOWPAN_SERVICE_NAME = "lowpan";
|
||||
|
||||
ILowpanInterface getInterface(@utf8InCpp String name);
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package android.net.lowpan;
|
||||
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.util.AndroidException;
|
||||
|
||||
@@ -49,92 +47,76 @@ public class LowpanException extends AndroidException {
|
||||
public static final int LOWPAN_JOIN_FAILED_AT_AUTH = 16;
|
||||
public static final int LOWPAN_FORM_FAILED_AT_SCAN = 17;
|
||||
|
||||
/**
|
||||
* Convert ServiceSpecificExceptions and Binder RemoteExceptions from LoWPAN binder interfaces
|
||||
* into the correct public exceptions.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static void throwAsPublicException(Throwable t) throws LowpanException {
|
||||
if (t instanceof ServiceSpecificException) {
|
||||
ServiceSpecificException e = (ServiceSpecificException) t;
|
||||
int reason;
|
||||
switch (e.errorCode) {
|
||||
case ILowpanInterface.ERROR_INVALID_ARGUMENT:
|
||||
case ILowpanInterface.ERROR_INVALID_TYPE:
|
||||
case ILowpanInterface.ERROR_INVALID_VALUE:
|
||||
throw new IllegalArgumentException(e.getMessage(), e);
|
||||
public static LowpanException rethrowAsLowpanException(ServiceSpecificException e)
|
||||
throws LowpanException {
|
||||
int reason;
|
||||
switch (e.errorCode) {
|
||||
case ILowpanInterface.ERROR_INVALID_ARGUMENT:
|
||||
case ILowpanInterface.ERROR_INVALID_TYPE:
|
||||
case ILowpanInterface.ERROR_INVALID_VALUE:
|
||||
throw new IllegalArgumentException(e.getMessage(), e);
|
||||
|
||||
case ILowpanInterface.ERROR_PERMISSION_DENIED:
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
case ILowpanInterface.ERROR_PERMISSION_DENIED:
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
|
||||
case ILowpanInterface.ERROR_DISABLED:
|
||||
reason = LowpanException.LOWPAN_DISABLED;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_DISABLED:
|
||||
reason = LowpanException.LOWPAN_DISABLED;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_WRONG_STATE:
|
||||
reason = LowpanException.LOWPAN_WRONG_STATE;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_WRONG_STATE:
|
||||
reason = LowpanException.LOWPAN_WRONG_STATE;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_BUSY:
|
||||
reason = LowpanException.LOWPAN_BUSY;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_BUSY:
|
||||
reason = LowpanException.LOWPAN_BUSY;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_ALREADY:
|
||||
reason = LowpanException.LOWPAN_ALREADY;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_ALREADY:
|
||||
reason = LowpanException.LOWPAN_ALREADY;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_CANCELED:
|
||||
reason = LowpanException.LOWPAN_CANCELED;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_CANCELED:
|
||||
reason = LowpanException.LOWPAN_CANCELED;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_CREDENTIAL_NEEDED:
|
||||
reason = LowpanException.LOWPAN_CREDENTIAL_NEEDED;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_CREDENTIAL_NEEDED:
|
||||
reason = LowpanException.LOWPAN_CREDENTIAL_NEEDED;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_FEATURE_NOT_SUPPORTED:
|
||||
reason = LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_FEATURE_NOT_SUPPORTED:
|
||||
reason = LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_PROPERTY_NOT_FOUND:
|
||||
reason = LowpanException.LOWPAN_PROPERTY_NOT_FOUND;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_PROPERTY_NOT_FOUND:
|
||||
reason = LowpanException.LOWPAN_PROPERTY_NOT_FOUND;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_JOIN_FAILED_UNKNOWN:
|
||||
reason = LowpanException.LOWPAN_JOIN_FAILED_UNKNOWN;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_JOIN_FAILED_UNKNOWN:
|
||||
reason = LowpanException.LOWPAN_JOIN_FAILED_UNKNOWN;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_JOIN_FAILED_AT_SCAN:
|
||||
reason = LowpanException.LOWPAN_JOIN_FAILED_AT_SCAN;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_JOIN_FAILED_AT_SCAN:
|
||||
reason = LowpanException.LOWPAN_JOIN_FAILED_AT_SCAN;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_JOIN_FAILED_AT_AUTH:
|
||||
reason = LowpanException.LOWPAN_JOIN_FAILED_AT_AUTH;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_JOIN_FAILED_AT_AUTH:
|
||||
reason = LowpanException.LOWPAN_JOIN_FAILED_AT_AUTH;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_FORM_FAILED_AT_SCAN:
|
||||
reason = LowpanException.LOWPAN_FORM_FAILED_AT_SCAN;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_FORM_FAILED_AT_SCAN:
|
||||
reason = LowpanException.LOWPAN_FORM_FAILED_AT_SCAN;
|
||||
break;
|
||||
|
||||
case ILowpanInterface.ERROR_TIMEOUT:
|
||||
case ILowpanInterface.ERROR_NCP_PROBLEM:
|
||||
reason = LowpanException.LOWPAN_NCP_PROBLEM;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_UNSPECIFIED:
|
||||
default:
|
||||
reason = LOWPAN_ERROR;
|
||||
break;
|
||||
}
|
||||
throw new LowpanException(reason, e.getMessage(), e);
|
||||
} else if (t instanceof DeadObjectException) {
|
||||
throw new LowpanException(LOWPAN_DEAD, t);
|
||||
} else if (t instanceof RemoteException) {
|
||||
throw new UnsupportedOperationException(
|
||||
"An unknown RemoteException was thrown" + " which should never happen.", t);
|
||||
} else if (t instanceof RuntimeException) {
|
||||
RuntimeException e = (RuntimeException) t;
|
||||
throw e;
|
||||
case ILowpanInterface.ERROR_TIMEOUT:
|
||||
case ILowpanInterface.ERROR_NCP_PROBLEM:
|
||||
reason = LowpanException.LOWPAN_NCP_PROBLEM;
|
||||
break;
|
||||
case ILowpanInterface.ERROR_UNSPECIFIED:
|
||||
default:
|
||||
reason = LOWPAN_ERROR;
|
||||
break;
|
||||
}
|
||||
throw new LowpanException(reason, e.getMessage(), e);
|
||||
}
|
||||
|
||||
private final int mReason;
|
||||
|
||||
@@ -53,7 +53,7 @@ public class LowpanIdentity {
|
||||
}
|
||||
|
||||
public Builder setXpanid(byte x[]) {
|
||||
identity.mXpanid = x.clone();
|
||||
identity.mXpanid = (x != null ? x.clone() : null);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ public class LowpanIdentity {
|
||||
}
|
||||
|
||||
public byte[] getXpanid() {
|
||||
return mXpanid.clone();
|
||||
return mXpanid != null ? mXpanid.clone() : null;
|
||||
}
|
||||
|
||||
public int getPanid() {
|
||||
|
||||
@@ -18,9 +18,12 @@ package android.net.lowpan;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.net.IpPrefix;
|
||||
import android.net.LinkAddress;
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.util.Log;
|
||||
@@ -188,60 +191,35 @@ public class LowpanInterface {
|
||||
public void onPropertiesChanged(@NonNull Map properties) {}
|
||||
}
|
||||
|
||||
private ILowpanInterface mBinder;
|
||||
private final ILowpanInterface mBinder;
|
||||
private final Looper mLooper;
|
||||
private final HashMap<Integer, ILowpanInterfaceListener> mListenerMap = new HashMap<>();
|
||||
|
||||
/** Map between IBinder identity hashes and LowpanInstance objects. */
|
||||
private static final HashMap<Integer, LowpanInterface> sInstanceMap = new HashMap<>();
|
||||
/**
|
||||
* Create a new LowpanInterface instance. Applications will almost always want to use {@link
|
||||
* LowpanManager#getInterface LowpanManager.getInterface()} instead of this.
|
||||
*
|
||||
* @param context the application context
|
||||
* @param service the Binder interface
|
||||
* @param looper the Binder interface
|
||||
* @hide
|
||||
*/
|
||||
public LowpanInterface(Context context, ILowpanInterface service, Looper looper) {
|
||||
/* We aren't currently using the context, but if we need
|
||||
* it later on we can easily add it to the class.
|
||||
*/
|
||||
|
||||
private LowpanInterface(IBinder binder) {
|
||||
mBinder = ILowpanInterface.Stub.asInterface(binder);
|
||||
mBinder = service;
|
||||
mLooper = looper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the LowpanInterface object associated with this IBinder. Returns null if this IBinder
|
||||
* does not implement the appropriate interface.
|
||||
* Returns the ILowpanInterface object associated with this interface.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public static final LowpanInterface from(IBinder binder) {
|
||||
Integer hashCode = Integer.valueOf(System.identityHashCode(binder));
|
||||
LowpanInterface instance;
|
||||
|
||||
synchronized (sInstanceMap) {
|
||||
instance = sInstanceMap.get(hashCode);
|
||||
|
||||
if (instance == null) {
|
||||
instance = new LowpanInterface(binder);
|
||||
sInstanceMap.put(hashCode, instance);
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public static final LowpanInterface from(ILowpanInterface iface) {
|
||||
return from(iface.asBinder());
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public static final LowpanInterface getInterfaceFromBinder(IBinder binder) {
|
||||
return from(binder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IBinder object associated with this interface.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public IBinder getBinder() {
|
||||
return mBinder.asBinder();
|
||||
}
|
||||
|
||||
private static void throwAsPublicException(Throwable t) throws LowpanException {
|
||||
LowpanException.throwAsPublicException(t);
|
||||
public ILowpanInterface getService() {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
// Private Property Helpers
|
||||
@@ -251,11 +229,10 @@ public class LowpanInterface {
|
||||
mBinder.setProperties(properties);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,13 +240,13 @@ public class LowpanInterface {
|
||||
Map<String, Object> getProperties(String keys[]) throws LowpanException {
|
||||
try {
|
||||
return mBinder.getProperties(keys);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
return new HashMap();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -294,13 +271,13 @@ public class LowpanInterface {
|
||||
<T> String getPropertyAsString(LowpanProperty<T> key) throws LowpanException {
|
||||
try {
|
||||
return mBinder.getPropertyAsString(key.getName());
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int getPropertyAsInt(LowpanProperty<Integer> key) throws LowpanException {
|
||||
@@ -332,10 +309,12 @@ public class LowpanInterface {
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
provision.addToMap(parameters);
|
||||
mBinder.form(parameters);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throwAsPublicException(x);
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,10 +331,12 @@ public class LowpanInterface {
|
||||
Map<String, Object> parameters = new HashMap();
|
||||
provision.addToMap(parameters);
|
||||
mBinder.join(parameters);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throwAsPublicException(x);
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,10 +367,12 @@ public class LowpanInterface {
|
||||
public void leave() throws LowpanException {
|
||||
try {
|
||||
mBinder.leave();
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throwAsPublicException(x);
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,34 +398,26 @@ public class LowpanInterface {
|
||||
public void reset() throws LowpanException {
|
||||
try {
|
||||
mBinder.reset();
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throwAsPublicException(x);
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
// Public Getters and Setters
|
||||
|
||||
/**
|
||||
* Returns the name of this network interface.
|
||||
*
|
||||
* <p>Will return empty string if this interface is no longer viable.
|
||||
*/
|
||||
/** Returns the name of this network interface. */
|
||||
@NonNull
|
||||
public String getName() {
|
||||
try {
|
||||
return mBinder.getName();
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
// when fetching the name.
|
||||
Log.e(TAG, x.toString());
|
||||
} catch (ServiceSpecificException x) {
|
||||
// Catch and ignore all service-specific exceptions
|
||||
// when fetching the name.
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -640,58 +615,77 @@ public class LowpanInterface {
|
||||
public void registerCallback(@NonNull Callback cb, @Nullable Handler handler) {
|
||||
ILowpanInterfaceListener.Stub listenerBinder =
|
||||
new ILowpanInterfaceListener.Stub() {
|
||||
public void onPropertiesChanged(Map properties) {
|
||||
private Handler mHandler;
|
||||
|
||||
{
|
||||
if (handler != null) {
|
||||
mHandler = handler;
|
||||
} else if (mLooper != null) {
|
||||
mHandler = new Handler(mLooper);
|
||||
} else {
|
||||
mHandler = new Handler();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onPropertiesChanged(Map properties) {
|
||||
Runnable runnable =
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (String key : (Set<String>) properties.keySet()) {
|
||||
Object value = properties.get(key);
|
||||
switch (key) {
|
||||
case ILowpanInterface.KEY_INTERFACE_ENABLED:
|
||||
cb.onEnabledChanged(
|
||||
((Boolean) value).booleanValue());
|
||||
break;
|
||||
case ILowpanInterface.KEY_INTERFACE_UP:
|
||||
cb.onUpChanged(
|
||||
((Boolean) value).booleanValue());
|
||||
break;
|
||||
case ILowpanInterface.KEY_INTERFACE_CONNECTED:
|
||||
cb.onConnectedChanged(
|
||||
((Boolean) value).booleanValue());
|
||||
break;
|
||||
case ILowpanInterface.KEY_INTERFACE_STATE:
|
||||
cb.onStateChanged((String) value);
|
||||
break;
|
||||
case ILowpanInterface.KEY_NETWORK_NAME:
|
||||
case ILowpanInterface.KEY_NETWORK_PANID:
|
||||
case ILowpanInterface.KEY_NETWORK_XPANID:
|
||||
case ILowpanInterface.KEY_CHANNEL:
|
||||
cb.onLowpanIdentityChanged(getLowpanIdentity());
|
||||
break;
|
||||
case ILowpanInterface.KEY_NETWORK_ROLE:
|
||||
cb.onRoleChanged(value.toString());
|
||||
break;
|
||||
}
|
||||
() -> {
|
||||
for (String key : (Set<String>) properties.keySet()) {
|
||||
Object value = properties.get(key);
|
||||
switch (key) {
|
||||
case ILowpanInterface.KEY_INTERFACE_ENABLED:
|
||||
cb.onEnabledChanged(
|
||||
((Boolean) value).booleanValue());
|
||||
break;
|
||||
case ILowpanInterface.KEY_INTERFACE_UP:
|
||||
cb.onUpChanged(((Boolean) value).booleanValue());
|
||||
break;
|
||||
case ILowpanInterface.KEY_INTERFACE_CONNECTED:
|
||||
cb.onConnectedChanged(
|
||||
((Boolean) value).booleanValue());
|
||||
break;
|
||||
case ILowpanInterface.KEY_INTERFACE_STATE:
|
||||
cb.onStateChanged((String) value);
|
||||
break;
|
||||
case ILowpanInterface.KEY_NETWORK_NAME:
|
||||
case ILowpanInterface.KEY_NETWORK_PANID:
|
||||
case ILowpanInterface.KEY_NETWORK_XPANID:
|
||||
case ILowpanInterface.KEY_CHANNEL:
|
||||
cb.onLowpanIdentityChanged(getLowpanIdentity());
|
||||
break;
|
||||
case ILowpanInterface.KEY_NETWORK_ROLE:
|
||||
cb.onRoleChanged(value.toString());
|
||||
break;
|
||||
}
|
||||
cb.onPropertiesChanged(properties);
|
||||
}
|
||||
cb.onPropertiesChanged(properties);
|
||||
};
|
||||
|
||||
if (handler != null) {
|
||||
handler.post(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
mHandler.post(runnable);
|
||||
}
|
||||
|
||||
@Override public void onLinkNetworkAdded(IpPrefix prefix) {
|
||||
// Support for this event isn't yet implemented.
|
||||
}
|
||||
|
||||
@Override public void onLinkNetworkRemoved(IpPrefix prefix) {
|
||||
// Support for this event isn't yet implemented.
|
||||
}
|
||||
|
||||
@Override public void onLinkAddressAdded(String address) {
|
||||
// Support for this event isn't yet implemented.
|
||||
}
|
||||
|
||||
@Override public void onLinkAddressRemoved(String address) {
|
||||
// Support for this event isn't yet implemented.
|
||||
}
|
||||
};
|
||||
try {
|
||||
mBinder.addListener(listenerBinder);
|
||||
} catch (RemoteException x) {
|
||||
// Log and ignore. If this happens, this interface
|
||||
// is likely dead anyway.
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
}
|
||||
|
||||
synchronized (mListenerMap) {
|
||||
mListenerMap.put(System.identityHashCode(cb), listenerBinder);
|
||||
}
|
||||
@@ -728,9 +722,11 @@ public class LowpanInterface {
|
||||
|
||||
try {
|
||||
mBinder.removeListener(listenerBinder);
|
||||
} catch (DeadObjectException x) {
|
||||
// We ignore a dead object exception because that
|
||||
// pretty clearly means our callback isn't registered.
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -751,6 +747,46 @@ public class LowpanInterface {
|
||||
|
||||
// Route Management
|
||||
|
||||
/**
|
||||
* Makes a copy of the internal list of LinkAddresses.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress[] copyLinkAddresses() throws LowpanException {
|
||||
try {
|
||||
String[] linkAddressStrings = mBinder.copyLinkAddresses();
|
||||
LinkAddress[] ret = new LinkAddress[linkAddressStrings.length];
|
||||
int i = 0;
|
||||
for (String str : linkAddressStrings) {
|
||||
ret[i++] = new LinkAddress(str);
|
||||
}
|
||||
return ret;
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of the internal list of networks reachable on via this link.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public IpPrefix[] copyLinkNetworks() throws LowpanException {
|
||||
try {
|
||||
return mBinder.copyLinkNetworks();
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Advertise the given IP prefix as an on-mesh prefix.
|
||||
*
|
||||
@@ -759,10 +795,12 @@ public class LowpanInterface {
|
||||
public void addOnMeshPrefix(IpPrefix prefix, int flags) throws LowpanException {
|
||||
try {
|
||||
mBinder.addOnMeshPrefix(prefix, flags);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throwAsPublicException(x);
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,9 +813,10 @@ public class LowpanInterface {
|
||||
public void removeOnMeshPrefix(IpPrefix prefix) {
|
||||
try {
|
||||
mBinder.removeOnMeshPrefix(prefix);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
// Catch and ignore all service exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
@@ -793,10 +832,12 @@ public class LowpanInterface {
|
||||
public void addExternalRoute(IpPrefix prefix, int flags) throws LowpanException {
|
||||
try {
|
||||
mBinder.addExternalRoute(prefix, flags);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throwAsPublicException(x);
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -808,9 +849,10 @@ public class LowpanInterface {
|
||||
public void removeExternalRoute(IpPrefix prefix) {
|
||||
try {
|
||||
mBinder.removeExternalRoute(prefix);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
// Catch and ignore all service exceptions
|
||||
Log.e(TAG, x.toString());
|
||||
|
||||
@@ -19,14 +19,15 @@ package android.net.lowpan;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.AndroidException;
|
||||
import android.util.Log;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Manager object for looking up LoWPAN interfaces.
|
||||
@@ -45,72 +46,119 @@ public class LowpanManager {
|
||||
public void onInterfaceRemoved(LowpanInterface lowpanInterface) {}
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private ILowpanManager mManager;
|
||||
private HashMap<Integer, ILowpanManagerListener> mListenerMap = new HashMap<>();
|
||||
private final Map<Integer, ILowpanManagerListener> mListenerMap = new HashMap<>();
|
||||
private final Map<String, LowpanInterface> mInterfaceCache = new HashMap<>();
|
||||
|
||||
private static LowpanManager sSingletonInstance;
|
||||
/* This is a WeakHashMap because we don't want to hold onto
|
||||
* a strong reference to ILowpanInterface, so that it can be
|
||||
* garbage collected if it isn't being used anymore. Since
|
||||
* the value class holds onto this specific ILowpanInterface,
|
||||
* we also need to have a weak reference to the value.
|
||||
* This design pattern allows us to skip removal of items
|
||||
* from this Map without leaking memory.
|
||||
*/
|
||||
private final Map<ILowpanInterface, WeakReference<LowpanInterface>> mBinderCache =
|
||||
new WeakHashMap<>();
|
||||
|
||||
private final ILowpanManager mService;
|
||||
private final Context mContext;
|
||||
private final Looper mLooper;
|
||||
|
||||
// Static Methods
|
||||
|
||||
/** Returns a reference to the LowpanManager object, allocating it if necessary. */
|
||||
public static LowpanManager getManager() {
|
||||
return from(null);
|
||||
public static LowpanManager from(Context context) {
|
||||
return (LowpanManager) context.getSystemService(Context.LOWPAN_SERVICE);
|
||||
}
|
||||
|
||||
public static LowpanManager from(Context context) {
|
||||
// TODO: Actually get this from the context!
|
||||
/** @hide */
|
||||
public static LowpanManager getManager() {
|
||||
IBinder binder = ServiceManager.getService(Context.LOWPAN_SERVICE);
|
||||
|
||||
if (sSingletonInstance == null) {
|
||||
sSingletonInstance = new LowpanManager();
|
||||
if (binder != null) {
|
||||
ILowpanManager service = ILowpanManager.Stub.asInterface(binder);
|
||||
return new LowpanManager(service);
|
||||
}
|
||||
return sSingletonInstance;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Constructors
|
||||
|
||||
/**
|
||||
* Private LowpanManager constructor. Since we are a singleton, we do not allow external
|
||||
* construction.
|
||||
*/
|
||||
private LowpanManager() {}
|
||||
|
||||
// Private Methods
|
||||
|
||||
/**
|
||||
* Returns a reference to the ILowpanManager interface, provided by the LoWPAN Manager Service.
|
||||
*/
|
||||
@Nullable
|
||||
private synchronized ILowpanManager getILowpanManager() {
|
||||
// Use a local reference of this object for thread safety.
|
||||
ILowpanManager manager = mManager;
|
||||
|
||||
if (manager == null) {
|
||||
IBinder serviceBinder =
|
||||
new ServiceManager().getService(ILowpanManager.LOWPAN_SERVICE_NAME);
|
||||
|
||||
manager = ILowpanManager.Stub.asInterface(serviceBinder);
|
||||
|
||||
mManager = manager;
|
||||
|
||||
// Add any listeners
|
||||
synchronized (mListenerMap) {
|
||||
for (ILowpanManagerListener listener : mListenerMap.values()) {
|
||||
try {
|
||||
manager.addListener(listener);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Consider any failure here as implying the manager is defunct
|
||||
mManager = null;
|
||||
manager = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return manager;
|
||||
LowpanManager(ILowpanManager service) {
|
||||
mService = service;
|
||||
mContext = null;
|
||||
mLooper = null;
|
||||
}
|
||||
|
||||
// Public Methods
|
||||
/**
|
||||
* Create a new LowpanManager instance. Applications will almost always want to use {@link
|
||||
* android.content.Context#getSystemService Context.getSystemService()} to retrieve the standard
|
||||
* {@link android.content.Context#LOWPAN_SERVICE Context.LOWPAN_SERVICE}.
|
||||
*
|
||||
* @param context the application context
|
||||
* @param service the Binder interface
|
||||
* @param looper the default Looper to run callbacks on
|
||||
* @hide - hide this because it takes in a parameter of type ILowpanManager, which is a system
|
||||
* private class.
|
||||
*/
|
||||
public LowpanManager(Context context, ILowpanManager service, Looper looper) {
|
||||
mContext = context;
|
||||
mService = service;
|
||||
mLooper = looper;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Nullable
|
||||
public LowpanInterface getInterface(@NonNull ILowpanInterface ifaceService) {
|
||||
LowpanInterface iface = null;
|
||||
|
||||
try {
|
||||
synchronized (mBinderCache) {
|
||||
if (mBinderCache.containsKey(ifaceService)) {
|
||||
iface = mBinderCache.get(ifaceService).get();
|
||||
}
|
||||
|
||||
if (iface == null) {
|
||||
String ifaceName = ifaceService.getName();
|
||||
|
||||
iface = new LowpanInterface(mContext, ifaceService, mLooper);
|
||||
|
||||
synchronized (mInterfaceCache) {
|
||||
mInterfaceCache.put(iface.getName(), iface);
|
||||
}
|
||||
|
||||
mBinderCache.put(ifaceService, new WeakReference(iface));
|
||||
|
||||
/* Make sure we remove the object from the
|
||||
* interface cache if the associated service
|
||||
* dies.
|
||||
*/
|
||||
ifaceService
|
||||
.asBinder()
|
||||
.linkToDeath(
|
||||
new IBinder.DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
synchronized (mInterfaceCache) {
|
||||
LowpanInterface iface =
|
||||
mInterfaceCache.get(ifaceName);
|
||||
|
||||
if ((iface != null)
|
||||
&& (iface.getService() == ifaceService)) {
|
||||
mInterfaceCache.remove(ifaceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
0);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowAsRuntimeException();
|
||||
}
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the requested LowpanInterface object. If the given interface doesn't
|
||||
@@ -118,27 +166,32 @@ public class LowpanManager {
|
||||
*/
|
||||
@Nullable
|
||||
public LowpanInterface getInterface(@NonNull String name) {
|
||||
LowpanInterface ret = null;
|
||||
ILowpanManager manager = getILowpanManager();
|
||||
LowpanInterface iface = null;
|
||||
|
||||
// Maximum number of tries is two. We should only try
|
||||
// more than once if our manager has died or there
|
||||
// was some sort of AIDL buffer full event.
|
||||
for (int i = 0; i < 2 && manager != null; i++) {
|
||||
try {
|
||||
ILowpanInterface iface = manager.getInterface(name);
|
||||
if (iface != null) {
|
||||
ret = LowpanInterface.getInterfaceFromBinder(iface.asBinder());
|
||||
try {
|
||||
/* This synchronized block covers both branches of the enclosed
|
||||
* if() statement in order to avoid a race condition. Two threads
|
||||
* calling getInterface() with the same name would race to create
|
||||
* the associated LowpanInterface object, creating two of them.
|
||||
* Having the whole block be synchronized avoids that race.
|
||||
*/
|
||||
synchronized (mInterfaceCache) {
|
||||
if (mInterfaceCache.containsKey(name)) {
|
||||
iface = mInterfaceCache.get(name);
|
||||
|
||||
} else {
|
||||
ILowpanInterface ifaceService = mService.getInterface(name);
|
||||
|
||||
if (ifaceService != null) {
|
||||
iface = getInterface(ifaceService);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} catch (RemoteException x) {
|
||||
// In all of the cases when we get this exception, we reconnect and try again
|
||||
mManager = null;
|
||||
manager = getILowpanManager();
|
||||
}
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
return ret;
|
||||
return iface;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,23 +213,11 @@ public class LowpanManager {
|
||||
*/
|
||||
@NonNull
|
||||
public String[] getInterfaceList() {
|
||||
ILowpanManager manager = getILowpanManager();
|
||||
|
||||
// Maximum number of tries is two. We should only try
|
||||
// more than once if our manager has died or there
|
||||
// was some sort of AIDL buffer full event.
|
||||
for (int i = 0; i < 2 && manager != null; i++) {
|
||||
try {
|
||||
return manager.getInterfaceList();
|
||||
} catch (RemoteException x) {
|
||||
// In all of the cases when we get this exception, we reconnect and try again
|
||||
mManager = null;
|
||||
manager = getILowpanManager();
|
||||
}
|
||||
try {
|
||||
return mService.getInterfaceList();
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
// Return empty list if we have no service.
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,55 +230,52 @@ public class LowpanManager {
|
||||
throws LowpanException {
|
||||
ILowpanManagerListener.Stub listenerBinder =
|
||||
new ILowpanManagerListener.Stub() {
|
||||
public void onInterfaceAdded(ILowpanInterface lowpanInterface) {
|
||||
Runnable runnable =
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cb.onInterfaceAdded(
|
||||
LowpanInterface.getInterfaceFromBinder(
|
||||
lowpanInterface.asBinder()));
|
||||
}
|
||||
};
|
||||
private Handler mHandler;
|
||||
|
||||
{
|
||||
if (handler != null) {
|
||||
handler.post(runnable);
|
||||
mHandler = handler;
|
||||
} else if (mLooper != null) {
|
||||
mHandler = new Handler(mLooper);
|
||||
} else {
|
||||
runnable.run();
|
||||
mHandler = new Handler();
|
||||
}
|
||||
}
|
||||
|
||||
public void onInterfaceRemoved(ILowpanInterface lowpanInterface) {
|
||||
@Override
|
||||
public void onInterfaceAdded(ILowpanInterface ifaceService) {
|
||||
Runnable runnable =
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cb.onInterfaceRemoved(
|
||||
LowpanInterface.getInterfaceFromBinder(
|
||||
lowpanInterface.asBinder()));
|
||||
() -> {
|
||||
LowpanInterface iface = getInterface(ifaceService);
|
||||
|
||||
if (iface != null) {
|
||||
cb.onInterfaceAdded(iface);
|
||||
}
|
||||
};
|
||||
|
||||
if (handler != null) {
|
||||
handler.post(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
mHandler.post(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterfaceRemoved(ILowpanInterface ifaceService) {
|
||||
Runnable runnable =
|
||||
() -> {
|
||||
LowpanInterface iface = getInterface(ifaceService);
|
||||
|
||||
if (iface != null) {
|
||||
cb.onInterfaceRemoved(iface);
|
||||
}
|
||||
};
|
||||
|
||||
mHandler.post(runnable);
|
||||
}
|
||||
};
|
||||
ILowpanManager manager = getILowpanManager();
|
||||
if (manager != null) {
|
||||
try {
|
||||
manager.addListener(listenerBinder);
|
||||
} catch (DeadObjectException x) {
|
||||
mManager = null;
|
||||
// Tickle the ILowpanManager instance, which might
|
||||
// get us added back.
|
||||
getILowpanManager();
|
||||
} catch (Throwable x) {
|
||||
LowpanException.throwAsPublicException(x);
|
||||
}
|
||||
try {
|
||||
mService.addListener(listenerBinder);
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
synchronized (mListenerMap) {
|
||||
mListenerMap.put(Integer.valueOf(System.identityHashCode(cb)), listenerBinder);
|
||||
}
|
||||
@@ -253,20 +291,23 @@ public class LowpanManager {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void unregisterCallback(@NonNull Callback cb) throws AndroidException {
|
||||
public void unregisterCallback(@NonNull Callback cb) {
|
||||
Integer hashCode = Integer.valueOf(System.identityHashCode(cb));
|
||||
ILowpanManagerListener listenerBinder = mListenerMap.get(hashCode);
|
||||
ILowpanManagerListener listenerBinder = null;
|
||||
|
||||
synchronized (mListenerMap) {
|
||||
listenerBinder = mListenerMap.get(hashCode);
|
||||
mListenerMap.remove(hashCode);
|
||||
}
|
||||
|
||||
if (listenerBinder != null) {
|
||||
synchronized (mListenerMap) {
|
||||
mListenerMap.remove(hashCode);
|
||||
}
|
||||
if (getILowpanManager() != null) {
|
||||
try {
|
||||
mManager.removeListener(listenerBinder);
|
||||
} catch (DeadObjectException x) {
|
||||
mManager = null;
|
||||
}
|
||||
try {
|
||||
mService.removeListener(listenerBinder);
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowFromSystemServer();
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Attempt to unregister an unknown callback");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package android.net.lowpan;
|
||||
|
||||
import android.net.IpPrefix;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.RouteInfo;
|
||||
import java.util.List;
|
||||
|
||||
/** {@hide} */
|
||||
public final class LowpanProperties {
|
||||
@@ -77,14 +76,6 @@ public final class LowpanProperties {
|
||||
public static final LowpanProperty<String> KEY_NCP_VERSION =
|
||||
new LowpanStandardProperty("android.net.lowpan.property.NCP_VERSION", String.class);
|
||||
|
||||
public static final LowpanProperty<List<LinkAddress>> KEY_LINK_ADDRESS_ARRAY =
|
||||
new LowpanStandardProperty(
|
||||
"android.net.lowpan.property.LINK_ADDRESS_ARRAY", LinkAddress[].class);
|
||||
|
||||
public static final LowpanProperty<List<RouteInfo>> KEY_ROUTE_INFO_ARRAY =
|
||||
new LowpanStandardProperty(
|
||||
"android.net.lowpan.property.ROUTE_INFO_ARRAY", RouteInfo[].class);
|
||||
|
||||
/** @hide */
|
||||
public static final LowpanProperty<byte[]> KEY_EXTENDED_ADDRESS =
|
||||
new LowpanStandardProperty(
|
||||
|
||||
@@ -226,8 +226,12 @@ public class LowpanScanner {
|
||||
|
||||
try {
|
||||
mBinder.startNetScan(map, binderListener);
|
||||
} catch (ServiceSpecificException | RemoteException x) {
|
||||
LowpanException.throwAsPublicException(x);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,8 +243,11 @@ public class LowpanScanner {
|
||||
public void stopNetScan() {
|
||||
try {
|
||||
mBinder.stopNetScan();
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
Log.e(TAG, x.toString());
|
||||
}
|
||||
}
|
||||
@@ -303,10 +310,12 @@ public class LowpanScanner {
|
||||
|
||||
try {
|
||||
mBinder.startEnergyScan(map, binderListener);
|
||||
|
||||
} catch (RemoteException x) {
|
||||
LowpanException.throwAsPublicException(x);
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
LowpanException.throwAsPublicException(x);
|
||||
throw LowpanException.rethrowAsLowpanException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,8 +327,11 @@ public class LowpanScanner {
|
||||
public void stopEnergyScan() {
|
||||
try {
|
||||
mBinder.stopEnergyScan();
|
||||
|
||||
} catch (RemoteException x) {
|
||||
// Catch and ignore all binder exceptions
|
||||
throw x.rethrowAsRuntimeException();
|
||||
|
||||
} catch (ServiceSpecificException x) {
|
||||
Log.e(TAG, x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user