diff options
author | Kolin Lu <kolinlu@google.com> | 2023-04-27 16:17:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-27 16:17:19 -0700 |
commit | 1d3fa077dd023d0174ce282bdbf9d2c9bd9f4b83 (patch) | |
tree | e516d5d795675fc71b5ff5410faf8f5f8d84c07c | |
parent | 20d9d3dfda778f8394c6468f5793f14a824a8f06 (diff) | |
download | mobly-snippet-lib-1d3fa077dd023d0174ce282bdbf9d2c9bd9f4b83.tar.gz |
Support `@RpcOptional`
With this annotation, arguments which are not present when calling will be assign `null` value by default.
Usage:
```java
@Rpc(description = "Returns true if value is null, false otherwise.")
public boolean isValueNull(@RpcOptional Integer value) {
return value == null;
}
```
```python
assert mbs.isValueNull()==True
assert mbs.isValueNull(0)==False
```
-rw-r--r-- | third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/MethodDescriptor.java | 39 | ||||
-rw-r--r-- | third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/RpcOptional.java | 34 |
2 files changed, 73 insertions, 0 deletions
diff --git a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/MethodDescriptor.java b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/MethodDescriptor.java index b9c8a7a..506fae9 100644 --- a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/MethodDescriptor.java +++ b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/MethodDescriptor.java @@ -22,6 +22,7 @@ import com.google.android.mobly.snippet.Snippet; import com.google.android.mobly.snippet.manager.SnippetManager; import com.google.android.mobly.snippet.manager.SnippetObjectConverterManager; import com.google.android.mobly.snippet.util.AndroidUtil; +import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; @@ -68,6 +69,7 @@ public final class MethodDescriptor { * @throws Throwable the exception raised from executing the RPC method. */ public Object invoke(SnippetManager manager, final JSONArray parameters) throws Throwable { + final Annotation annotations[][] = getParameterAnnotations(); final Type[] parameterTypes = getGenericParameterTypes(); final Object[] args = new Object[parameterTypes.length]; @@ -79,6 +81,8 @@ public final class MethodDescriptor { final Type parameterType = parameterTypes[i]; if (i < parameters.length()) { args[i] = convertParameter(parameters, i, parameterType); + } else if (MethodDescriptor.hasDefaultValue(annotations[i])) { + args[i] = MethodDescriptor.getDefaultValue(parameterType, annotations[i]); } else { throw new RpcError("Argument " + (i + 1) + " is not present"); } @@ -218,6 +222,10 @@ public final class MethodDescriptor { return mClass; } + public Annotation[][] getParameterAnnotations() { + return mMethod.getParameterAnnotations(); + } + private String getAnnotationDescription() { if (isAsync()) { AsyncRpc annotation = mMethod.getAnnotation(AsyncRpc.class); @@ -226,6 +234,7 @@ public final class MethodDescriptor { Rpc annotation = mMethod.getAnnotation(Rpc.class); return annotation.description(); } + /** * Returns a human-readable help text for this RPC, based on annotations in the source code. * @@ -249,4 +258,34 @@ public final class MethodDescriptor { mMethod.getReturnType().getSimpleName(), getAnnotationDescription()); } + + /** + * Returns the default value for a specific parameter. + * + * @param parameterType parameterType + * @param annotations annotations of the parameter + */ + public static Object getDefaultValue(Type parameterType, Annotation[] annotations) { + for (Annotation a : annotations) { + if (a instanceof RpcOptional) { + return null; + } + } + throw new IllegalStateException("No default value for " + parameterType); + } + + /** + * Determines whether or not this parameter has default value. + * + * @param annotations annotations of the parameter + */ + public static boolean hasDefaultValue(Annotation[] annotations) { + for (Annotation a : annotations) { + if (a instanceof RpcOptional) { + return true; + } + } + return false; + } + } diff --git a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/RpcOptional.java b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/RpcOptional.java new file mode 100644 index 0000000..b4b43aa --- /dev/null +++ b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/rpc/RpcOptional.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2016 Google Inc. + * + * 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 com.google.android.mobly.snippet.rpc; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Use this annotation to mark RPC parameter as optional. + * + * <p>The parameter marked as optional has no explicit default value. {@code null} is used as + * default value. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +@Documented +public @interface RpcOptional {} |