diff options
25 files changed, 1103 insertions, 149 deletions
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 802c1a0ae6d5..08817e05e0a5 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3301,7 +3301,7 @@ public abstract class Context { * <dt> {@link #VIBRATOR_SERVICE} ("vibrator") * <dd> A {@link android.os.Vibrator} for interacting with the vibrator * hardware. - * <dt> {@link #CONNECTIVITY_SERVICE} ("connection") + * <dt> {@link #CONNECTIVITY_SERVICE} ("connectivity") * <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for * handling management of network connections. * <dt> {@link #IPSEC_SERVICE} ("ipsec") diff --git a/core/java/com/android/internal/util/function/DecConsumer.java b/core/java/com/android/internal/util/function/DecConsumer.java new file mode 100644 index 000000000000..0abb785bea32 --- /dev/null +++ b/core/java/com/android/internal/util/function/DecConsumer.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 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 com.android.internal.util.function; + +import java.util.function.Consumer; + +/** + * A 10-argument {@link Consumer} + * + * @hide + */ +public interface DecConsumer<A, B, C, D, E, F, G, H, I, J> { + void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j); +} diff --git a/core/java/com/android/internal/util/function/DecFunction.java b/core/java/com/android/internal/util/function/DecFunction.java new file mode 100644 index 000000000000..59fc5e6e6562 --- /dev/null +++ b/core/java/com/android/internal/util/function/DecFunction.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 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 com.android.internal.util.function; + +import java.util.function.Function; + +/** + * A 10-argument {@link Function} + * + * @hide + */ +public interface DecFunction<A, B, C, D, E, F, G, H, I, J, R> { + R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j); +} diff --git a/core/java/com/android/internal/util/function/DecPredicate.java b/core/java/com/android/internal/util/function/DecPredicate.java new file mode 100644 index 000000000000..975993dc05dc --- /dev/null +++ b/core/java/com/android/internal/util/function/DecPredicate.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 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 com.android.internal.util.function; + +import java.util.function.Predicate; + +/** + * A 10-argument {@link Predicate} + * + * @hide + */ +public interface DecPredicate<A, B, C, D, E, F, G, H, I, J> { + boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j); +} diff --git a/core/java/com/android/internal/util/function/UndecConsumer.java b/core/java/com/android/internal/util/function/UndecConsumer.java new file mode 100644 index 000000000000..1a1d4ca600af --- /dev/null +++ b/core/java/com/android/internal/util/function/UndecConsumer.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 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 com.android.internal.util.function; + +import java.util.function.Consumer; + +/** + * A 11-argument {@link Consumer} + * + * @hide + */ +public interface UndecConsumer<A, B, C, D, E, F, G, H, I, J, K> { + void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k); +} diff --git a/core/java/com/android/internal/util/function/UndecFunction.java b/core/java/com/android/internal/util/function/UndecFunction.java new file mode 100644 index 000000000000..5cd324c2a7e5 --- /dev/null +++ b/core/java/com/android/internal/util/function/UndecFunction.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 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 com.android.internal.util.function; + +import java.util.function.Function; + +/** + * A 11-argument {@link Function} + * + * @hide + */ +public interface UndecFunction<A, B, C, D, E, F, G, H, I, J, K, R> { + R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k); +} diff --git a/core/java/com/android/internal/util/function/UndecPredicate.java b/core/java/com/android/internal/util/function/UndecPredicate.java new file mode 100644 index 000000000000..c09193eb7a11 --- /dev/null +++ b/core/java/com/android/internal/util/function/UndecPredicate.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 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 com.android.internal.util.function; + +import java.util.function.Predicate; + +/** + * A 11-argument {@link Predicate} + * + * @hide + */ +public interface UndecPredicate<A, B, C, D, E, F, G, H, I, J, K> { + boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k); +} diff --git a/core/java/com/android/internal/util/function/pooled/OmniFunction.java b/core/java/com/android/internal/util/function/pooled/OmniFunction.java index d74e715605bb..7a17253ffd35 100755 --- a/core/java/com/android/internal/util/function/pooled/OmniFunction.java +++ b/core/java/com/android/internal/util/function/pooled/OmniFunction.java @@ -18,6 +18,8 @@ package com.android.internal.util.function.pooled; import com.android.internal.util.FunctionalUtils.ThrowingRunnable; import com.android.internal.util.FunctionalUtils.ThrowingSupplier; +import com.android.internal.util.function.DecConsumer; +import com.android.internal.util.function.DecFunction; import com.android.internal.util.function.HeptConsumer; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.HexConsumer; @@ -32,6 +34,8 @@ import com.android.internal.util.function.QuintConsumer; import com.android.internal.util.function.QuintFunction; import com.android.internal.util.function.TriConsumer; import com.android.internal.util.function.TriFunction; +import com.android.internal.util.function.UndecConsumer; +import com.android.internal.util.function.UndecFunction; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -43,62 +47,65 @@ import java.util.function.Function; * * @hide */ -abstract class OmniFunction<A, B, C, D, E, F, G, H, I, R> implements +abstract class OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> implements PooledFunction<A, R>, BiFunction<A, B, R>, TriFunction<A, B, C, R>, QuadFunction<A, B, C, D, R>, QuintFunction<A, B, C, D, E, R>, HexFunction<A, B, C, D, E, F, R>, HeptFunction<A, B, C, D, E, F, G, R>, OctFunction<A, B, C, D, E, F, G, H, R>, NonaFunction<A, B, C, D, E, F, G, H, I, R>, + DecFunction<A, B, C, D, E, F, G, H, I, J, R>, + UndecFunction<A, B, C, D, E, F, G, H, I, J, K, R>, PooledConsumer<A>, BiConsumer<A, B>, TriConsumer<A, B, C>, QuadConsumer<A, B, C, D>, QuintConsumer<A, B, C, D, E>, HexConsumer<A, B, C, D, E, F>, HeptConsumer<A, B, C, D, E, F, G>, OctConsumer<A, B, C, D, E, F, G, H>, - NonaConsumer<A, B, C, D, E, F, G, H, I>, PooledPredicate<A>, BiPredicate<A, B>, - PooledSupplier<R>, PooledRunnable, ThrowingRunnable, ThrowingSupplier<R>, - PooledSupplier.OfInt, PooledSupplier.OfLong, PooledSupplier.OfDouble { + NonaConsumer<A, B, C, D, E, F, G, H, I>, DecConsumer<A, B, C, D, E, F, G, H, I, J>, + UndecConsumer<A, B, C, D, E, F, G, H, I, J, K>, + PooledPredicate<A>, BiPredicate<A, B>, PooledSupplier<R>, PooledRunnable, ThrowingRunnable, + ThrowingSupplier<R>, PooledSupplier.OfInt, PooledSupplier.OfLong, PooledSupplier.OfDouble { - abstract R invoke(A a, B b, C c, D d, E e, F f, G g, H h, I i); + abstract R invoke(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k); @Override public R apply(A o, B o2) { - return invoke(o, o2, null, null, null, null, null, null, null); + return invoke(o, o2, null, null, null, null, null, null, null, null, null); } @Override public R apply(A o) { - return invoke(o, null, null, null, null, null, null, null, null); + return invoke(o, null, null, null, null, null, null, null, null, null, null); } - public abstract <V> OmniFunction<A, B, C, D, E, F, G, H, I, V> andThen( + public abstract <V> OmniFunction<A, B, C, D, E, F, G, H, I, J, K, V> andThen( Function<? super R, ? extends V> after); - public abstract OmniFunction<A, B, C, D, E, F, G, H, I, R> negate(); + public abstract OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> negate(); @Override public void accept(A o, B o2) { - invoke(o, o2, null, null, null, null, null, null, null); + invoke(o, o2, null, null, null, null, null, null, null, null, null); } @Override public void accept(A o) { - invoke(o, null, null, null, null, null, null, null, null); + invoke(o, null, null, null, null, null, null, null, null, null, null); } @Override public void run() { - invoke(null, null, null, null, null, null, null, null, null); + invoke(null, null, null, null, null, null, null, null, null, null, null); } @Override public R get() { - return invoke(null, null, null, null, null, null, null, null, null); + return invoke(null, null, null, null, null, null, null, null, null, null, null); } @Override public boolean test(A o, B o2) { - return (Boolean) invoke(o, o2, null, null, null, null, null, null, null); + return (Boolean) invoke(o, o2, null, null, null, null, null, null, null, null, null); } @Override public boolean test(A o) { - return (Boolean) invoke(o, null, null, null, null, null, null, null, null); + return (Boolean) invoke(o, null, null, null, null, null, null, null, null, null, null); } @Override @@ -113,72 +120,92 @@ abstract class OmniFunction<A, B, C, D, E, F, G, H, I, R> implements @Override public R apply(A a, B b, C c) { - return invoke(a, b, c, null, null, null, null, null, null); + return invoke(a, b, c, null, null, null, null, null, null, null, null); } @Override public void accept(A a, B b, C c) { - invoke(a, b, c, null, null, null, null, null, null); + invoke(a, b, c, null, null, null, null, null, null, null, null); } @Override public R apply(A a, B b, C c, D d) { - return invoke(a, b, c, d, null, null, null, null, null); + return invoke(a, b, c, d, null, null, null, null, null, null, null); } @Override public R apply(A a, B b, C c, D d, E e) { - return invoke(a, b, c, d, e, null, null, null, null); + return invoke(a, b, c, d, e, null, null, null, null, null, null); } @Override public R apply(A a, B b, C c, D d, E e, F f) { - return invoke(a, b, c, d, e, f, null, null, null); + return invoke(a, b, c, d, e, f, null, null, null, null, null); } @Override public R apply(A a, B b, C c, D d, E e, F f, G g) { - return invoke(a, b, c, d, e, f, g, null, null); + return invoke(a, b, c, d, e, f, g, null, null, null, null); } @Override public R apply(A a, B b, C c, D d, E e, F f, G g, H h) { - return invoke(a, b, c, d, e, f, g, h, null); + return invoke(a, b, c, d, e, f, g, h, null, null, null); } @Override public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i) { - return invoke(a, b, c, d, e, f, g, h, i); + return invoke(a, b, c, d, e, f, g, h, i, null, null); + } + + @Override + public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) { + return invoke(a, b, c, d, e, f, g, h, i, j, null); + } + + @Override + public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) { + return invoke(a, b, c, d, e, f, g, h, i, j, k); } @Override public void accept(A a, B b, C c, D d) { - invoke(a, b, c, d, null, null, null, null, null); + invoke(a, b, c, d, null, null, null, null, null, null, null); } @Override public void accept(A a, B b, C c, D d, E e) { - invoke(a, b, c, d, e, null, null, null, null); + invoke(a, b, c, d, e, null, null, null, null, null, null); } @Override public void accept(A a, B b, C c, D d, E e, F f) { - invoke(a, b, c, d, e, f, null, null, null); + invoke(a, b, c, d, e, f, null, null, null, null, null); } @Override public void accept(A a, B b, C c, D d, E e, F f, G g) { - invoke(a, b, c, d, e, f, g, null, null); + invoke(a, b, c, d, e, f, g, null, null, null, null); } @Override public void accept(A a, B b, C c, D d, E e, F f, G g, H h) { - invoke(a, b, c, d, e, f, g, h, null); + invoke(a, b, c, d, e, f, g, h, null, null, null); } @Override public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i) { - invoke(a, b, c, d, e, f, g, h, i); + invoke(a, b, c, d, e, f, g, h, i, null, null); + } + + @Override + public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) { + invoke(a, b, c, d, e, f, g, h, i, j, null); + } + + @Override + public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) { + invoke(a, b, c, d, e, f, g, h, i, j, k); } @Override @@ -192,5 +219,5 @@ abstract class OmniFunction<A, B, C, D, E, F, G, H, I, R> implements } @Override - public abstract OmniFunction<A, B, C, D, E, F, G, H, I, R> recycleOnUse(); + public abstract OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> recycleOnUse(); } diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambda.java b/core/java/com/android/internal/util/function/pooled/PooledLambda.java index c00932e7a8aa..b9bf9337c3d6 100755 --- a/core/java/com/android/internal/util/function/pooled/PooledLambda.java +++ b/core/java/com/android/internal/util/function/pooled/PooledLambda.java @@ -21,6 +21,8 @@ import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquire import android.os.Message; +import com.android.internal.util.function.DecConsumer; +import com.android.internal.util.function.DecFunction; import com.android.internal.util.function.HeptConsumer; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.HexConsumer; @@ -35,6 +37,8 @@ import com.android.internal.util.function.QuintConsumer; import com.android.internal.util.function.QuintFunction; import com.android.internal.util.function.TriConsumer; import com.android.internal.util.function.TriFunction; +import com.android.internal.util.function.UndecConsumer; +import com.android.internal.util.function.UndecFunction; import com.android.internal.util.function.pooled.PooledLambdaImpl.LambdaType.ReturnType; import java.util.function.BiConsumer; @@ -181,7 +185,7 @@ public interface PooledLambda { A arg1) { return acquire(PooledLambdaImpl.sPool, function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -198,7 +202,7 @@ public interface PooledLambda { A arg1) { return acquire(PooledLambdaImpl.sPool, function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -215,7 +219,7 @@ public interface PooledLambda { A arg1) { return acquire(PooledLambdaImpl.sPool, function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -246,7 +250,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -266,7 +270,7 @@ public interface PooledLambda { A arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -284,7 +288,7 @@ public interface PooledLambda { A arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -302,7 +306,7 @@ public interface PooledLambda { A arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -320,7 +324,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -338,7 +342,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -356,7 +360,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -374,7 +378,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -392,7 +396,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -410,7 +414,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); } /** @@ -442,7 +446,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -463,7 +467,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -482,7 +486,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -501,7 +505,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -520,7 +524,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -539,7 +543,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -558,7 +562,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -577,7 +581,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -596,7 +600,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); } /** @@ -629,7 +633,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -651,7 +655,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -671,7 +675,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -691,7 +695,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -711,7 +715,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -731,7 +735,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -751,7 +755,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -771,7 +775,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -791,7 +795,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -811,7 +815,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -831,7 +835,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); } /** @@ -865,7 +869,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -888,7 +892,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5) { return acquire(PooledLambdaImpl.sPool, function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null, - null); + null, null, null); } /** @@ -909,7 +913,7 @@ public interface PooledLambda { function, A arg1, B arg2, C arg3, D arg4, E arg5) { return acquire(PooledLambdaImpl.sPool, function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null, null, null, - null); + null, null, null); } /** @@ -945,7 +949,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -969,7 +973,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) { return acquire(PooledLambdaImpl.sPool, function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null, - null); + null, null, null); } /** @@ -991,7 +995,7 @@ public interface PooledLambda { ? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) { return acquire(PooledLambdaImpl.sPool, function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, null, null, - null); + null, null, null); } /** @@ -1028,7 +1032,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1053,7 +1057,7 @@ public interface PooledLambda { ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) { return acquire(PooledLambdaImpl.sPool, function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null, - null); + null, null, null); } /** @@ -1077,7 +1081,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) { return acquire(PooledLambdaImpl.sPool, function, 7, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null, - null); + null, null, null); } /** @@ -1115,7 +1119,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1142,7 +1146,7 @@ public interface PooledLambda { H arg8) { return acquire(PooledLambdaImpl.sPool, function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - null); + null, null, null); } /** @@ -1167,7 +1171,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8) { return acquire(PooledLambdaImpl.sPool, function, 8, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - null); + null, null, null); } /** @@ -1207,7 +1211,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - null); + null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1235,7 +1239,7 @@ public interface PooledLambda { E arg5, F arg6, G arg7, H arg8, I arg9) { return acquire(PooledLambdaImpl.sPool, function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9); + arg9, null, null); } /** @@ -1261,7 +1265,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9) { return acquire(PooledLambdaImpl.sPool, function, 9, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9); + arg9, null, null); } /** @@ -1302,7 +1306,209 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9); + arg9, null, null); + return Message.obtain().setCallback(callback.recycleOnUse()); + } + } + + /** + * {@link PooledRunnable} factory + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @return a {@link PooledRunnable}, equivalent to lambda: + * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) } + */ + static <A, B, C, D, E, F, G, H, I, J> PooledRunnable obtainRunnable( + DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3, + D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) { + return acquire(PooledLambdaImpl.sPool, + function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, + arg9, arg10, null); + } + + /** + * {@link PooledSupplier} factory + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @return a {@link PooledSupplier}, equivalent to lambda: + * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) } + */ + static <A, B, C, D, E, F, G, H, I, J, R> PooledSupplier<R> obtainSupplier( + DecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J, ? extends R> function, + A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) { + return acquire(PooledLambdaImpl.sPool, + function, 10, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, + arg9, arg10, null); + } + + /** + * Factory of {@link Message}s that contain an + * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its + * {@link Message#getCallback internal callback}. + * + * The callback is equivalent to one obtainable via + * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)} + * + * Note that using this method with {@link android.os.Handler#handleMessage} + * is more efficient than the alternative of {@link android.os.Handler#post} + * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points + * when obtaining {@link Message} and {@link PooledRunnable} from pools separately + * + * You may optionally set a {@link Message#what} for the message if you want to be + * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise + * there's no need to do so + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6, + * arg7, arg8, arg9, arg10) } when handled + */ + static <A, B, C, D, E, F, G, H, I, J> Message obtainMessage( + DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3, + D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) { + synchronized (Message.sPoolSync) { + PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, + function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, + arg8, arg9, arg10, null); + return Message.obtain().setCallback(callback.recycleOnUse()); + } + } + + /** + * {@link PooledRunnable} factory + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @param arg11 parameter supplied to {@code function} on call + * @return a {@link PooledRunnable}, equivalent to lambda: + * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, + * arg11) } + */ + static <A, B, C, D, E, F, G, H, I, J, K> PooledRunnable obtainRunnable( + UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2, + C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) { + return acquire(PooledLambdaImpl.sPool, + function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, + arg9, arg10, arg11); + } + + /** + * {@link PooledSupplier} factory + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @param arg11 parameter supplied to {@code function} on call + * @return a {@link PooledSupplier}, equivalent to lambda: + * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, + * arg11) } + */ + static <A, B, C, D, E, F, G, H, I, J, K, R> PooledSupplier<R> obtainSupplier( + UndecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J, ? super K, ? extends R> function, + A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, + K arg11) { + return acquire(PooledLambdaImpl.sPool, + function, 11, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, + arg9, arg10, arg11); + } + + /** + * Factory of {@link Message}s that contain an + * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its + * {@link Message#getCallback internal callback}. + * + * The callback is equivalent to one obtainable via + * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)} + * + * Note that using this method with {@link android.os.Handler#handleMessage} + * is more efficient than the alternative of {@link android.os.Handler#post} + * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points + * when obtaining {@link Message} and {@link PooledRunnable} from pools separately + * + * You may optionally set a {@link Message#what} for the message if you want to be + * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise + * there's no need to do so + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @param arg11 parameter supplied to {@code function} on call + * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6, + * arg7, arg8, arg9, arg10, arg11) } when handled + */ + static <A, B, C, D, E, F, G, H, I, J, K> Message obtainMessage( + UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2, + C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) { + synchronized (Message.sPoolSync) { + PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, + function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, + arg8, arg9, arg10, arg11); return Message.obtain().setCallback(callback.recycleOnUse()); } } diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java index e12c031f0036..c7502ef04f1b 100755 --- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java +++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java @@ -26,6 +26,9 @@ import android.util.Pools; import com.android.internal.util.ArrayUtils; import com.android.internal.util.BitUtils; import com.android.internal.util.Preconditions; +import com.android.internal.util.function.DecConsumer; +import com.android.internal.util.function.DecFunction; +import com.android.internal.util.function.DecPredicate; import com.android.internal.util.function.HeptConsumer; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.HeptPredicate; @@ -47,6 +50,9 @@ import com.android.internal.util.function.QuintPredicate; import com.android.internal.util.function.TriConsumer; import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.TriPredicate; +import com.android.internal.util.function.UndecConsumer; +import com.android.internal.util.function.UndecFunction; +import com.android.internal.util.function.UndecPredicate; import java.util.Arrays; import java.util.Objects; @@ -63,12 +69,12 @@ import java.util.function.Supplier; * @hide */ final class PooledLambdaImpl<R> extends OmniFunction<Object, - Object, Object, Object, Object, Object, Object, Object, Object, R> { + Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, R> { private static final boolean DEBUG = false; private static final String LOG_TAG = "PooledLambdaImpl"; - private static final int MAX_ARGS = 9; + private static final int MAX_ARGS = 11; private static final int MAX_POOL_SIZE = 50; @@ -134,7 +140,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, /** * Bit schema: - * AAAAAAAAABCDEEEEEEFFFFFF + * AAAAAAAAAAABCDEEEEEEFFFFFF * * Where: * A - whether {@link #mArgs arg} at corresponding index was specified at @@ -171,18 +177,18 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, @Override R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9) { + Object a8, Object a9, Object a10, Object a11) { checkNotRecycled(); if (DEBUG) { Log.i(LOG_TAG, this + ".invoke(" + commaSeparateFirstN( - new Object[] { a1, a2, a3, a4, a5, a6, a7, a8, a9 }, + new Object[] { a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 }, LambdaType.decodeArgCount(getFlags(MASK_EXPOSED_AS))) + ")"); } final boolean notUsed = fillInArg(a1) && fillInArg(a2) && fillInArg(a3) && fillInArg(a4) && fillInArg(a5) && fillInArg(a6) && fillInArg(a7) && fillInArg(a8) - && fillInArg(a9); + && fillInArg(a9) && fillInArg(a10) && fillInArg(a11); int argCount = LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE)); if (argCount != LambdaType.MASK_ARG_COUNT) { for (int i = 0; i < argCount; i++) { @@ -410,6 +416,48 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, } } } break; + + case 10: { + switch (returnType) { + case LambdaType.ReturnType.VOID: { + ((DecConsumer) mFunc).accept(popArg(0), popArg(1), + popArg(2), popArg(3), popArg(4), popArg(5), + popArg(6), popArg(7), popArg(8), popArg(9)); + return null; + } + case LambdaType.ReturnType.BOOLEAN: { + return (R) (Object) ((DecPredicate) mFunc).test(popArg(0), + popArg(1), popArg(2), popArg(3), popArg(4), + popArg(5), popArg(6), popArg(7), popArg(8), popArg(9)); + } + case LambdaType.ReturnType.OBJECT: { + return (R) ((DecFunction) mFunc).apply(popArg(0), popArg(1), + popArg(2), popArg(3), popArg(4), popArg(5), + popArg(6), popArg(7), popArg(8), popArg(9)); + } + } + } break; + + case 11: { + switch (returnType) { + case LambdaType.ReturnType.VOID: { + ((UndecConsumer) mFunc).accept(popArg(0), popArg(1), + popArg(2), popArg(3), popArg(4), popArg(5), + popArg(6), popArg(7), popArg(8), popArg(9), popArg(10)); + return null; + } + case LambdaType.ReturnType.BOOLEAN: { + return (R) (Object) ((UndecPredicate) mFunc).test(popArg(0), + popArg(1), popArg(2), popArg(3), popArg(4), + popArg(5), popArg(6), popArg(7), popArg(8), popArg(9), popArg(10)); + } + case LambdaType.ReturnType.OBJECT: { + return (R) ((UndecFunction) mFunc).apply(popArg(0), popArg(1), + popArg(2), popArg(3), popArg(4), popArg(5), + popArg(6), popArg(7), popArg(8), popArg(9), popArg(10)); + } + } + } break; } throw new IllegalStateException("Unknown function type: " + LambdaType.toString(funcType)); } @@ -475,7 +523,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, */ static <E extends PooledLambda> E acquire(Pool pool, Object func, int fNumArgs, int numPlaceholders, int fReturnType, Object a, Object b, Object c, - Object d, Object e, Object f, Object g, Object h, Object i) { + Object d, Object e, Object f, Object g, Object h, Object i, Object j, Object k) { PooledLambdaImpl r = acquire(pool); if (DEBUG) { Log.i(LOG_TAG, @@ -493,6 +541,8 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, + ", g = " + g + ", h = " + h + ", i = " + i + + ", j = " + j + + ", k = " + k + ")"); } r.mFunc = Preconditions.checkNotNull(func); @@ -508,6 +558,8 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, setIfInBounds(r.mArgs, 6, g); setIfInBounds(r.mArgs, 7, h); setIfInBounds(r.mArgs, 8, i); + setIfInBounds(r.mArgs, 9, j); + setIfInBounds(r.mArgs, 10, k); return (E) r; } @@ -564,13 +616,13 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, @Override public OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object, - R> negate() { + Object, Object, R> negate() { throw new UnsupportedOperationException(); } @Override public <V> OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object, - V> andThen(Function<? super R, ? extends V> after) { + Object, Object, V> andThen(Function<? super R, ? extends V> after) { throw new UnsupportedOperationException(); } @@ -591,7 +643,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, @Override public OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object, - R> recycleOnUse() { + Object, Object, R> recycleOnUse() { if (DEBUG) Log.i(LOG_TAG, this + ".recycleOnUse()"); mFlags |= FLAG_RECYCLE_ON_USE; return this; @@ -683,6 +735,8 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, case 7: return "Hept"; case 8: return "Oct"; case 9: return "Nona"; + case 10: return "Dec"; + case 11: return "Undec"; default: return "" + argCount + "arg"; } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 8d167e8783bf..a00a8e7aa4e9 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -128,7 +128,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - mSecurityModel = new KeyguardSecurityModel(context); + mSecurityModel = Dependency.get(KeyguardSecurityModel.class); mLockPatternUtils = new LockPatternUtils(context); mUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java index bb89959b7a11..1395fd9e3482 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java @@ -25,6 +25,10 @@ import com.android.internal.telephony.IccCardConstants; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.Dependency; +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton public class KeyguardSecurityModel { /** @@ -46,6 +50,7 @@ public class KeyguardSecurityModel { private LockPatternUtils mLockPatternUtils; + @Inject KeyguardSecurityModel(Context context) { mContext = context; mLockPatternUtils = new LockPatternUtils(context); @@ -57,7 +62,7 @@ public class KeyguardSecurityModel { mLockPatternUtils = utils; } - SecurityMode getSecurityMode(int userId) { + public SecurityMode getSecurityMode(int userId) { KeyguardUpdateMonitor monitor = Dependency.get(KeyguardUpdateMonitor.class); if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId( diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index a6b3be23417e..dc8ee16e8645 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -58,6 +58,7 @@ import android.content.IntentFilter; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.pm.UserInfo; import android.database.ContentObserver; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricSourceType; @@ -329,6 +330,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private SparseBooleanArray mUserIsUnlocked = new SparseBooleanArray(); private SparseBooleanArray mUserHasTrust = new SparseBooleanArray(); private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray(); + private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray(); private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray(); private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray(); private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray(); @@ -472,6 +474,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { public void onTrustManagedChanged(boolean managed, int userId) { checkIsHandlerThread(); mUserTrustIsManaged.put(userId, managed); + mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId)); for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { @@ -925,6 +928,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId); } + /** + * Cached version of {@link TrustManager#isTrustUsuallyManaged(int)}. + */ + public boolean isTrustUsuallyManaged(int userId) { + checkIsHandlerThread(); + return mUserTrustIsUsuallyManaged.get(userId); + } + public boolean isUnlockingWithBiometricAllowed() { return mStrongAuthTracker.isUnlockingWithBiometricAllowed(); } @@ -1474,9 +1485,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { mUserIsUnlocked.put(userId, mUserManager.isUserUnlocked(userId)); } - private void handleUserRemoved(int userId) { + @VisibleForTesting + void handleUserRemoved(int userId) { checkIsHandlerThread(); mUserIsUnlocked.delete(userId); + mUserTrustIsUsuallyManaged.delete(userId); } @VisibleForTesting @@ -1662,7 +1675,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { e.rethrowAsRuntimeException(); } - mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE); + mTrustManager = context.getSystemService(TrustManager.class); mTrustManager.registerTrustListener(this); mLockPatternUtils = new LockPatternUtils(context); mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker); @@ -1697,6 +1710,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user)); mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class); mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled(); + List<UserInfo> allUsers = mUserManager.getUsers(); + for (UserInfo userInfo : allUsers) { + mUserTrustIsUsuallyManaged.put(userInfo.id, + mTrustManager.isTrustUsuallyManaged(userInfo.id)); + } updateAirplaneModeState(); TelephonyManager telephony = @@ -2048,6 +2066,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { */ private void handleUserSwitching(int userId, IRemoteCallback reply) { checkIsHandlerThread(); + mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId)); for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 37bb54cc1b11..07bfa7194413 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -30,6 +30,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.Preconditions; +import com.android.keyguard.KeyguardSecurityModel; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.clock.ClockManager; import com.android.settingslib.bluetooth.LocalBluetoothManager; @@ -316,6 +317,7 @@ public class Dependency { @Inject Lazy<FalsingManager> mFalsingManager; @Inject Lazy<SysUiState> mSysUiStateFlagsContainer; @Inject Lazy<AlarmManager> mAlarmManager; + @Inject Lazy<KeyguardSecurityModel> mKeyguardSecurityModel; @Inject public Dependency() { @@ -501,6 +503,7 @@ public class Dependency { mProviders.put(FalsingManager.class, mFalsingManager::get); mProviders.put(SysUiState.class, mSysUiStateFlagsContainer::get); mProviders.put(AlarmManager.class, mAlarmManager::get); + mProviders.put(KeyguardSecurityModel.class, mKeyguardSecurityModel::get); // TODO(b/118592525): to support multi-display , we start to add something which is // per-display, while others may be global. I think it's time to add diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index f159d8c1d431..6a7b21a9b9d2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -650,29 +650,26 @@ public class KeyguardViewMediator extends SystemUI { @Override public int getBouncerPromptReason() { - // TODO(b/140053364) - return whitelistIpcs(() -> { - int currentUser = ActivityManager.getCurrentUser(); - boolean trust = mTrustManager.isTrustUsuallyManaged(currentUser); - boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser); - boolean any = trust || biometrics; - KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker = - mUpdateMonitor.getStrongAuthTracker(); - int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser); - - if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) { - return KeyguardSecurityView.PROMPT_REASON_RESTART; - } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) { - return KeyguardSecurityView.PROMPT_REASON_TIMEOUT; - } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) { - return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN; - } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) { - return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST; - } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) { - return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT; - } - return KeyguardSecurityView.PROMPT_REASON_NONE; - }); + int currentUser = KeyguardUpdateMonitor.getCurrentUser(); + boolean trust = mUpdateMonitor.isTrustUsuallyManaged(currentUser); + boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser); + boolean any = trust || biometrics; + KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker = + mUpdateMonitor.getStrongAuthTracker(); + int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser); + + if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) { + return KeyguardSecurityView.PROMPT_REASON_RESTART; + } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) { + return KeyguardSecurityView.PROMPT_REASON_TIMEOUT; + } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) { + return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN; + } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) { + return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST; + } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) { + return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT; + } + return KeyguardSecurityView.PROMPT_REASON_NONE; } @Override @@ -701,7 +698,7 @@ public class KeyguardViewMediator extends SystemUI { private void setupLocked() { mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE); + mTrustManager = mContext.getSystemService(TrustManager.class); mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard"); mShowKeyguardWakeLock.setReferenceCounted(false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index c3de84366d4b..f34c15c7099d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.phone; import static com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.plugins.ActivityStarter.OnDismissAction; import android.content.Context; @@ -38,11 +37,13 @@ import android.view.WindowInsets; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardHostView; +import com.android.keyguard.KeyguardSecurityModel; import com.android.keyguard.KeyguardSecurityView; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.DejankUtils; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.plugins.FalsingManager; @@ -461,15 +462,9 @@ public class KeyguardBouncer { * notifications on Keyguard, like SIM PIN/PUK. */ public boolean needsFullscreenBouncer() { - // TODO(b/140059518) - return whitelistIpcs(() -> { - ensureView(); - if (mKeyguardView != null) { - SecurityMode mode = mKeyguardView.getSecurityMode(); - return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk; - } - return false; - }); + SecurityMode mode = Dependency.get(KeyguardSecurityModel.class).getSecurityMode( + KeyguardUpdateMonitor.getCurrentUser()); + return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk; } /** diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index ad7bba1e0790..57b09872f9c1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; @@ -481,6 +482,25 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { assertThat(mKeyguardUpdateMonitor.isUserUnlocked(randomUser)).isFalse(); } + @Test + public void testTrustUsuallyManaged_whenTrustChanges() { + int user = KeyguardUpdateMonitor.getCurrentUser(); + when(mTrustManager.isTrustUsuallyManaged(eq(user))).thenReturn(true); + mKeyguardUpdateMonitor.onTrustManagedChanged(false /* managed */, user); + assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isTrue(); + } + + @Test + public void testTrustUsuallyManaged_resetWhenUserIsRemoved() { + int user = KeyguardUpdateMonitor.getCurrentUser(); + when(mTrustManager.isTrustUsuallyManaged(eq(user))).thenReturn(true); + mKeyguardUpdateMonitor.onTrustManagedChanged(false /* managed */, user); + assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isTrue(); + + mKeyguardUpdateMonitor.handleUserRemoved(user); + assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isFalse(); + } + private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) { int subscription = simInited ? 1/* mock subid=1 */ : SubscriptionManager.DUMMY_SUBSCRIPTION_ID_BASE; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index 3ba3e281dc81..cb87d7d842a4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -89,6 +89,8 @@ public class KeyguardBouncerTest extends SysuiTestCase { private KeyguardBypassController mKeyguardBypassController; @Mock private Handler mHandler; + @Mock + private KeyguardSecurityModel mKeyguardSecurityModel; private KeyguardBouncer mBouncer; @@ -97,6 +99,9 @@ public class KeyguardBouncerTest extends SysuiTestCase { com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper(); MockitoAnnotations.initMocks(this); mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor); + mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel); + when(mKeyguardSecurityModel.getSecurityMode(anyInt())) + .thenReturn(KeyguardSecurityModel.SecurityMode.None); DejankUtils.setImmediate(true); final ViewGroup container = new FrameLayout(getContext()); when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver); @@ -306,14 +311,6 @@ public class KeyguardBouncerTest extends SysuiTestCase { } @Test - public void testNeedsFullscreenBouncer_asksKeyguardView() { - mBouncer.ensureView(); - mBouncer.needsFullscreenBouncer(); - verify(mKeyguardHostView).getSecurityMode(); - verify(mKeyguardHostView, never()).getCurrentSecurityMode(); - } - - @Test public void testIsFullscreenBouncer_asksKeyguardView() { mBouncer.ensureView(); mBouncer.isFullscreenBouncer(); diff --git a/tests/Codegen/runTest.sh b/tests/Codegen/runTest.sh index 614cbb7c9eb6..01522735ec3c 100755 --- a/tests/Codegen/runTest.sh +++ b/tests/Codegen/runTest.sh @@ -13,6 +13,7 @@ else header_and_eval m -j16 codegen_cli && \ header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java && \ header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java && \ + header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java && \ cd $ANDROID_BUILD_TOP && header_and_eval mmma -j16 frameworks/base/tests/Codegen && \ header_and_eval adb install -r -t $ANDROID_PRODUCT_OUT/testcases/CodegenTests/arm64/CodegenTests.apk && \ diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java new file mode 100644 index 000000000000..2d4125783990 --- /dev/null +++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2019 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 com.android.codegentest; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.SparseArray; +import android.util.SparseIntArray; + +import com.android.internal.util.AnnotationValidations; +import com.android.internal.util.DataClass; + +import java.util.List; +import java.util.Map; + +/** + * Additional test for various parcelling corner-cases. + */ +@DataClass( + genBuilder = true, + genAidl = false, + genToString = true) +public class ParcelAllTheThingsDataClass implements Parcelable { + + @NonNull String[] mStringArray = null; + @NonNull int[] mIntArray = null; + @NonNull List<String> mStringList = null; + + @NonNull Map<String, SampleWithCustomBuilder> mMap = null; + @NonNull Map<String, String> mStringMap = null; + + @NonNull SparseArray<SampleWithCustomBuilder> mSparseArray = null; + @NonNull SparseIntArray mSparseIntArray = null; + + + + // Code below generated by codegen v1.0.4. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java + + + @DataClass.Generated.Member + /* package-private */ ParcelAllTheThingsDataClass( + @NonNull String[] stringArray, + @NonNull int[] intArray, + @NonNull List<String> stringList, + @NonNull Map<String,SampleWithCustomBuilder> map, + @NonNull Map<String,String> stringMap, + @NonNull SparseArray<SampleWithCustomBuilder> sparseArray, + @NonNull SparseIntArray sparseIntArray) { + this.mStringArray = stringArray; + AnnotationValidations.validate( + NonNull.class, null, mStringArray); + this.mIntArray = intArray; + AnnotationValidations.validate( + NonNull.class, null, mIntArray); + this.mStringList = stringList; + AnnotationValidations.validate( + NonNull.class, null, mStringList); + this.mMap = map; + AnnotationValidations.validate( + NonNull.class, null, mMap); + this.mStringMap = stringMap; + AnnotationValidations.validate( + NonNull.class, null, mStringMap); + this.mSparseArray = sparseArray; + AnnotationValidations.validate( + NonNull.class, null, mSparseArray); + this.mSparseIntArray = sparseIntArray; + AnnotationValidations.validate( + NonNull.class, null, mSparseIntArray); + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public @NonNull String[] getStringArray() { + return mStringArray; + } + + @DataClass.Generated.Member + public @NonNull int[] getIntArray() { + return mIntArray; + } + + @DataClass.Generated.Member + public @NonNull List<String> getStringList() { + return mStringList; + } + + @DataClass.Generated.Member + public @NonNull Map<String,SampleWithCustomBuilder> getMap() { + return mMap; + } + + @DataClass.Generated.Member + public @NonNull Map<String,String> getStringMap() { + return mStringMap; + } + + @DataClass.Generated.Member + public @NonNull SparseArray<SampleWithCustomBuilder> getSparseArray() { + return mSparseArray; + } + + @DataClass.Generated.Member + public @NonNull SparseIntArray getSparseIntArray() { + return mSparseIntArray; + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "ParcelAllTheThingsDataClass { " + + "stringArray = " + java.util.Arrays.toString(mStringArray) + ", " + + "intArray = " + java.util.Arrays.toString(mIntArray) + ", " + + "stringList = " + mStringList + ", " + + "map = " + mMap + ", " + + "stringMap = " + mStringMap + ", " + + "sparseArray = " + mSparseArray + ", " + + "sparseIntArray = " + mSparseIntArray + + " }"; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeStringArray(mStringArray); + dest.writeIntArray(mIntArray); + dest.writeStringList(mStringList); + dest.writeMap(mMap); + dest.writeMap(mStringMap); + dest.writeSparseArray(mSparseArray); + dest.writeSparseIntArray(mSparseIntArray); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<ParcelAllTheThingsDataClass> CREATOR + = new Parcelable.Creator<ParcelAllTheThingsDataClass>() { + @Override + public ParcelAllTheThingsDataClass[] newArray(int size) { + return new ParcelAllTheThingsDataClass[size]; + } + + @Override + @SuppressWarnings({"unchecked", "RedundantCast"}) + public ParcelAllTheThingsDataClass createFromParcel(Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + String[] stringArray = in.createStringArray(); + int[] intArray = in.createIntArray(); + List<String> stringList = new java.util.ArrayList<>(); + in.readStringList(stringList); + Map<String,SampleWithCustomBuilder> map = new java.util.LinkedHashMap<>(); + in.readMap(map, SampleWithCustomBuilder.class.getClassLoader()); + Map<String,String> stringMap = new java.util.LinkedHashMap<>(); + in.readMap(stringMap, String.class.getClassLoader()); + SparseArray<SampleWithCustomBuilder> sparseArray = (SparseArray) in.readSparseArray(SampleWithCustomBuilder.class.getClassLoader()); + SparseIntArray sparseIntArray = (SparseIntArray) in.readSparseIntArray(); + return new ParcelAllTheThingsDataClass( + stringArray, + intArray, + stringList, + map, + stringMap, + sparseArray, + sparseIntArray); + } + }; + + /** + * A builder for {@link ParcelAllTheThingsDataClass} + */ + @SuppressWarnings("WeakerAccess") + @DataClass.Generated.Member + public static class Builder { + + private @NonNull String[] mStringArray; + private @NonNull int[] mIntArray; + private @NonNull List<String> mStringList; + private @NonNull Map<String,SampleWithCustomBuilder> mMap; + private @NonNull Map<String,String> mStringMap; + private @NonNull SparseArray<SampleWithCustomBuilder> mSparseArray; + private @NonNull SparseIntArray mSparseIntArray; + + private long mBuilderFieldsSet = 0L; + + public Builder() { + } + + @DataClass.Generated.Member + public @NonNull Builder setStringArray(@NonNull String... value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x1; + mStringArray = value; + return this; + } + + @DataClass.Generated.Member + public @NonNull Builder setIntArray(@NonNull int... value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x2; + mIntArray = value; + return this; + } + + @DataClass.Generated.Member + public @NonNull Builder setStringList(@NonNull List<String> value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x4; + mStringList = value; + return this; + } + + /** @see #setStringList */ + @DataClass.Generated.Member + public @NonNull Builder addStringList(String value) { + // You can refine this method's name by providing item's singular name, e.g.: + // @DataClass.PluralOf("item")) mItems = ... + + if (mStringList == null) setStringList(new java.util.ArrayList<>()); + mStringList.add(value); + return this; + } + + @DataClass.Generated.Member + public @NonNull Builder setMap(@NonNull Map<String,SampleWithCustomBuilder> value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x8; + mMap = value; + return this; + } + + /** @see #setMap */ + @DataClass.Generated.Member + public @NonNull Builder addMap(String key, SampleWithCustomBuilder value) { + // You can refine this method's name by providing item's singular name, e.g.: + // @DataClass.PluralOf("item")) mItems = ... + + if (mMap == null) setMap(new java.util.LinkedHashMap()); + mMap.put(key, value); + return this; + } + + @DataClass.Generated.Member + public @NonNull Builder setStringMap(@NonNull Map<String,String> value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x10; + mStringMap = value; + return this; + } + + /** @see #setStringMap */ + @DataClass.Generated.Member + public @NonNull Builder addStringMap(String key, String value) { + // You can refine this method's name by providing item's singular name, e.g.: + // @DataClass.PluralOf("item")) mItems = ... + + if (mStringMap == null) setStringMap(new java.util.LinkedHashMap()); + mStringMap.put(key, value); + return this; + } + + @DataClass.Generated.Member + public @NonNull Builder setSparseArray(@NonNull SparseArray<SampleWithCustomBuilder> value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x20; + mSparseArray = value; + return this; + } + + @DataClass.Generated.Member + public @NonNull Builder setSparseIntArray(@NonNull SparseIntArray value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x40; + mSparseIntArray = value; + return this; + } + + /** Builds the instance. This builder should not be touched after calling this! */ + public ParcelAllTheThingsDataClass build() { + checkNotUsed(); + mBuilderFieldsSet |= 0x80; // Mark builder used + + if ((mBuilderFieldsSet & 0x1) == 0) { + mStringArray = null; + } + if ((mBuilderFieldsSet & 0x2) == 0) { + mIntArray = null; + } + if ((mBuilderFieldsSet & 0x4) == 0) { + mStringList = null; + } + if ((mBuilderFieldsSet & 0x8) == 0) { + mMap = null; + } + if ((mBuilderFieldsSet & 0x10) == 0) { + mStringMap = null; + } + if ((mBuilderFieldsSet & 0x20) == 0) { + mSparseArray = null; + } + if ((mBuilderFieldsSet & 0x40) == 0) { + mSparseIntArray = null; + } + ParcelAllTheThingsDataClass o = new ParcelAllTheThingsDataClass( + mStringArray, + mIntArray, + mStringList, + mMap, + mStringMap, + mSparseArray, + mSparseIntArray); + return o; + } + + private void checkNotUsed() { + if ((mBuilderFieldsSet & 0x80) != 0) { + throw new IllegalStateException( + "This Builder should not be reused. Use a new Builder instance instead"); + } + } + } + + @DataClass.Generated( + time = 1570139502128L, + codegenVersion = "1.0.4", + sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java", + inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)") + @Deprecated + private void __metadata() {} + +} diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java index 66c7d06d6ff4..0631f7ded8ae 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java +++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java @@ -342,7 +342,7 @@ public final class SampleDataClass implements Parcelable { - // Code below generated by codegen v1.0.3. + // Code below generated by codegen v1.0.4. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -1798,8 +1798,8 @@ public final class SampleDataClass implements Parcelable { } @DataClass.Generated( - time = 1569956013899L, - codegenVersion = "1.0.3", + time = 1570139500112L, + codegenVersion = "1.0.4", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java", inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_UNDEFINED\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)") @Deprecated diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java index 663620743af9..c7a773530963 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java +++ b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java @@ -25,9 +25,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; +import static java.util.concurrent.TimeUnit.SECONDS; + import android.net.LinkAddress; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import android.util.SparseArray; +import android.util.SparseIntArray; import androidx.test.runner.AndroidJUnit4; @@ -36,6 +41,9 @@ import org.junit.runner.RunWith; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** @@ -209,6 +217,32 @@ public class SampleDataClassTest { newBuilder().setDayOfWeek(42).build(); } + @Test + public void testDataStructures_parcelCorrectly() { + SampleWithCustomBuilder otherParcelable = new SampleWithCustomBuilder.Builder().setDelay(3, SECONDS).build(); + + ParcelAllTheThingsDataClass instance = new ParcelAllTheThingsDataClass.Builder() + .setIntArray(40, 41) + .addMap("foo", otherParcelable) + .setSparseArray(new SparseArray<SampleWithCustomBuilder>() {{ + put(45, otherParcelable); + }}) + .setSparseIntArray(new SparseIntArray() {{ + put(48, 49); + }}) + .addStringMap("foo2", "fooValue") + .setStringArray("foo", "bar") + .addStringList("foo") + .build(); + + ParcelAllTheThingsDataClass unparceledInstance = + parcelAndUnparcel(instance, ParcelAllTheThingsDataClass.CREATOR); + + // SparseArray and friends don't implement equals + // so just compare string representations instead + assertEquals(instance.toString(), unparceledInstance.toString()); + } + private static <T extends Parcelable> T parcelAndUnparcel( T original, Parcelable.Creator<T> creator) { Parcel p = Parcel.obtain(); diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java index c6bc8de3bb9e..0f8c663f5d4b 100644 --- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java +++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java @@ -17,14 +17,16 @@ package com.android.codegentest; import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; import android.os.SystemClock; import com.android.internal.util.DataClass; import java.util.concurrent.TimeUnit; -@DataClass(genBuilder = true) -public class SampleWithCustomBuilder { +@DataClass(genBuilder = true, genAidl = false, genToString = true) +public class SampleWithCustomBuilder implements Parcelable { long delayAmount = 0; @NonNull @@ -73,8 +75,17 @@ public class SampleWithCustomBuilder { } + private static TimeUnit unparcelDelayUnit(Parcel p) { + return TimeUnit.values()[p.readInt()]; + } + + private void parcelDelayUnit(Parcel p, int flags) { + p.writeInt(delayUnit.ordinal()); + } - // Code below generated by codegen v1.0.3. + + + // Code below generated by codegen v1.0.4. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -112,6 +123,58 @@ public class SampleWithCustomBuilder { return creationTimestamp; } + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "SampleWithCustomBuilder { " + + "delayAmount = " + delayAmount + ", " + + "delayUnit = " + delayUnit + ", " + + "creationTimestamp = " + creationTimestamp + + " }"; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeLong(delayAmount); + parcelDelayUnit(dest, flags); + dest.writeLong(creationTimestamp); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<SampleWithCustomBuilder> CREATOR + = new Parcelable.Creator<SampleWithCustomBuilder>() { + @Override + public SampleWithCustomBuilder[] newArray(int size) { + return new SampleWithCustomBuilder[size]; + } + + @Override + @SuppressWarnings({"unchecked", "RedundantCast"}) + public SampleWithCustomBuilder createFromParcel(Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + long _delayAmount = in.readLong(); + TimeUnit _delayUnit = unparcelDelayUnit(in); + long _creationTimestamp = in.readLong(); + return new SampleWithCustomBuilder( + _delayAmount, + _delayUnit, + _creationTimestamp); + } + }; + /** * A builder for {@link SampleWithCustomBuilder} */ @@ -176,10 +239,10 @@ public class SampleWithCustomBuilder { } @DataClass.Generated( - time = 1569956014908L, - codegenVersion = "1.0.3", + time = 1570139501160L, + codegenVersion = "1.0.4", sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java", - inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nclass SampleWithCustomBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []") + inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nprivate static java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []") @Deprecated private void __metadata() {} diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt index 914e475cfe41..865340566019 100644 --- a/tools/codegen/src/com/android/codegen/Generators.kt +++ b/tools/codegen/src/com/android/codegen/Generators.kt @@ -341,7 +341,7 @@ private fun ClassPrinter.generateBuilderSetters(visibility: String) { } } - if (Type.contains("Map<")) { + if (FieldClass.endsWith("Map") && FieldInnerType != null) { generateBuilderMethod( name = adderName, defVisibility = visibility, @@ -533,7 +533,7 @@ fun ClassPrinter.generateParcelable() { } else if (Type !in PRIMITIVE_TYPES + "String" + "Bundle" && (!isArray || FieldInnerType !in PRIMITIVE_TYPES + "String") && ParcelMethodsSuffix != "Parcelable") { - !"($Type) " + !"($FieldClass) " } } @@ -541,12 +541,15 @@ fun ClassPrinter.generateParcelable() { when { ParcelMethodsSuffix == "Parcelable" -> methodArgs += "$FieldClass.class.getClassLoader()" + ParcelMethodsSuffix == "SparseArray" -> + methodArgs += "$FieldInnerClass.class.getClassLoader()" ParcelMethodsSuffix == "TypedObject" -> methodArgs += "$FieldClass.CREATOR" ParcelMethodsSuffix == "TypedArray" -> methodArgs += "$FieldInnerClass.CREATOR" + ParcelMethodsSuffix == "Map" -> + methodArgs += "${fieldTypeGenegicArgs[1].substringBefore("<")}.class.getClassLoader()" ParcelMethodsSuffix.startsWith("Parcelable") - || FieldClass == "Map" || (isList || isArray) && FieldInnerType !in PRIMITIVE_TYPES + "String" -> methodArgs += "$FieldInnerClass.class.getClassLoader()" diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt index 1e3973eaa022..1cc7ef338cc3 100644 --- a/tools/codegen/src/com/android/codegen/SharedConstants.kt +++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt @@ -1,7 +1,7 @@ package com.android.codegen const val CODEGEN_NAME = "codegen" -const val CODEGEN_VERSION = "1.0.3" +const val CODEGEN_VERSION = "1.0.4" const val CANONICAL_BUILDER_CLASS = "Builder" const val BASE_BUILDER_CLASS = "BaseBuilder" |