Skip to content
Snippets Groups Projects
Commit 0797d9d5 authored by Yang Sun's avatar Yang Sun
Browse files

Add setEnabled API

setEnabled API is added to ThreadNetworkController, this
can be used by applications with privileged permission to set
Thread to enable/disabled state.

The Thread enabled state can be subscribed with
ThreadNetworkController#registerStateCallback.

When Thread is disabled, the join/scheduleMigration APIs will
fail with ERROR_THREAD_DISABLED.

When Thread is disabling, all commands will fail with ERROR_BUSY.

Bug: 299243765

Test: atest CtsThreadNetworkTestCases:android.net.thread.cts.ThreadNetworkControllerTest

Change-Id: Ifa7845bf1d5664ecd31ce74e24b3a839f92bba13
parent 86939424
No related branches found
No related tags found
No related merge requests found
......@@ -500,6 +500,7 @@ package android.net.thread {
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_NETWORK_STATE, "android.permission.THREAD_NETWORK_PRIVILEGED"}) public void registerOperationalDatasetCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.thread.ThreadNetworkController.OperationalDatasetCallback);
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.thread.ThreadNetworkController.StateCallback);
method @RequiresPermission("android.permission.THREAD_NETWORK_PRIVILEGED") public void scheduleMigration(@NonNull android.net.thread.PendingOperationalDataset, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.net.thread.ThreadNetworkException>);
method @RequiresPermission("android.permission.THREAD_NETWORK_PRIVILEGED") public void setEnabled(boolean, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.net.thread.ThreadNetworkException>);
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_NETWORK_STATE, "android.permission.THREAD_NETWORK_PRIVILEGED"}) public void unregisterOperationalDatasetCallback(@NonNull android.net.thread.ThreadNetworkController.OperationalDatasetCallback);
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void unregisterStateCallback(@NonNull android.net.thread.ThreadNetworkController.StateCallback);
field public static final int DEVICE_ROLE_CHILD = 2; // 0x2
......@@ -507,6 +508,9 @@ package android.net.thread {
field public static final int DEVICE_ROLE_LEADER = 4; // 0x4
field public static final int DEVICE_ROLE_ROUTER = 3; // 0x3
field public static final int DEVICE_ROLE_STOPPED = 0; // 0x0
field public static final int STATE_DISABLED = 0; // 0x0
field public static final int STATE_DISABLING = 2; // 0x2
field public static final int STATE_ENABLED = 1; // 0x1
field public static final int THREAD_VERSION_1_3 = 4; // 0x4
}
......@@ -518,6 +522,7 @@ package android.net.thread {
public static interface ThreadNetworkController.StateCallback {
method public void onDeviceRoleChanged(int);
method public default void onPartitionIdChanged(long);
method public default void onThreadEnableStateChanged(int);
}
@FlaggedApi("com.android.net.thread.flags.thread_enabled") public class ThreadNetworkException extends java.lang.Exception {
......@@ -530,6 +535,7 @@ package android.net.thread {
field public static final int ERROR_REJECTED_BY_PEER = 8; // 0x8
field public static final int ERROR_RESOURCE_EXHAUSTED = 10; // 0xa
field public static final int ERROR_RESPONSE_BAD_FORMAT = 9; // 0x9
field public static final int ERROR_THREAD_DISABLED = 12; // 0xc
field public static final int ERROR_TIMEOUT = 3; // 0x3
field public static final int ERROR_UNAVAILABLE = 4; // 0x4
field public static final int ERROR_UNKNOWN = 11; // 0xb
......
......@@ -22,4 +22,5 @@ package android.net.thread;
oneway interface IStateCallback {
void onDeviceRoleChanged(int deviceRole);
void onPartitionIdChanged(long partitionId);
void onThreadEnableStateChanged(int enabledState);
}
......@@ -42,4 +42,6 @@ interface IThreadNetworkController {
int getThreadVersion();
void createRandomizedDataset(String networkName, IActiveOperationalDatasetReceiver receiver);
void setEnabled(boolean enabled, in IOperationReceiver receiver);
}
......@@ -68,6 +68,15 @@ public final class ThreadNetworkController {
/** The device is a Thread Leader. */
public static final int DEVICE_ROLE_LEADER = 4;
/** The Thread radio is disabled. */
public static final int STATE_DISABLED = 0;
/** The Thread radio is enabled. */
public static final int STATE_ENABLED = 1;
/** The Thread radio is being disabled. */
public static final int STATE_DISABLING = 2;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
......@@ -79,6 +88,13 @@ public final class ThreadNetworkController {
})
public @interface DeviceRole {}
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(
prefix = {"STATE_"},
value = {STATE_DISABLED, STATE_ENABLED, STATE_DISABLING})
public @interface EnabledState {}
/** Thread standard version 1.3. */
public static final int THREAD_VERSION_1_3 = 4;
......@@ -106,6 +122,40 @@ public final class ThreadNetworkController {
mControllerService = controllerService;
}
/**
* Enables/Disables the radio of this ThreadNetworkController. The requested enabled state will
* be persistent and survives device reboots.
*
* <p>When Thread is in {@code STATE_DISABLED}, {@link ThreadNetworkController} APIs which
* require the Thread radio will fail with error code {@link
* ThreadNetworkException#ERROR_THREAD_DISABLED}. When Thread is in {@code STATE_DISABLING},
* {@link ThreadNetworkController} APIs that return a {@link ThreadNetworkException} will fail
* with error code {@link ThreadNetworkException#ERROR_BUSY}.
*
* <p>On success, {@link OutcomeReceiver#onResult} of {@code receiver} is called. It indicates
* the operation has completed. But there maybe subsequent calls to update the enabled state,
* callers of this method should use {@link #registerStateCallback} to subscribe to the Thread
* enabled state changes.
*
* <p>On failure, {@link OutcomeReceiver#onError} of {@code receiver} will be invoked with a
* specific error in {@link ThreadNetworkException#ERROR_}.
*
* @param enabled {@code true} for enabling Thread
* @param executor the executor to execute {@code receiver}
* @param receiver the receiver to receive result of this operation
*/
@RequiresPermission("android.permission.THREAD_NETWORK_PRIVILEGED")
public void setEnabled(
boolean enabled,
@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Void, ThreadNetworkException> receiver) {
try {
mControllerService.setEnabled(enabled, new OperationReceiverProxy(executor, receiver));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** Returns the Thread version this device is operating on. */
@ThreadVersion
public int getThreadVersion() {
......@@ -170,6 +220,16 @@ public final class ThreadNetworkController {
* @param partitionId the new Thread partition ID
*/
default void onPartitionIdChanged(long partitionId) {}
/**
* The Thread enabled state has changed.
*
* <p>The Thread enabled state can be set with {@link setEnabled}, it may also be updated by
* airplane mode or admin control.
*
* @param enabledState the new Thread enabled state
*/
default void onThreadEnableStateChanged(@EnabledState int enabledState) {}
}
private static final class StateCallbackProxy extends IStateCallback.Stub {
......@@ -200,6 +260,16 @@ public final class ThreadNetworkController {
Binder.restoreCallingIdentity(identity);
}
}
@Override
public void onThreadEnableStateChanged(@EnabledState int enabled) {
final long identity = Binder.clearCallingIdentity();
try {
mExecutor.execute(() -> mCallback.onThreadEnableStateChanged(enabled));
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
/**
......
......@@ -48,6 +48,7 @@ public class ThreadNetworkException extends Exception {
ERROR_RESPONSE_BAD_FORMAT,
ERROR_RESOURCE_EXHAUSTED,
ERROR_UNKNOWN,
ERROR_THREAD_DISABLED,
})
public @interface ErrorCode {}
......@@ -129,6 +130,13 @@ public class ThreadNetworkException extends Exception {
*/
public static final int ERROR_UNKNOWN = 11;
/**
* The operation failed because the Thread radio is disabled by {@link
* ThreadNetworkController#setEnabled}, airplane mode or device admin. The caller should retry
* only after Thread is enabled.
*/
public static final int ERROR_THREAD_DISABLED = 12;
private final int mErrorCode;
/** Creates a new {@link ThreadNetworkException} object with given error code and message. */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment