diff options
67 files changed, 3 insertions, 6954 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index d828faa0..67d5bef3 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk | |||
@@ -57,6 +57,9 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/androi | |||
57 | $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/src/android/car/hardware/ICarDiagnostic*.java) | 57 | $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/src/android/car/hardware/ICarDiagnostic*.java) |
58 | $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.car7_intermediates/src/android/car/hardware/ICarDiagnostic*.java) | 58 | $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.car7_intermediates/src/android/car/hardware/ICarDiagnostic*.java) |
59 | 59 | ||
60 | $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.car7_intermediates/) | ||
61 | $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.car_intermediates/) | ||
62 | |||
60 | # ************************************************ | 63 | # ************************************************ |
61 | # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST | 64 | # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST |
62 | # ************************************************ | 65 | # ************************************************ |
diff --git a/car-lib/src/android/car/Car.java b/car-lib/src/android/car/Car.java index c0b83f71..9a9e5312 100644 --- a/car-lib/src/android/car/Car.java +++ b/car-lib/src/android/car/Car.java | |||
@@ -32,7 +32,6 @@ import android.car.media.CarAudioManager; | |||
32 | import android.car.navigation.CarNavigationStatusManager; | 32 | import android.car.navigation.CarNavigationStatusManager; |
33 | import android.car.CarBluetoothManager; | 33 | import android.car.CarBluetoothManager; |
34 | import android.car.test.CarTestManagerBinderWrapper; | 34 | import android.car.test.CarTestManagerBinderWrapper; |
35 | import android.car.vms.VmsSubscriberManager; | ||
36 | import android.content.ComponentName; | 35 | import android.content.ComponentName; |
37 | import android.content.Context; | 36 | import android.content.Context; |
38 | import android.content.Intent; | 37 | import android.content.Intent; |
@@ -135,12 +134,6 @@ public final class Car { | |||
135 | public static final String BLUETOOTH_SERVICE = "car_bluetooth"; | 134 | public static final String BLUETOOTH_SERVICE = "car_bluetooth"; |
136 | 135 | ||
137 | /** | 136 | /** |
138 | * @FutureFeature Cannot drop due to usage in non-flag protected place. | ||
139 | * @hide | ||
140 | */ | ||
141 | public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service"; | ||
142 | |||
143 | /** | ||
144 | * Service for testing. This is system app only feature. | 137 | * Service for testing. This is system app only feature. |
145 | * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}. | 138 | * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}. |
146 | * @hide | 139 | * @hide |
@@ -261,22 +254,6 @@ public final class Car { | |||
261 | "android.car.permission.CAR_TEST_SERVICE"; | 254 | "android.car.permission.CAR_TEST_SERVICE"; |
262 | 255 | ||
263 | /** | 256 | /** |
264 | * Permissions necessary to access VMS publisher APIs. | ||
265 | * | ||
266 | * @hide | ||
267 | */ | ||
268 | @FutureFeature | ||
269 | public static final String PERMISSION_VMS_PUBLISHER = "android.car.permission.VMS_PUBLISHER"; | ||
270 | |||
271 | /** | ||
272 | * Permissions necessary to access VMS subscriber APIs. | ||
273 | * | ||
274 | * @hide | ||
275 | */ | ||
276 | @FutureFeature | ||
277 | public static final String PERMISSION_VMS_SUBSCRIBER = "android.car.permission.VMS_SUBSCRIBER"; | ||
278 | |||
279 | /** | ||
280 | * Permissions necessary to read diagnostic information, including vendor-specific bits. | 257 | * Permissions necessary to read diagnostic information, including vendor-specific bits. |
281 | * | 258 | * |
282 | * @hide | 259 | * @hide |
@@ -654,11 +631,6 @@ public final class Car { | |||
654 | * only pass binder wrapper so that CarTestManager can be constructed outside. */ | 631 | * only pass binder wrapper so that CarTestManager can be constructed outside. */ |
655 | manager = new CarTestManagerBinderWrapper(binder); | 632 | manager = new CarTestManagerBinderWrapper(binder); |
656 | break; | 633 | break; |
657 | case VMS_SUBSCRIBER_SERVICE: | ||
658 | if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
659 | manager = new VmsSubscriberManager(binder, mEventHandler); | ||
660 | } | ||
661 | break; | ||
662 | case BLUETOOTH_SERVICE: | 634 | case BLUETOOTH_SERVICE: |
663 | manager = new CarBluetoothManager(binder, mContext); | 635 | manager = new CarBluetoothManager(binder, mContext); |
664 | } | 636 | } |
diff --git a/car-lib/src/android/car/vms/IVmsPublisherClient.aidl b/car-lib/src/android/car/vms/IVmsPublisherClient.aidl deleted file mode 100644 index 96b993b3..00000000 --- a/car-lib/src/android/car/vms/IVmsPublisherClient.aidl +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.vms.IVmsPublisherService; | ||
20 | import android.car.vms.VmsSubscriptionState; | ||
21 | |||
22 | /** | ||
23 | * @hide | ||
24 | */ | ||
25 | interface IVmsPublisherClient { | ||
26 | /** | ||
27 | * Once the VmsPublisherService is bound to the client, this callback is used to set the | ||
28 | * binder that the client can use to invoke publisher services. This also gives the client | ||
29 | * the token it should use when calling the service. | ||
30 | */ | ||
31 | oneway void setVmsPublisherService(in IBinder token, IVmsPublisherService service) = 0; | ||
32 | |||
33 | /** | ||
34 | * The VmsPublisherService uses this callback to notify about subscription changes. | ||
35 | * @param subscriptionState all the layers that have subscribers and a sequence number, | ||
36 | * clients should ignore any packet with a sequence number that is less | ||
37 | * than the highest sequence number they have seen thus far. | ||
38 | */ | ||
39 | oneway void onVmsSubscriptionChange(in VmsSubscriptionState subscriptionState) = 1; | ||
40 | } | ||
diff --git a/car-lib/src/android/car/vms/IVmsPublisherService.aidl b/car-lib/src/android/car/vms/IVmsPublisherService.aidl deleted file mode 100644 index 3c26a1b0..00000000 --- a/car-lib/src/android/car/vms/IVmsPublisherService.aidl +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.vms.VmsLayer; | ||
20 | import android.car.vms.VmsLayersOffering; | ||
21 | import android.car.vms.VmsSubscriptionState; | ||
22 | |||
23 | /** | ||
24 | * Exposes publisher services to VMS clients. | ||
25 | * | ||
26 | * @hide | ||
27 | */ | ||
28 | interface IVmsPublisherService { | ||
29 | /** | ||
30 | * Client call to publish a message. | ||
31 | */ | ||
32 | oneway void publish(in IBinder token, in VmsLayer layer, int publisherId, in byte[] message) = 0; | ||
33 | |||
34 | /** | ||
35 | * Returns the list of VmsLayers that has any clients subscribed to it. | ||
36 | */ | ||
37 | VmsSubscriptionState getSubscriptions() = 1; | ||
38 | |||
39 | /** | ||
40 | * Sets which layers the publisher can publish under which dependencties. | ||
41 | */ | ||
42 | oneway void setLayersOffering(in IBinder token, in VmsLayersOffering offering) = 2; | ||
43 | |||
44 | /** | ||
45 | * The first time a publisher calls this API it will store the publisher info and assigns the | ||
46 | * publisher an ID. Between reboots, subsequent calls with the same publisher info will | ||
47 | * return the same ID so that a restarting process can obtain the same ID as it had before. | ||
48 | */ | ||
49 | int getPublisherId(in byte[] publisherInfo) = 3; | ||
50 | } | ||
diff --git a/car-lib/src/android/car/vms/IVmsSubscriberClient.aidl b/car-lib/src/android/car/vms/IVmsSubscriberClient.aidl deleted file mode 100644 index d5b56060..00000000 --- a/car-lib/src/android/car/vms/IVmsSubscriberClient.aidl +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.vms.VmsAssociatedLayer; | ||
20 | import android.car.vms.VmsLayer; | ||
21 | |||
22 | /** | ||
23 | * @hide | ||
24 | */ | ||
25 | oneway interface IVmsSubscriberClient { | ||
26 | /** | ||
27 | * A VmsService uses this callback to pass messages to subscribers. | ||
28 | */ | ||
29 | void onVmsMessageReceived(in VmsLayer layer, in byte[] payload) = 0; | ||
30 | |||
31 | void onLayersAvailabilityChanged(in List<VmsAssociatedLayer> availableLayers) = 1; | ||
32 | } | ||
diff --git a/car-lib/src/android/car/vms/IVmsSubscriberService.aidl b/car-lib/src/android/car/vms/IVmsSubscriberService.aidl deleted file mode 100644 index d10a6e47..00000000 --- a/car-lib/src/android/car/vms/IVmsSubscriberService.aidl +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.vms.IVmsSubscriberClient; | ||
20 | import android.car.vms.VmsLayer; | ||
21 | |||
22 | /** | ||
23 | * @hide | ||
24 | */ | ||
25 | interface IVmsSubscriberService { | ||
26 | /** | ||
27 | * Adds a subscriber to notifications only. | ||
28 | * Should be called when a subscriber registers its callback, and before any subscription to a | ||
29 | * layer is made. | ||
30 | */ | ||
31 | void addVmsSubscriberToNotifications( | ||
32 | in IVmsSubscriberClient subscriber) = 0; | ||
33 | |||
34 | /** | ||
35 | * Adds a subscriber to a VMS layer. | ||
36 | */ | ||
37 | void addVmsSubscriber( | ||
38 | in IVmsSubscriberClient subscriber, | ||
39 | in VmsLayer layer) = 1; | ||
40 | |||
41 | /** | ||
42 | * Adds a subscriber to all actively broadcasted layers. | ||
43 | * Publishers will not be notified regarding this request so the state of the service will not | ||
44 | * change. | ||
45 | */ | ||
46 | void addVmsSubscriberPassive(in IVmsSubscriberClient subscriber) = 2; | ||
47 | |||
48 | /** | ||
49 | * Adds a subscriber to a VMS layer from a specific publisher. | ||
50 | */ | ||
51 | void addVmsSubscriberToPublisher( | ||
52 | in IVmsSubscriberClient subscriber, | ||
53 | in VmsLayer layer, | ||
54 | int publisherId) = 3; | ||
55 | |||
56 | /** | ||
57 | Â Â * Removes a subscriber to notifications only. | ||
58 | * Should be called when a subscriber unregisters its callback, and after all subscriptions to | ||
59 | * layers are removed. | ||
60 | Â Â */ | ||
61 | void removeVmsSubscriberToNotifications( | ||
62 | in IVmsSubscriberClient subscriber) = 4; | ||
63 | |||
64 | /** | ||
65 | Â Â * Removes a subscriber to a VMS layer. | ||
66 | Â Â */ | ||
67 | void removeVmsSubscriber( | ||
68 | in IVmsSubscriberClient subscriber, | ||
69 | in VmsLayer layer) = 5; | ||
70 | |||
71 | /** | ||
72 | * Removes a subscriber to all actively broadcasted layers. | ||
73 | * Publishers will not be notified regarding this request so the state of the service will not | ||
74 | * change. | ||
75 | */ | ||
76 | void removeVmsSubscriberPassive( | ||
77 | in IVmsSubscriberClient subscriber) = 6; | ||
78 | |||
79 | /** | ||
80 | * Removes a subscriber to a VMS layer from a specific publisher. | ||
81 | */ | ||
82 | void removeVmsSubscriberToPublisher( | ||
83 | in IVmsSubscriberClient subscriber, | ||
84 | in VmsLayer layer, | ||
85 | int publisherId) = 7; | ||
86 | |||
87 | /** | ||
88 | * Returns a list of available layers from the closure of the publishers offerings. | ||
89 | */ | ||
90 | List<VmsLayer> getAvailableLayers() = 8; | ||
91 | |||
92 | /** | ||
93 | * Returns a the publisher information for a publisher ID. | ||
94 | */ | ||
95 | byte[] getPublisherInfo(in int publisherId) = 9; | ||
96 | } | ||
diff --git a/car-lib/src/android/car/vms/VmsAssociatedLayer.aidl b/car-lib/src/android/car/vms/VmsAssociatedLayer.aidl deleted file mode 100644 index c2cf2715..00000000 --- a/car-lib/src/android/car/vms/VmsAssociatedLayer.aidl +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | parcelable VmsAssociatedLayer; \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsAssociatedLayer.java b/car-lib/src/android/car/vms/VmsAssociatedLayer.java deleted file mode 100644 index 023fd9cb..00000000 --- a/car-lib/src/android/car/vms/VmsAssociatedLayer.java +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.os.Parcel; | ||
21 | import android.os.Parcelable; | ||
22 | |||
23 | import java.util.*; | ||
24 | |||
25 | /** | ||
26 | * A VMS Layer with a list of publisher IDs it is associated with. | ||
27 | * | ||
28 | * @hide | ||
29 | */ | ||
30 | @FutureFeature | ||
31 | public final class VmsAssociatedLayer implements Parcelable { | ||
32 | |||
33 | // The VmsLayer. | ||
34 | private final VmsLayer mLayer; | ||
35 | |||
36 | // The IDs of the publishers that can publish this VmsLayer. | ||
37 | private final Set<Integer> mPublisherIds; | ||
38 | |||
39 | public VmsAssociatedLayer(VmsLayer layer, Set<Integer> publisherIds) { | ||
40 | mLayer = layer; | ||
41 | mPublisherIds = Collections.unmodifiableSet(publisherIds); | ||
42 | } | ||
43 | |||
44 | public VmsLayer getVmsLayer() { | ||
45 | return mLayer; | ||
46 | } | ||
47 | |||
48 | public Set<Integer> getPublisherIds() { | ||
49 | return mPublisherIds; | ||
50 | } | ||
51 | |||
52 | @Override | ||
53 | public String toString() { | ||
54 | return "VmsAssociatedLayer{ VmsLayer: " + mLayer + ", Publishers: " + mPublisherIds + "}"; | ||
55 | } | ||
56 | |||
57 | // Parcelable related methods. | ||
58 | public static final Parcelable.Creator<VmsAssociatedLayer> CREATOR = | ||
59 | new Parcelable.Creator<VmsAssociatedLayer>() { | ||
60 | public VmsAssociatedLayer createFromParcel(Parcel in) { | ||
61 | return new VmsAssociatedLayer(in); | ||
62 | } | ||
63 | |||
64 | public VmsAssociatedLayer[] newArray(int size) { | ||
65 | return new VmsAssociatedLayer[size]; | ||
66 | } | ||
67 | }; | ||
68 | |||
69 | @Override | ||
70 | public void writeToParcel(Parcel out, int flags) { | ||
71 | out.writeParcelable(mLayer, flags); | ||
72 | out.writeArray(mPublisherIds.toArray()); | ||
73 | } | ||
74 | |||
75 | @Override | ||
76 | public boolean equals(Object o) { | ||
77 | if (!(o instanceof VmsAssociatedLayer)) { | ||
78 | return false; | ||
79 | } | ||
80 | VmsAssociatedLayer p = (VmsAssociatedLayer) o; | ||
81 | return Objects.equals(p.mLayer, mLayer) && p.mPublisherIds.equals(mPublisherIds); | ||
82 | } | ||
83 | |||
84 | @Override | ||
85 | public int describeContents() { | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | @Override | ||
90 | public int hashCode() { | ||
91 | return Objects.hash(mLayer, mPublisherIds); | ||
92 | } | ||
93 | |||
94 | private VmsAssociatedLayer(Parcel in) { | ||
95 | mLayer = in.readParcelable(VmsLayer.class.getClassLoader()); | ||
96 | |||
97 | mPublisherIds = Collections.unmodifiableSet( | ||
98 | new HashSet<>(Arrays.asList( | ||
99 | (Integer[]) in.readArray(Integer.class.getClassLoader())))); | ||
100 | } | ||
101 | } \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsLayer.aidl b/car-lib/src/android/car/vms/VmsLayer.aidl deleted file mode 100644 index ff0768a3..00000000 --- a/car-lib/src/android/car/vms/VmsLayer.aidl +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | parcelable VmsLayer; \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsLayer.java b/car-lib/src/android/car/vms/VmsLayer.java deleted file mode 100644 index 9125796e..00000000 --- a/car-lib/src/android/car/vms/VmsLayer.java +++ /dev/null | |||
@@ -1,126 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.os.Parcel; | ||
21 | import android.os.Parcelable; | ||
22 | |||
23 | import java.util.Objects; | ||
24 | |||
25 | /** | ||
26 | * A VMS Layer which can be subscribed to by VMS clients. | ||
27 | * | ||
28 | * @hide | ||
29 | */ | ||
30 | @FutureFeature | ||
31 | public final class VmsLayer implements Parcelable { | ||
32 | |||
33 | // The layer Type. | ||
34 | private int mType; | ||
35 | |||
36 | // The layer Subtype. | ||
37 | private int mSubtype; | ||
38 | |||
39 | // The layer version. | ||
40 | private int mVersion; | ||
41 | |||
42 | public VmsLayer(int type, int subtype, int version) { | ||
43 | mType = type; | ||
44 | mSubtype = subtype; | ||
45 | mVersion = version; | ||
46 | } | ||
47 | |||
48 | public int getType() { | ||
49 | return mType; | ||
50 | } | ||
51 | |||
52 | public int getSubtype() { | ||
53 | return mSubtype; | ||
54 | } | ||
55 | |||
56 | public int getVersion() { | ||
57 | return mVersion; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * Checks the two objects for equality by comparing their IDs and Versions. | ||
62 | * | ||
63 | * @param o the {@link VmsLayer} to which this one is to be checked for equality | ||
64 | * @return true if the underlying objects of the VmsLayer are both considered equal | ||
65 | */ | ||
66 | @Override | ||
67 | public boolean equals(Object o) { | ||
68 | if (!(o instanceof VmsLayer)) { | ||
69 | return false; | ||
70 | } | ||
71 | VmsLayer p = (VmsLayer) o; | ||
72 | return Objects.equals(p.mType, mType) && | ||
73 | Objects.equals(p.mSubtype, mSubtype) && | ||
74 | Objects.equals(p.mVersion, mVersion); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * Compute a hash code similarly tp {@link android.util.Pair} | ||
79 | * | ||
80 | * @return a hashcode of the Pair | ||
81 | */ | ||
82 | @Override | ||
83 | public int hashCode() { | ||
84 | return Objects.hash(mType, mSubtype, mVersion); | ||
85 | } | ||
86 | |||
87 | @Override | ||
88 | public String toString() { | ||
89 | return "VmsLayer{ Type: " + mType + ", Sub type: " + mSubtype + ", Version: " + mVersion + "}"; | ||
90 | } | ||
91 | |||
92 | |||
93 | // Parcelable related methods. | ||
94 | public static final Parcelable.Creator<VmsLayer> CREATOR = new | ||
95 | Parcelable.Creator<VmsLayer>() { | ||
96 | public VmsLayer createFromParcel(Parcel in) { | ||
97 | return new VmsLayer(in); | ||
98 | } | ||
99 | |||
100 | public VmsLayer[] newArray(int size) { | ||
101 | return new VmsLayer[size]; | ||
102 | } | ||
103 | }; | ||
104 | |||
105 | @Override | ||
106 | public void writeToParcel(Parcel out, int flags) { | ||
107 | out.writeInt(mType); | ||
108 | out.writeInt(mSubtype); | ||
109 | out.writeInt(mVersion); | ||
110 | } | ||
111 | |||
112 | @Override | ||
113 | public int describeContents() { | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | private VmsLayer(Parcel in) { | ||
118 | readFromParcel(in); | ||
119 | } | ||
120 | |||
121 | private void readFromParcel(Parcel in) { | ||
122 | mType = in.readInt(); | ||
123 | mSubtype = in.readInt(); | ||
124 | mVersion = in.readInt(); | ||
125 | } | ||
126 | } \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsLayerDependency.aidl b/car-lib/src/android/car/vms/VmsLayerDependency.aidl deleted file mode 100644 index 3e64001b..00000000 --- a/car-lib/src/android/car/vms/VmsLayerDependency.aidl +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | parcelable VmsLayerDependency; \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsLayerDependency.java b/car-lib/src/android/car/vms/VmsLayerDependency.java deleted file mode 100644 index 3b82775a..00000000 --- a/car-lib/src/android/car/vms/VmsLayerDependency.java +++ /dev/null | |||
@@ -1,97 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.os.Parcel; | ||
21 | import android.os.Parcelable; | ||
22 | import java.util.ArrayList; | ||
23 | import java.util.Arrays; | ||
24 | import java.util.Collections; | ||
25 | import java.util.HashSet; | ||
26 | import java.util.List; | ||
27 | import java.util.Set; | ||
28 | |||
29 | /** | ||
30 | * A dependency for a VMS layer on other VMS layers. | ||
31 | * | ||
32 | * @hide | ||
33 | */ | ||
34 | @FutureFeature | ||
35 | public final class VmsLayerDependency implements Parcelable { | ||
36 | private final VmsLayer mLayer; | ||
37 | private final Set<VmsLayer> mDependency; | ||
38 | |||
39 | /** | ||
40 | * Construct a dependency for layer on other layers. | ||
41 | */ | ||
42 | public VmsLayerDependency(VmsLayer layer, Set<VmsLayer> dependencies) { | ||
43 | mLayer = layer; | ||
44 | mDependency = Collections.unmodifiableSet(dependencies); | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Constructs a layer without a dependency. | ||
49 | */ | ||
50 | public VmsLayerDependency(VmsLayer layer) { | ||
51 | mLayer = layer; | ||
52 | mDependency = Collections.emptySet(); | ||
53 | } | ||
54 | |||
55 | public VmsLayer getLayer() { | ||
56 | return mLayer; | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Returns the dependencies. | ||
61 | */ | ||
62 | public Set<VmsLayer> getDependencies() { | ||
63 | return mDependency; | ||
64 | } | ||
65 | |||
66 | public static final Parcelable.Creator<VmsLayerDependency> CREATOR = new | ||
67 | Parcelable.Creator<VmsLayerDependency>() { | ||
68 | public VmsLayerDependency createFromParcel(Parcel in) { | ||
69 | return new VmsLayerDependency(in); | ||
70 | } | ||
71 | public VmsLayerDependency[] newArray(int size) { | ||
72 | return new VmsLayerDependency[size]; | ||
73 | } | ||
74 | }; | ||
75 | |||
76 | public String toString() { | ||
77 | return "VmsLayerDependency{ Layer: " + mLayer + " Dependency: " + mDependency + "}"; | ||
78 | } | ||
79 | |||
80 | @Override | ||
81 | public void writeToParcel(Parcel out, int flags) { | ||
82 | out.writeParcelable(mLayer, flags); | ||
83 | out.writeParcelableList(new ArrayList<VmsLayer>(mDependency), flags); | ||
84 | } | ||
85 | |||
86 | @Override | ||
87 | public int describeContents() { | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | private VmsLayerDependency(Parcel in) { | ||
92 | mLayer = in.readParcelable(VmsLayer.class.getClassLoader()); | ||
93 | List<VmsLayer> dependency = new ArrayList<>(); | ||
94 | in.readParcelableList(dependency, VmsLayer.class.getClassLoader()); | ||
95 | mDependency = Collections.unmodifiableSet(new HashSet<VmsLayer>(dependency)); | ||
96 | } | ||
97 | } \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsLayersOffering.aidl b/car-lib/src/android/car/vms/VmsLayersOffering.aidl deleted file mode 100644 index 4231f2da..00000000 --- a/car-lib/src/android/car/vms/VmsLayersOffering.aidl +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | parcelable VmsLayersOffering; \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsLayersOffering.java b/car-lib/src/android/car/vms/VmsLayersOffering.java deleted file mode 100644 index 6abffc60..00000000 --- a/car-lib/src/android/car/vms/VmsLayersOffering.java +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.os.Parcel; | ||
21 | import android.os.Parcelable; | ||
22 | import java.util.ArrayList; | ||
23 | import java.util.Collections; | ||
24 | import java.util.HashSet; | ||
25 | import java.util.List; | ||
26 | import java.util.Set; | ||
27 | |||
28 | /** | ||
29 | * The state of dependencies for a single publisher. | ||
30 | * | ||
31 | * @hide | ||
32 | */ | ||
33 | @FutureFeature | ||
34 | public final class VmsLayersOffering implements Parcelable { | ||
35 | |||
36 | private final Set<VmsLayerDependency> mDependencies; | ||
37 | |||
38 | private final int mPublisherId; | ||
39 | |||
40 | public VmsLayersOffering(Set<VmsLayerDependency> dependencies, int publisherId) { | ||
41 | mDependencies = Collections.unmodifiableSet(dependencies); | ||
42 | mPublisherId = publisherId; | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * Returns the dependencies. | ||
47 | */ | ||
48 | public Set<VmsLayerDependency> getDependencies() { | ||
49 | return mDependencies; | ||
50 | } | ||
51 | |||
52 | public int getPublisherId() { | ||
53 | return mPublisherId; | ||
54 | } | ||
55 | |||
56 | public static final Parcelable.Creator<VmsLayersOffering> CREATOR = new | ||
57 | Parcelable.Creator<VmsLayersOffering>() { | ||
58 | public VmsLayersOffering createFromParcel(Parcel in) { | ||
59 | return new VmsLayersOffering(in); | ||
60 | } | ||
61 | public VmsLayersOffering[] newArray(int size) { | ||
62 | return new VmsLayersOffering[size]; | ||
63 | } | ||
64 | }; | ||
65 | |||
66 | @Override | ||
67 | public String toString() { | ||
68 | return "VmsLayersOffering{" + mDependencies+ "}"; | ||
69 | } | ||
70 | |||
71 | @Override | ||
72 | public void writeToParcel(Parcel out, int flags) { | ||
73 | |||
74 | out.writeParcelableList(new ArrayList(mDependencies), flags); | ||
75 | out.writeInt(mPublisherId); | ||
76 | } | ||
77 | |||
78 | @Override | ||
79 | public int describeContents() { | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | private VmsLayersOffering(Parcel in) { | ||
84 | List<VmsLayerDependency> dependencies = new ArrayList<>(); | ||
85 | in.readParcelableList(dependencies, VmsLayerDependency.class.getClassLoader()); | ||
86 | mDependencies = Collections.unmodifiableSet(new HashSet<>(dependencies)); | ||
87 | mPublisherId = in.readInt(); | ||
88 | } | ||
89 | } \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsOperationRecorder.java b/car-lib/src/android/car/vms/VmsOperationRecorder.java deleted file mode 100644 index c873dce1..00000000 --- a/car-lib/src/android/car/vms/VmsOperationRecorder.java +++ /dev/null | |||
@@ -1,227 +0,0 @@ | |||
1 | package android.car.vms; | ||
2 | |||
3 | import android.car.annotation.FutureFeature; | ||
4 | import android.util.Log; | ||
5 | |||
6 | import com.android.internal.annotations.VisibleForTesting; | ||
7 | |||
8 | import org.json.JSONArray; | ||
9 | import org.json.JSONException; | ||
10 | import org.json.JSONObject; | ||
11 | |||
12 | /** | ||
13 | * Records VMS operations using the Android Log. | ||
14 | * | ||
15 | * This class records VMS operations. The recorded messages include the VMS operations and its | ||
16 | * arguments encoded as JSON text so that the string can be both read as a log message and easily | ||
17 | * parsed. VmsOperationRecorder is intended to be called after successful state change. | ||
18 | * | ||
19 | * Access the VmsOperationRecorder using the {@link #get()} method, which returns a singleton | ||
20 | * instance. Each VMS operation has a corresponding VmsOperationRecorder method. For instance: | ||
21 | * <pre>{@code | ||
22 | * VmsOperationRecorder.get().subscribe(layer); | ||
23 | * }</pre> | ||
24 | * | ||
25 | * @hide | ||
26 | */ | ||
27 | @FutureFeature | ||
28 | public final class VmsOperationRecorder { | ||
29 | private static final String TAG = "VmsOperationRecorder"; | ||
30 | private static final VmsOperationRecorder INSTANCE = new VmsOperationRecorder(new Writer()); | ||
31 | private final Writer mWriter; | ||
32 | |||
33 | @VisibleForTesting | ||
34 | public VmsOperationRecorder(Writer writer) { | ||
35 | mWriter = writer; | ||
36 | } | ||
37 | |||
38 | /** Return the singleton instance. */ | ||
39 | public static VmsOperationRecorder get() { | ||
40 | return INSTANCE; | ||
41 | } | ||
42 | |||
43 | // VMS Client operations. | ||
44 | |||
45 | public void subscribe(VmsLayer layer) { | ||
46 | recordOp("subscribe", layer); | ||
47 | } | ||
48 | |||
49 | public void unsubscribe(VmsLayer layer) { | ||
50 | recordOp("unsubscribe", layer); | ||
51 | } | ||
52 | |||
53 | public void subscribe(VmsLayer layer, int publisherId) { | ||
54 | recordOp("subscribe", "publisherId", publisherId, layer); | ||
55 | } | ||
56 | |||
57 | public void unsubscribe(VmsLayer layer, int publisherId) { | ||
58 | recordOp("unsubscribe", "publisherId", publisherId, layer); | ||
59 | } | ||
60 | |||
61 | public void startMonitoring() { | ||
62 | recordOp("startMonitoring"); | ||
63 | } | ||
64 | |||
65 | public void stopMonitoring() { | ||
66 | recordOp("stopMonitoring"); | ||
67 | } | ||
68 | |||
69 | public void setLayersOffering(VmsLayersOffering layersOffering) { | ||
70 | recordOp("setLayersOffering", layersOffering); | ||
71 | } | ||
72 | |||
73 | public void getPublisherId(int publisherId) { | ||
74 | recordOp("getPublisherId", "publisherId", publisherId); | ||
75 | } | ||
76 | |||
77 | // VMS Service operations. | ||
78 | |||
79 | public void addSubscription(int sequenceNumber, VmsLayer layer) { | ||
80 | recordOp("addSubscription", "sequenceNumber", sequenceNumber, layer); | ||
81 | } | ||
82 | |||
83 | public void removeSubscription(int sequenceNumber, VmsLayer layer) { | ||
84 | recordOp("removeSubscription", "sequenceNumber", sequenceNumber, layer); | ||
85 | } | ||
86 | |||
87 | public void addPromiscuousSubscription(int sequenceNumber) { | ||
88 | recordOp("addPromiscuousSubscription", "sequenceNumber", sequenceNumber); | ||
89 | } | ||
90 | |||
91 | public void removePromiscuousSubscription(int sequenceNumber) { | ||
92 | recordOp("removePromiscuousSubscription", "sequenceNumber", sequenceNumber); | ||
93 | } | ||
94 | |||
95 | public void addHalSubscription(int sequenceNumber, VmsLayer layer) { | ||
96 | recordOp("addHalSubscription", "sequenceNumber", sequenceNumber, layer); | ||
97 | } | ||
98 | |||
99 | public void removeHalSubscription(int sequenceNumber, VmsLayer layer) { | ||
100 | recordOp("removeHalSubscription", "sequenceNumber", sequenceNumber, layer); | ||
101 | } | ||
102 | |||
103 | public void setPublisherLayersOffering(VmsLayersOffering layersOffering) { | ||
104 | recordOp("setPublisherLayersOffering", layersOffering); | ||
105 | } | ||
106 | |||
107 | public void setHalPublisherLayersOffering(VmsLayersOffering layersOffering) { | ||
108 | recordOp("setHalPublisherLayersOffering", layersOffering); | ||
109 | } | ||
110 | |||
111 | private void recordOp(String operation) { | ||
112 | if (isEnabled()) { | ||
113 | try { | ||
114 | write(new JSONObject().put(operation, new JSONObject())); | ||
115 | } catch (JSONException e) { | ||
116 | Log.e(TAG, e.toString()); | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | private void recordOp(String operation, VmsLayer layer) { | ||
122 | if (isEnabled()) { | ||
123 | try { | ||
124 | recordOp(operation, new JSONObject().put("layer", toJson(layer))); | ||
125 | } catch (JSONException e) { | ||
126 | Log.e(TAG, e.toString()); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | private void recordOp(String operation, VmsLayersOffering layersOffering) { | ||
132 | if (isEnabled()) { | ||
133 | try { | ||
134 | JSONObject args = new JSONObject(); | ||
135 | JSONArray offering = toJson(layersOffering); | ||
136 | if (offering.length() > 0) { | ||
137 | args.put("layerDependency", offering); | ||
138 | } | ||
139 | recordOp(operation, args); | ||
140 | } catch (JSONException e) { | ||
141 | Log.e(TAG, e.toString()); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | private void recordOp(String operation, String intArgName, int arg) { | ||
147 | if (isEnabled()) { | ||
148 | try { | ||
149 | recordOp(operation, new JSONObject().put(intArgName, arg)); | ||
150 | } catch (JSONException e) { | ||
151 | Log.e(TAG, e.toString()); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | |||
156 | private void recordOp(String operation, String intArgName, int arg, VmsLayer layer) { | ||
157 | if (isEnabled()) { | ||
158 | try { | ||
159 | recordOp(operation, | ||
160 | new JSONObject().put(intArgName, arg).put("layer", toJson(layer))); | ||
161 | } catch (JSONException e) { | ||
162 | Log.e(TAG, e.toString()); | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | |||
167 | private void recordOp(String operation, JSONObject args) { | ||
168 | if (isEnabled()) { | ||
169 | try { | ||
170 | write(new JSONObject().put(operation, args)); | ||
171 | } catch (JSONException e) { | ||
172 | Log.e(TAG, e.toString()); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | private static JSONObject toJson(VmsLayer layer) throws JSONException { | ||
178 | return new JSONObject() | ||
179 | .put("type", layer.getType()) | ||
180 | .put("subtype", layer.getSubtype()) | ||
181 | .put("version", layer.getVersion()); | ||
182 | } | ||
183 | |||
184 | private static JSONObject toJson(VmsLayerDependency layerDependency) throws JSONException { | ||
185 | JSONObject dep = new JSONObject(); | ||
186 | dep.put("layer", toJson(layerDependency.getLayer())); | ||
187 | if (!layerDependency.getDependencies().isEmpty()) { | ||
188 | JSONArray dependencies = new JSONArray(); | ||
189 | for (VmsLayer dependency : layerDependency.getDependencies()) { | ||
190 | dependencies.put(toJson(dependency)); | ||
191 | } | ||
192 | dep.put("dependency", dependencies); | ||
193 | } | ||
194 | return dep; | ||
195 | } | ||
196 | |||
197 | private static JSONArray toJson(VmsLayersOffering layersOffering) throws JSONException { | ||
198 | JSONArray offerings = new JSONArray(); | ||
199 | for (VmsLayerDependency layerDependency : layersOffering.getDependencies()) { | ||
200 | offerings.put(toJson(layerDependency)); | ||
201 | } | ||
202 | return offerings; | ||
203 | } | ||
204 | |||
205 | private boolean isEnabled() { | ||
206 | return mWriter.isEnabled(); | ||
207 | } | ||
208 | |||
209 | private void write(JSONObject object) { | ||
210 | mWriter.write(object.toString()); | ||
211 | } | ||
212 | |||
213 | /** @hide */ | ||
214 | @VisibleForTesting | ||
215 | public static class Writer { | ||
216 | private static final String TAG = "VMS.RECORD.EVENT"; | ||
217 | private static final int LEVEL = Log.DEBUG; | ||
218 | |||
219 | public boolean isEnabled() { | ||
220 | return Log.isLoggable(TAG, LEVEL); | ||
221 | } | ||
222 | |||
223 | public void write(String msg) { | ||
224 | Log.println(LEVEL, TAG, msg); | ||
225 | } | ||
226 | } | ||
227 | } | ||
diff --git a/car-lib/src/android/car/vms/VmsPublisherClientService.java b/car-lib/src/android/car/vms/VmsPublisherClientService.java deleted file mode 100644 index 33ca1f30..00000000 --- a/car-lib/src/android/car/vms/VmsPublisherClientService.java +++ /dev/null | |||
@@ -1,282 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | |||
20 | import android.app.Service; | ||
21 | import android.car.annotation.FutureFeature; | ||
22 | import android.content.Intent; | ||
23 | import android.os.Handler; | ||
24 | import android.os.IBinder; | ||
25 | import android.os.Looper; | ||
26 | import android.os.Message; | ||
27 | import android.os.RemoteException; | ||
28 | import android.annotation.Nullable; | ||
29 | import android.util.Log; | ||
30 | |||
31 | import com.android.internal.annotations.GuardedBy; | ||
32 | |||
33 | import java.lang.ref.WeakReference; | ||
34 | |||
35 | /** | ||
36 | * Services that need VMS publisher services need to inherit from this class and also need to be | ||
37 | * declared in the array vmsPublisherClients located in | ||
38 | * packages/services/Car/service/res/values/config.xml (most likely, this file will be in an overlay | ||
39 | * of the target product. | ||
40 | * | ||
41 | * The {@link com.android.car.VmsPublisherService} will start this service. The callback | ||
42 | * {@link #onVmsPublisherServiceReady()} notifies when VMS publisher services can be used, and the | ||
43 | * publisher can request a publisher ID in order to start publishing. | ||
44 | * | ||
45 | * SystemApi candidate. | ||
46 | * | ||
47 | * @hide | ||
48 | */ | ||
49 | @FutureFeature | ||
50 | public abstract class VmsPublisherClientService extends Service { | ||
51 | private static final boolean DBG = true; | ||
52 | private static final String TAG = "VmsPublisherClient"; | ||
53 | |||
54 | private final Object mLock = new Object(); | ||
55 | |||
56 | private Handler mHandler = new VmsEventHandler(this); | ||
57 | private final VmsPublisherClientBinder mVmsPublisherClient = new VmsPublisherClientBinder(this); | ||
58 | private volatile IVmsPublisherService mVmsPublisherService = null; | ||
59 | @GuardedBy("mLock") | ||
60 | private IBinder mToken = null; | ||
61 | |||
62 | @Override | ||
63 | public final IBinder onBind(Intent intent) { | ||
64 | if (DBG) { | ||
65 | Log.d(TAG, "onBind, intent: " + intent); | ||
66 | } | ||
67 | return mVmsPublisherClient.asBinder(); | ||
68 | } | ||
69 | |||
70 | @Override | ||
71 | public final boolean onUnbind(Intent intent) { | ||
72 | if (DBG) { | ||
73 | Log.d(TAG, "onUnbind, intent: " + intent); | ||
74 | } | ||
75 | stopSelf(); | ||
76 | return super.onUnbind(intent); | ||
77 | } | ||
78 | |||
79 | private void setToken(IBinder token) { | ||
80 | synchronized (mLock) { | ||
81 | mToken = token; | ||
82 | } | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * Notifies that the publisher services are ready. | ||
87 | */ | ||
88 | protected abstract void onVmsPublisherServiceReady(); | ||
89 | |||
90 | /** | ||
91 | * Publishers need to implement this method to receive notifications of subscription changes. | ||
92 | * | ||
93 | * @param subscriptionState the state of the subscriptions. | ||
94 | */ | ||
95 | public abstract void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState); | ||
96 | |||
97 | /** | ||
98 | * Uses the VmsPublisherService binder to publish messages. | ||
99 | * | ||
100 | * @param layer the layer to publish to. | ||
101 | * @param payload the message to be sent. | ||
102 | * @param publisherId the ID that got assigned to the publisher that published the message by | ||
103 | * VMS core. | ||
104 | * @return if the call to the method VmsPublisherService.publish was successful. | ||
105 | */ | ||
106 | public final void publish(VmsLayer layer, int publisherId, byte[] payload) { | ||
107 | if (DBG) { | ||
108 | Log.d(TAG, "Publishing for layer : " + layer); | ||
109 | } | ||
110 | |||
111 | IBinder token = getTokenForPublisherServiceThreadSafe(); | ||
112 | |||
113 | try { | ||
114 | mVmsPublisherService.publish(token, layer, publisherId, payload); | ||
115 | } catch (RemoteException e) { | ||
116 | Log.e(TAG, "unable to publish message: " + payload, e); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * Uses the VmsPublisherService binder to set the layers offering. | ||
122 | * | ||
123 | * @param offering the layers that the publisher may publish. | ||
124 | * @return if the call to VmsPublisherService.setLayersOffering was successful. | ||
125 | */ | ||
126 | public final void setLayersOffering(VmsLayersOffering offering) { | ||
127 | if (DBG) { | ||
128 | Log.d(TAG, "Setting layers offering : " + offering); | ||
129 | } | ||
130 | |||
131 | IBinder token = getTokenForPublisherServiceThreadSafe(); | ||
132 | |||
133 | try { | ||
134 | mVmsPublisherService.setLayersOffering(token, offering); | ||
135 | VmsOperationRecorder.get().setLayersOffering(offering); | ||
136 | } catch (RemoteException e) { | ||
137 | Log.e(TAG, "unable to set layers offering: " + offering, e); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | private IBinder getTokenForPublisherServiceThreadSafe() { | ||
142 | if (mVmsPublisherService == null) { | ||
143 | throw new IllegalStateException("VmsPublisherService not set."); | ||
144 | } | ||
145 | |||
146 | IBinder token; | ||
147 | synchronized (mLock) { | ||
148 | token = mToken; | ||
149 | } | ||
150 | if (token == null) { | ||
151 | throw new IllegalStateException("VmsPublisherService does not have a valid token."); | ||
152 | } | ||
153 | return token; | ||
154 | } | ||
155 | |||
156 | public final int getPublisherId(byte[] publisherInfo) { | ||
157 | if (mVmsPublisherService == null) { | ||
158 | throw new IllegalStateException("VmsPublisherService not set."); | ||
159 | } | ||
160 | Integer publisherId = null; | ||
161 | try { | ||
162 | Log.i(TAG, "Getting publisher static ID"); | ||
163 | publisherId = mVmsPublisherService.getPublisherId(publisherInfo); | ||
164 | } catch (RemoteException e) { | ||
165 | Log.e(TAG, "unable to invoke binder method.", e); | ||
166 | } | ||
167 | if (publisherId == null) { | ||
168 | throw new IllegalStateException("VmsPublisherService cannot get a publisher static ID."); | ||
169 | } else { | ||
170 | VmsOperationRecorder.get().getPublisherId(publisherId); | ||
171 | } | ||
172 | return publisherId; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * Uses the VmsPublisherService binder to get the state of the subscriptions. | ||
177 | * | ||
178 | * @return list of layer/version or null in case of error. | ||
179 | */ | ||
180 | public final @Nullable VmsSubscriptionState getSubscriptions() { | ||
181 | if (mVmsPublisherService == null) { | ||
182 | throw new IllegalStateException("VmsPublisherService not set."); | ||
183 | } | ||
184 | try { | ||
185 | return mVmsPublisherService.getSubscriptions(); | ||
186 | } catch (RemoteException e) { | ||
187 | Log.e(TAG, "unable to invoke binder method.", e); | ||
188 | } | ||
189 | return null; | ||
190 | } | ||
191 | |||
192 | private void setVmsPublisherService(IVmsPublisherService service) { | ||
193 | mVmsPublisherService = service; | ||
194 | onVmsPublisherServiceReady(); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Implements the interface that the VMS service uses to communicate with this client. | ||
199 | */ | ||
200 | private static class VmsPublisherClientBinder extends IVmsPublisherClient.Stub { | ||
201 | private final WeakReference<VmsPublisherClientService> mVmsPublisherClientService; | ||
202 | @GuardedBy("mSequenceLock") | ||
203 | private long mSequence = -1; | ||
204 | private final Object mSequenceLock = new Object(); | ||
205 | |||
206 | public VmsPublisherClientBinder(VmsPublisherClientService vmsPublisherClientService) { | ||
207 | mVmsPublisherClientService = new WeakReference<>(vmsPublisherClientService); | ||
208 | } | ||
209 | |||
210 | @Override | ||
211 | public void setVmsPublisherService(IBinder token, IVmsPublisherService service) | ||
212 | throws RemoteException { | ||
213 | VmsPublisherClientService vmsPublisherClientService = mVmsPublisherClientService.get(); | ||
214 | if (vmsPublisherClientService == null) return; | ||
215 | if (DBG) { | ||
216 | Log.d(TAG, "setting VmsPublisherService."); | ||
217 | } | ||
218 | Handler handler = vmsPublisherClientService.mHandler; | ||
219 | handler.sendMessage( | ||
220 | handler.obtainMessage(VmsEventHandler.SET_SERVICE_CALLBACK, service)); | ||
221 | vmsPublisherClientService.setToken(token); | ||
222 | } | ||
223 | |||
224 | @Override | ||
225 | public void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState) | ||
226 | throws RemoteException { | ||
227 | VmsPublisherClientService vmsPublisherClientService = mVmsPublisherClientService.get(); | ||
228 | if (vmsPublisherClientService == null) return; | ||
229 | if (DBG) { | ||
230 | Log.d(TAG, "subscription event: " + subscriptionState); | ||
231 | } | ||
232 | synchronized (mSequenceLock) { | ||
233 | if (subscriptionState.getSequenceNumber() <= mSequence) { | ||
234 | Log.w(TAG, "Sequence out of order. Current sequence = " + mSequence | ||
235 | + "; expected new sequence = " + subscriptionState.getSequenceNumber()); | ||
236 | // Do not propagate old notifications. | ||
237 | return; | ||
238 | } else { | ||
239 | mSequence = subscriptionState.getSequenceNumber(); | ||
240 | } | ||
241 | } | ||
242 | Handler handler = vmsPublisherClientService.mHandler; | ||
243 | handler.sendMessage( | ||
244 | handler.obtainMessage(VmsEventHandler.ON_SUBSCRIPTION_CHANGE_EVENT, | ||
245 | subscriptionState)); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * Receives events from the binder thread and dispatches them. | ||
251 | */ | ||
252 | private final static class VmsEventHandler extends Handler { | ||
253 | /** Constants handled in the handler */ | ||
254 | private static final int ON_SUBSCRIPTION_CHANGE_EVENT = 0; | ||
255 | private static final int SET_SERVICE_CALLBACK = 1; | ||
256 | |||
257 | private final WeakReference<VmsPublisherClientService> mVmsPublisherClientService; | ||
258 | |||
259 | VmsEventHandler(VmsPublisherClientService service) { | ||
260 | super(Looper.getMainLooper()); | ||
261 | mVmsPublisherClientService = new WeakReference<>(service); | ||
262 | } | ||
263 | |||
264 | @Override | ||
265 | public void handleMessage(Message msg) { | ||
266 | VmsPublisherClientService service = mVmsPublisherClientService.get(); | ||
267 | if (service == null) return; | ||
268 | switch (msg.what) { | ||
269 | case ON_SUBSCRIPTION_CHANGE_EVENT: | ||
270 | VmsSubscriptionState subscriptionState = (VmsSubscriptionState) msg.obj; | ||
271 | service.onVmsSubscriptionChange(subscriptionState); | ||
272 | break; | ||
273 | case SET_SERVICE_CALLBACK: | ||
274 | service.setVmsPublisherService((IVmsPublisherService) msg.obj); | ||
275 | break; | ||
276 | default: | ||
277 | Log.e(TAG, "Event type not handled: " + msg.what); | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | } | ||
diff --git a/car-lib/src/android/car/vms/VmsSubscriberManager.java b/car-lib/src/android/car/vms/VmsSubscriberManager.java deleted file mode 100644 index 6f6377ca..00000000 --- a/car-lib/src/android/car/vms/VmsSubscriberManager.java +++ /dev/null | |||
@@ -1,377 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.Car; | ||
20 | import android.car.CarManagerBase; | ||
21 | import android.car.CarNotConnectedException; | ||
22 | import android.car.annotation.FutureFeature; | ||
23 | import android.os.Handler; | ||
24 | import android.os.IBinder; | ||
25 | import android.os.Looper; | ||
26 | import android.os.Message; | ||
27 | import android.os.RemoteException; | ||
28 | import android.util.Log; | ||
29 | |||
30 | import com.android.internal.annotations.GuardedBy; | ||
31 | |||
32 | import java.lang.ref.WeakReference; | ||
33 | import java.util.List; | ||
34 | |||
35 | /** | ||
36 | * API for interfacing with the VmsSubscriberService. It supports a single client callback that can | ||
37 | * (un)subscribe to different layers. Getting notifactions and managing subscriptions is enabled | ||
38 | * after setting the client callback with #registerClientCallback. | ||
39 | * SystemApi candidate | ||
40 | * | ||
41 | * @hide | ||
42 | */ | ||
43 | @FutureFeature | ||
44 | public final class VmsSubscriberManager implements CarManagerBase { | ||
45 | private static final boolean DBG = true; | ||
46 | private static final String TAG = "VmsSubscriberManager"; | ||
47 | |||
48 | private final Handler mHandler; | ||
49 | private final IVmsSubscriberService mVmsSubscriberService; | ||
50 | private final IVmsSubscriberClient mSubscriberManagerClient; | ||
51 | private final Object mClientCallbackLock = new Object(); | ||
52 | @GuardedBy("mClientCallbackLock") | ||
53 | private VmsSubscriberClientCallback mClientCallback; | ||
54 | |||
55 | /** | ||
56 | * Interface exposed to VMS subscribers: it is a wrapper of IVmsSubscriberClient. | ||
57 | */ | ||
58 | public interface VmsSubscriberClientCallback { | ||
59 | /** | ||
60 | * Called when the property is updated | ||
61 | */ | ||
62 | void onVmsMessageReceived(VmsLayer layer, byte[] payload); | ||
63 | |||
64 | /** | ||
65 | * Called when layers availability change | ||
66 | */ | ||
67 | void onLayersAvailabilityChanged(List<VmsLayer> availableLayers); | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * Allows to asynchronously dispatch onVmsMessageReceived events. | ||
72 | */ | ||
73 | private final static class VmsEventHandler extends Handler { | ||
74 | /** | ||
75 | * Constants handled in the handler | ||
76 | */ | ||
77 | private static final int ON_RECEIVE_MESSAGE_EVENT = 0; | ||
78 | private static final int ON_AVAILABILITY_CHANGE_EVENT = 1; | ||
79 | |||
80 | private final WeakReference<VmsSubscriberManager> mMgr; | ||
81 | |||
82 | VmsEventHandler(VmsSubscriberManager mgr, Looper looper) { | ||
83 | super(looper); | ||
84 | mMgr = new WeakReference<>(mgr); | ||
85 | } | ||
86 | |||
87 | @Override | ||
88 | public void handleMessage(Message msg) { | ||
89 | VmsSubscriberManager mgr = mMgr.get(); | ||
90 | switch (msg.what) { | ||
91 | case ON_RECEIVE_MESSAGE_EVENT: | ||
92 | if (mgr != null) { | ||
93 | // Parse the message | ||
94 | VmsDataMessage vmsDataMessage = (VmsDataMessage) msg.obj; | ||
95 | |||
96 | // Dispatch the parsed message | ||
97 | mgr.dispatchOnReceiveMessage(vmsDataMessage.getLayer(), | ||
98 | vmsDataMessage.getPayload()); | ||
99 | } | ||
100 | break; | ||
101 | case ON_AVAILABILITY_CHANGE_EVENT: | ||
102 | if (mgr != null) { | ||
103 | // Parse the message | ||
104 | List<VmsLayer> vmsAvailabilityChangeMessage = (List<VmsLayer>) msg.obj; | ||
105 | |||
106 | // Dispatch the parsed message | ||
107 | mgr.dispatchOnAvailabilityChangeMessage(vmsAvailabilityChangeMessage); | ||
108 | } | ||
109 | break; | ||
110 | |||
111 | default: | ||
112 | Log.e(VmsSubscriberManager.TAG, "Event type not handled: " + msg.what); | ||
113 | break; | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | |||
118 | public VmsSubscriberManager(IBinder service, Handler handler) { | ||
119 | mVmsSubscriberService = IVmsSubscriberService.Stub.asInterface(service); | ||
120 | mHandler = new VmsEventHandler(this, handler.getLooper()); | ||
121 | mSubscriberManagerClient = new IVmsSubscriberClient.Stub() { | ||
122 | @Override | ||
123 | public void onVmsMessageReceived(VmsLayer layer, byte[] payload) | ||
124 | throws RemoteException { | ||
125 | // Create the data message | ||
126 | VmsDataMessage vmsDataMessage = new VmsDataMessage(layer, payload); | ||
127 | mHandler.sendMessage( | ||
128 | mHandler.obtainMessage( | ||
129 | VmsEventHandler.ON_RECEIVE_MESSAGE_EVENT, | ||
130 | vmsDataMessage)); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public void onLayersAvailabilityChanged(List<VmsAssociatedLayer> availableLayers) { | ||
135 | mHandler.sendMessage( | ||
136 | mHandler.obtainMessage( | ||
137 | VmsEventHandler.ON_AVAILABILITY_CHANGE_EVENT, | ||
138 | availableLayers)); | ||
139 | } | ||
140 | }; | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * Registers the client callback in order to enable communication with the client. | ||
145 | * By registering, the client will start getting notifications, and will be able to subscribe | ||
146 | * to layers. | ||
147 | * <p> | ||
148 | * | ||
149 | * @param clientCallback subscriber callback that will handle onVmsMessageReceived events. | ||
150 | * @throws IllegalStateException if the client callback was already set. | ||
151 | */ | ||
152 | public void registerClientCallback(VmsSubscriberClientCallback clientCallback) | ||
153 | throws CarNotConnectedException { | ||
154 | synchronized (mClientCallbackLock) { | ||
155 | if (mClientCallback != null) { | ||
156 | throw new IllegalStateException("Client callback is already configured."); | ||
157 | } | ||
158 | mClientCallback = clientCallback; | ||
159 | } | ||
160 | try { | ||
161 | mVmsSubscriberService.addVmsSubscriberToNotifications(mSubscriberManagerClient); | ||
162 | } catch (RemoteException e) { | ||
163 | Log.e(TAG, "Could not connect: ", e); | ||
164 | throw new CarNotConnectedException(e); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * Unregisters the client callback which disables communication with the client. | ||
170 | * @throws CarNotConnectedException, IllegalStateException | ||
171 | */ | ||
172 | public void unregisterClientCallback() | ||
173 | throws CarNotConnectedException { | ||
174 | |||
175 | try { | ||
176 | mVmsSubscriberService.removeVmsSubscriberToNotifications(mSubscriberManagerClient); | ||
177 | } catch (RemoteException e) { | ||
178 | Log.e(TAG, "Could not connect: ", e); | ||
179 | throw new CarNotConnectedException(e); | ||
180 | } catch (IllegalStateException e) { | ||
181 | Log.e(TAG, "Could not unsubscribe from notifications"); | ||
182 | throw e; | ||
183 | } | ||
184 | |||
185 | synchronized (mClientCallbackLock) { | ||
186 | mClientCallback = null; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Returns a serialized publisher information for a publisher ID. | ||
192 | */ | ||
193 | public byte[] getPublisherInfo(int publisherId) | ||
194 | throws CarNotConnectedException, IllegalStateException { | ||
195 | try { | ||
196 | return mVmsSubscriberService.getPublisherInfo(publisherId); | ||
197 | } catch (RemoteException e) { | ||
198 | Log.e(TAG, "Could not connect: ", e); | ||
199 | throw new CarNotConnectedException(e); | ||
200 | } catch (IllegalStateException ex) { | ||
201 | Car.checkCarNotConnectedExceptionFromCarService(ex); | ||
202 | throw new IllegalStateException(ex); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * Subscribes to listen to the layer specified. | ||
208 | * | ||
209 | * @param layer the layer to subscribe to. | ||
210 | * @throws IllegalStateException if the client callback was not set via | ||
211 | * {@link #registerClientCallback}. | ||
212 | */ | ||
213 | public void subscribe(VmsLayer layer) throws CarNotConnectedException { | ||
214 | verifySubscriptionIsAllowed(); | ||
215 | try { | ||
216 | mVmsSubscriberService.addVmsSubscriber(mSubscriberManagerClient, layer); | ||
217 | VmsOperationRecorder.get().subscribe(layer); | ||
218 | } catch (RemoteException e) { | ||
219 | Log.e(TAG, "Could not connect: ", e); | ||
220 | throw new CarNotConnectedException(e); | ||
221 | } catch (IllegalStateException ex) { | ||
222 | Car.checkCarNotConnectedExceptionFromCarService(ex); | ||
223 | } | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * Subscribes to listen to the layer specified from the publisher specified. | ||
228 | * | ||
229 | * @param layer the layer to subscribe to. | ||
230 | * @param publisherId the publisher of the layer. | ||
231 | * @throws IllegalStateException if the client callback was not set via | ||
232 | * {@link #registerClientCallback}. | ||
233 | */ | ||
234 | public void subscribe(VmsLayer layer, int publisherId) throws CarNotConnectedException { | ||
235 | verifySubscriptionIsAllowed(); | ||
236 | try { | ||
237 | mVmsSubscriberService.addVmsSubscriberToPublisher( | ||
238 | mSubscriberManagerClient, layer, publisherId); | ||
239 | VmsOperationRecorder.get().subscribe(layer, publisherId); | ||
240 | } catch (RemoteException e) { | ||
241 | Log.e(TAG, "Could not connect: ", e); | ||
242 | throw new CarNotConnectedException(e); | ||
243 | } catch (IllegalStateException ex) { | ||
244 | Car.checkCarNotConnectedExceptionFromCarService(ex); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | public void startMonitoring() throws CarNotConnectedException { | ||
249 | verifySubscriptionIsAllowed(); | ||
250 | try { | ||
251 | mVmsSubscriberService.addVmsSubscriberPassive(mSubscriberManagerClient); | ||
252 | VmsOperationRecorder.get().startMonitoring(); | ||
253 | } catch (RemoteException e) { | ||
254 | Log.e(TAG, "Could not connect: ", e); | ||
255 | throw new CarNotConnectedException(e); | ||
256 | } catch (IllegalStateException ex) { | ||
257 | Car.checkCarNotConnectedExceptionFromCarService(ex); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * Unsubscribes from the layer/version specified. | ||
263 | * | ||
264 | * @param layer the layer to unsubscribe from. | ||
265 | * @throws IllegalStateException if the client callback was not set via | ||
266 | * {@link #registerClientCallback}. | ||
267 | */ | ||
268 | public void unsubscribe(VmsLayer layer) { | ||
269 | verifySubscriptionIsAllowed(); | ||
270 | try { | ||
271 | mVmsSubscriberService.removeVmsSubscriber(mSubscriberManagerClient, layer); | ||
272 | VmsOperationRecorder.get().unsubscribe(layer); | ||
273 | } catch (RemoteException e) { | ||
274 | Log.e(TAG, "Failed to unregister subscriber", e); | ||
275 | // ignore | ||
276 | } catch (IllegalStateException ex) { | ||
277 | Car.hideCarNotConnectedExceptionFromCarService(ex); | ||
278 | } | ||
279 | } | ||
280 | |||
281 | /** | ||
282 | * Unsubscribes from the layer/version specified. | ||
283 | * | ||
284 | * @param layer the layer to unsubscribe from. | ||
285 | * @param publisherId the pubisher of the layer. | ||
286 | * @throws IllegalStateException if the client callback was not set via | ||
287 | * {@link #registerClientCallback}. | ||
288 | */ | ||
289 | public void unsubscribe(VmsLayer layer, int publisherId) { | ||
290 | try { | ||
291 | mVmsSubscriberService.removeVmsSubscriberToPublisher( | ||
292 | mSubscriberManagerClient, layer, publisherId); | ||
293 | VmsOperationRecorder.get().unsubscribe(layer, publisherId); | ||
294 | } catch (RemoteException e) { | ||
295 | Log.e(TAG, "Failed to unregister subscriber", e); | ||
296 | // ignore | ||
297 | } catch (IllegalStateException ex) { | ||
298 | Car.hideCarNotConnectedExceptionFromCarService(ex); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | public void stopMonitoring() { | ||
303 | try { | ||
304 | mVmsSubscriberService.removeVmsSubscriberPassive(mSubscriberManagerClient); | ||
305 | VmsOperationRecorder.get().stopMonitoring(); | ||
306 | } catch (RemoteException e) { | ||
307 | Log.e(TAG, "Failed to unregister subscriber ", e); | ||
308 | // ignore | ||
309 | } catch (IllegalStateException ex) { | ||
310 | Car.hideCarNotConnectedExceptionFromCarService(ex); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | private void dispatchOnReceiveMessage(VmsLayer layer, byte[] payload) { | ||
315 | VmsSubscriberClientCallback clientCallback = getClientCallbackThreadSafe(); | ||
316 | if (clientCallback == null) { | ||
317 | Log.e(TAG, "Cannot dispatch received message."); | ||
318 | return; | ||
319 | } | ||
320 | clientCallback.onVmsMessageReceived(layer, payload); | ||
321 | } | ||
322 | |||
323 | private void dispatchOnAvailabilityChangeMessage(List<VmsLayer> availableLayers) { | ||
324 | VmsSubscriberClientCallback clientCallback = getClientCallbackThreadSafe(); | ||
325 | if (clientCallback == null) { | ||
326 | Log.e(TAG, "Cannot dispatch availability change message."); | ||
327 | return; | ||
328 | } | ||
329 | clientCallback.onLayersAvailabilityChanged(availableLayers); | ||
330 | } | ||
331 | |||
332 | private VmsSubscriberClientCallback getClientCallbackThreadSafe() { | ||
333 | VmsSubscriberClientCallback clientCallback; | ||
334 | synchronized (mClientCallbackLock) { | ||
335 | clientCallback = mClientCallback; | ||
336 | } | ||
337 | if (clientCallback == null) { | ||
338 | Log.e(TAG, "client callback not set."); | ||
339 | } | ||
340 | return clientCallback; | ||
341 | } | ||
342 | |||
343 | /* | ||
344 | * Verifies that the subscriber is in a state where it is allowed to subscribe. | ||
345 | */ | ||
346 | private void verifySubscriptionIsAllowed() { | ||
347 | VmsSubscriberClientCallback clientCallback = getClientCallbackThreadSafe(); | ||
348 | if (clientCallback == null) { | ||
349 | throw new IllegalStateException("Cannot subscribe."); | ||
350 | } | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * @hide | ||
355 | */ | ||
356 | @Override | ||
357 | public void onCarDisconnected() { | ||
358 | } | ||
359 | |||
360 | private static final class VmsDataMessage { | ||
361 | private final VmsLayer mLayer; | ||
362 | private final byte[] mPayload; | ||
363 | |||
364 | public VmsDataMessage(VmsLayer layer, byte[] payload) { | ||
365 | mLayer = layer; | ||
366 | mPayload = payload; | ||
367 | } | ||
368 | |||
369 | public VmsLayer getLayer() { | ||
370 | return mLayer; | ||
371 | } | ||
372 | |||
373 | public byte[] getPayload() { | ||
374 | return mPayload; | ||
375 | } | ||
376 | } | ||
377 | } | ||
diff --git a/car-lib/src/android/car/vms/VmsSubscriptionState.aidl b/car-lib/src/android/car/vms/VmsSubscriptionState.aidl deleted file mode 100644 index b5ce8fff..00000000 --- a/car-lib/src/android/car/vms/VmsSubscriptionState.aidl +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | parcelable VmsSubscriptionState; \ No newline at end of file | ||
diff --git a/car-lib/src/android/car/vms/VmsSubscriptionState.java b/car-lib/src/android/car/vms/VmsSubscriptionState.java deleted file mode 100644 index ea433f70..00000000 --- a/car-lib/src/android/car/vms/VmsSubscriptionState.java +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package android.car.vms; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.os.Parcel; | ||
21 | import android.os.Parcelable; | ||
22 | |||
23 | import java.util.ArrayList; | ||
24 | import java.util.Collections; | ||
25 | import java.util.HashSet; | ||
26 | import java.util.List; | ||
27 | import java.util.Set; | ||
28 | |||
29 | |||
30 | /** | ||
31 | * The list of layers with subscribers. | ||
32 | * | ||
33 | * @hide | ||
34 | */ | ||
35 | @FutureFeature | ||
36 | public final class VmsSubscriptionState implements Parcelable { | ||
37 | private final int mSequenceNumber; | ||
38 | private final Set<VmsLayer> mLayers; | ||
39 | private final Set<VmsAssociatedLayer> mSubscribedLayersFromPublishers; | ||
40 | |||
41 | /** | ||
42 | * Construcs a summary of the state of the current subscriptions for publishers to consume | ||
43 | * and adjust which layers that the are publishing. | ||
44 | */ | ||
45 | public VmsSubscriptionState(int sequenceNumber, | ||
46 | Set<VmsLayer> subscribedLayers, | ||
47 | Set<VmsAssociatedLayer> layersFromPublishers) { | ||
48 | mSequenceNumber = sequenceNumber; | ||
49 | mLayers = Collections.unmodifiableSet(subscribedLayers); | ||
50 | mSubscribedLayersFromPublishers = Collections.unmodifiableSet(layersFromPublishers); | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Returns the sequence number assigned by the VMS service. Sequence numbers are | ||
55 | * monotonically increasing and help clients ignore potential out-of-order states. | ||
56 | */ | ||
57 | public int getSequenceNumber() { | ||
58 | return mSequenceNumber; | ||
59 | } | ||
60 | |||
61 | public Set<VmsLayer> getLayers() { | ||
62 | return mLayers; | ||
63 | } | ||
64 | |||
65 | public Set<VmsAssociatedLayer> getAssociatedLayers() { | ||
66 | return mSubscribedLayersFromPublishers; | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public String toString() { | ||
71 | StringBuilder sb = new StringBuilder(); | ||
72 | sb.append("sequence number=").append(mSequenceNumber); | ||
73 | sb.append("; layers={"); | ||
74 | for (VmsLayer layer : mLayers) { | ||
75 | sb.append(layer).append(","); | ||
76 | } | ||
77 | sb.append("}"); | ||
78 | sb.append("; associatedLayers={"); | ||
79 | for (VmsAssociatedLayer layer : mSubscribedLayersFromPublishers) { | ||
80 | sb.append(layer).append(","); | ||
81 | } | ||
82 | sb.append("}"); | ||
83 | return sb.toString(); | ||
84 | } | ||
85 | |||
86 | public static final Parcelable.Creator<VmsSubscriptionState> CREATOR = new | ||
87 | Parcelable.Creator<VmsSubscriptionState>() { | ||
88 | public VmsSubscriptionState createFromParcel(Parcel in) { | ||
89 | return new VmsSubscriptionState(in); | ||
90 | } | ||
91 | |||
92 | public VmsSubscriptionState[] newArray(int size) { | ||
93 | return new VmsSubscriptionState[size]; | ||
94 | } | ||
95 | }; | ||
96 | |||
97 | @Override | ||
98 | public void writeToParcel(Parcel out, int flags) { | ||
99 | out.writeInt(mSequenceNumber); | ||
100 | out.writeParcelableList(new ArrayList(mLayers), flags); | ||
101 | out.writeParcelableList(new ArrayList(mSubscribedLayersFromPublishers), flags); | ||
102 | } | ||
103 | |||
104 | @Override | ||
105 | public int describeContents() { | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | private VmsSubscriptionState(Parcel in) { | ||
110 | mSequenceNumber = in.readInt(); | ||
111 | |||
112 | List<VmsLayer> layers = new ArrayList<>(); | ||
113 | in.readParcelableList(layers, VmsLayer.class.getClassLoader()); | ||
114 | mLayers = Collections.unmodifiableSet(new HashSet(layers)); | ||
115 | |||
116 | List<VmsAssociatedLayer> associatedLayers = new ArrayList<>(); | ||
117 | in.readParcelableList(associatedLayers, VmsAssociatedLayer.class.getClassLoader()); | ||
118 | mSubscribedLayersFromPublishers = Collections.unmodifiableSet(new HashSet(associatedLayers)); | ||
119 | } | ||
120 | } \ No newline at end of file | ||
diff --git a/service/AndroidManifest.xml b/service/AndroidManifest.xml index e39fb9ed..5c4dfaac 100644 --- a/service/AndroidManifest.xml +++ b/service/AndroidManifest.xml | |||
@@ -101,17 +101,6 @@ | |||
101 | android:protectionLevel="system|signature" | 101 | android:protectionLevel="system|signature" |
102 | android:label="@string/car_permission_label_diag_clear" | 102 | android:label="@string/car_permission_label_diag_clear" |
103 | android:description="@string/car_permission_desc_diag_clear" /> | 103 | android:description="@string/car_permission_desc_diag_clear" /> |
104 | <permission | ||
105 | android:name="android.car.permission.VMS_PUBLISHER" | ||
106 | android:protectionLevel="system|signature" | ||
107 | android:label="@string/car_permission_label_vms_publisher" | ||
108 | android:description="@string/car_permission_desc_vms_publisher" /> | ||
109 | <permission | ||
110 | android:name="android.car.permission.VMS_SUBSCRIBER" | ||
111 | android:protectionLevel="system|signature" | ||
112 | android:label="@string/car_permission_label_vms_subscriber" | ||
113 | android:description="@string/car_permission_desc_vms_subscriber" /> | ||
114 | |||
115 | <!-- may replace this with system permission if proper one is defined. --> | 104 | <!-- may replace this with system permission if proper one is defined. --> |
116 | <permission | 105 | <permission |
117 | android:name="android.car.permission.CONTROL_APP_BLOCKING" | 106 | android:name="android.car.permission.CONTROL_APP_BLOCKING" |
diff --git a/service/res/values/config.xml b/service/res/values/config.xml index 61cef594..73028cba 100644 --- a/service/res/values/config.xml +++ b/service/res/values/config.xml | |||
@@ -74,11 +74,4 @@ | |||
74 | <string name="defauiltActivityWhitelist">android,com.android.systemui</string> | 74 | <string name="defauiltActivityWhitelist">android,com.android.systemui</string> |
75 | <!-- Default home activity --> | 75 | <!-- Default home activity --> |
76 | <string name="defaultHomeActivity">com.android.car.overview/com.android.car.overview.StreamOverviewActivity</string> | 76 | <string name="defaultHomeActivity">com.android.car.overview/com.android.car.overview.StreamOverviewActivity</string> |
77 | <!-- The com.android.car.VmsPublisherService will bind to this list of clients --> | ||
78 | <string-array translatable="false" name="vmsPublisherClients"> | ||
79 | </string-array> | ||
80 | <!-- Permissions that the com.android.car.VmsPublisherService is allowed to grant to publishers --> | ||
81 | <string-array translatable="false" name="vmsSafePermissions"> | ||
82 | <item>"android.permission.ACCESS_FINE_LOCATION"</item> | ||
83 | </string-array> | ||
84 | </resources> | 77 | </resources> |
diff --git a/service/res/values/strings.xml b/service/res/values/strings.xml index 6cfff9a8..7f826d4c 100644 --- a/service/res/values/strings.xml +++ b/service/res/values/strings.xml | |||
@@ -116,13 +116,4 @@ | |||
116 | <!-- Permission text: apps can clear diagnostic data from the car [CHAR LIMIT=NONE] --> | 116 | <!-- Permission text: apps can clear diagnostic data from the car [CHAR LIMIT=NONE] --> |
117 | <string name="car_permission_desc_diag_clear">Clear diagnostic data from the car</string> | 117 | <string name="car_permission_desc_diag_clear">Clear diagnostic data from the car</string> |
118 | 118 | ||
119 | <!-- Permission text: apps can publish VMS data [CHAR LIMIT=NONE] --> | ||
120 | <string name="car_permission_label_vms_publisher">VMS publisher</string> | ||
121 | <!-- Permission text: apps can send VMS messages to the car [CHAR LIMIT=NONE] --> | ||
122 | <string name="car_permission_desc_vms_publisher">Publish vms messages</string> | ||
123 | |||
124 | <!-- Permission text: apps can subscribe to VMS data [CHAR LIMIT=NONE] --> | ||
125 | <string name="car_permission_label_vms_subscriber">VMS subscriber</string> | ||
126 | <!-- Permission text: apps can receive VMS messages from the car [CHAR LIMIT=NONE] --> | ||
127 | <string name="car_permission_desc_vms_subscriber">Subscribe to vms messages</string> | ||
128 | </resources> | 119 | </resources> |
diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java index bd424542..bbb86f60 100644 --- a/service/src/com/android/car/ICarImpl.java +++ b/service/src/com/android/car/ICarImpl.java | |||
@@ -72,10 +72,6 @@ public class ICarImpl extends ICar.Stub { | |||
72 | private final CarBluetoothService mCarBluetoothService; | 72 | private final CarBluetoothService mCarBluetoothService; |
73 | private final PerUserCarServiceHelper mPerUserCarServiceHelper; | 73 | private final PerUserCarServiceHelper mPerUserCarServiceHelper; |
74 | private CarDiagnosticService mCarDiagnosticService; | 74 | private CarDiagnosticService mCarDiagnosticService; |
75 | @FutureFeature | ||
76 | private VmsSubscriberService mVmsSubscriberService; | ||
77 | @FutureFeature | ||
78 | private VmsPublisherService mVmsPublisherService; | ||
79 | 75 | ||
80 | private final CarServiceBase[] mAllServices; | 76 | private final CarServiceBase[] mAllServices; |
81 | 77 | ||
@@ -121,10 +117,6 @@ public class ICarImpl extends ICar.Stub { | |||
121 | mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext); | 117 | mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext); |
122 | mCarBluetoothService = new CarBluetoothService(serviceContext, mCarCabinService, | 118 | mCarBluetoothService = new CarBluetoothService(serviceContext, mCarCabinService, |
123 | mCarSensorService, mPerUserCarServiceHelper); | 119 | mCarSensorService, mPerUserCarServiceHelper); |
124 | if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
125 | mVmsSubscriberService = new VmsSubscriberService(serviceContext, mHal.getVmsHal()); | ||
126 | mVmsPublisherService = new VmsPublisherService(serviceContext, mHal.getVmsHal()); | ||
127 | } | ||
128 | mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal()); | 120 | mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal()); |
129 | 121 | ||
130 | // Be careful with order. Service depending on other service should be inited later. | 122 | // Be careful with order. Service depending on other service should be inited later. |
@@ -150,10 +142,6 @@ public class ICarImpl extends ICar.Stub { | |||
150 | mCarDiagnosticService, | 142 | mCarDiagnosticService, |
151 | mPerUserCarServiceHelper | 143 | mPerUserCarServiceHelper |
152 | )); | 144 | )); |
153 | if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
154 | allServices.add(mVmsSubscriberService); | ||
155 | allServices.add(mVmsPublisherService); | ||
156 | } | ||
157 | mAllServices = allServices.toArray(new CarServiceBase[0]); | 145 | mAllServices = allServices.toArray(new CarServiceBase[0]); |
158 | } | 146 | } |
159 | 147 | ||
@@ -233,12 +221,6 @@ public class ICarImpl extends ICar.Stub { | |||
233 | case Car.VENDOR_EXTENSION_SERVICE: | 221 | case Car.VENDOR_EXTENSION_SERVICE: |
234 | assertVendorExtensionPermission(mContext); | 222 | assertVendorExtensionPermission(mContext); |
235 | return mCarVendorExtensionService; | 223 | return mCarVendorExtensionService; |
236 | case Car.VMS_SUBSCRIBER_SERVICE: | ||
237 | FeatureUtil.assertFeature(FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE); | ||
238 | if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
239 | assertVmsSubscriberPermission(mContext); | ||
240 | return mVmsSubscriberService; | ||
241 | } | ||
242 | case Car.TEST_SERVICE: { | 224 | case Car.TEST_SERVICE: { |
243 | assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE); | 225 | assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE); |
244 | synchronized (this) { | 226 | synchronized (this) { |
@@ -312,16 +294,6 @@ public class ICarImpl extends ICar.Stub { | |||
312 | Car.PERMISSION_CAR_DIAGNOSTIC_CLEAR); | 294 | Car.PERMISSION_CAR_DIAGNOSTIC_CLEAR); |
313 | } | 295 | } |
314 | 296 | ||
315 | @FutureFeature | ||
316 | public static void assertVmsPublisherPermission(Context context) { | ||
317 | assertPermission(context, Car.PERMISSION_VMS_PUBLISHER); | ||
318 | } | ||
319 | |||
320 | @FutureFeature | ||
321 | public static void assertVmsSubscriberPermission(Context context) { | ||
322 | assertPermission(context, Car.PERMISSION_VMS_SUBSCRIBER); | ||
323 | } | ||
324 | |||
325 | public static void assertPermission(Context context, String permission) { | 297 | public static void assertPermission(Context context, String permission) { |
326 | if (context.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { | 298 | if (context.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { |
327 | throw new SecurityException("requires " + permission); | 299 | throw new SecurityException("requires " + permission); |
diff --git a/service/src/com/android/car/VmsLayersAvailability.java b/service/src/com/android/car/VmsLayersAvailability.java deleted file mode 100644 index 93b917ca..00000000 --- a/service/src/com/android/car/VmsLayersAvailability.java +++ /dev/null | |||
@@ -1,200 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.car.vms.VmsAssociatedLayer; | ||
21 | import android.car.vms.VmsLayer; | ||
22 | import android.car.vms.VmsLayerDependency; | ||
23 | import android.car.vms.VmsLayersOffering; | ||
24 | import android.util.Log; | ||
25 | import com.android.internal.annotations.GuardedBy; | ||
26 | |||
27 | import java.util.ArrayList; | ||
28 | import java.util.Collection; | ||
29 | import java.util.Collections; | ||
30 | import java.util.HashMap; | ||
31 | import java.util.HashSet; | ||
32 | import java.util.List; | ||
33 | import java.util.Map; | ||
34 | import java.util.Set; | ||
35 | import java.util.stream.Collectors; | ||
36 | |||
37 | /** | ||
38 | * Manages VMS availability for layers. | ||
39 | * <p> | ||
40 | * Each VMS publisher sets its layers offering which are a list of layers the publisher claims | ||
41 | * it might publish. VmsLayersAvailability calculates from all the offering what are the | ||
42 | * available layers. | ||
43 | */ | ||
44 | |||
45 | @FutureFeature | ||
46 | public class VmsLayersAvailability { | ||
47 | |||
48 | private static final boolean DBG = true; | ||
49 | private static final String TAG = "VmsLayersAvailability"; | ||
50 | |||
51 | private final Object mLock = new Object(); | ||
52 | @GuardedBy("mLock") | ||
53 | private final Map<VmsLayer, Set<Set<VmsLayer>>> mPotentialLayersAndDependencies = | ||
54 | new HashMap<>(); | ||
55 | @GuardedBy("mLock") | ||
56 | private Set<VmsAssociatedLayer> mAvailableAssociatedLayers = Collections.EMPTY_SET; | ||
57 | @GuardedBy("mLock") | ||
58 | private Set<VmsAssociatedLayer> mUnavailableAssociatedLayers = Collections.EMPTY_SET; | ||
59 | @GuardedBy("mLock") | ||
60 | private Map<VmsLayer, Set<Integer>> mPotentialLayersAndPublishers = new HashMap<>(); | ||
61 | |||
62 | /** | ||
63 | * Setting the current layers offerings as reported by publishers. | ||
64 | */ | ||
65 | public void setPublishersOffering(Collection<VmsLayersOffering> publishersLayersOfferings) { | ||
66 | synchronized (mLock) { | ||
67 | reset(); | ||
68 | |||
69 | for (VmsLayersOffering offering : publishersLayersOfferings) { | ||
70 | for (VmsLayerDependency dependency : offering.getDependencies()) { | ||
71 | VmsLayer layer = dependency.getLayer(); | ||
72 | |||
73 | // Associate publishers with layers. | ||
74 | Set<Integer> curPotentialLayerAndPublishers = | ||
75 | mPotentialLayersAndPublishers.get(layer); | ||
76 | if (curPotentialLayerAndPublishers == null) { | ||
77 | curPotentialLayerAndPublishers = new HashSet<>(); | ||
78 | mPotentialLayersAndPublishers.put(layer, curPotentialLayerAndPublishers); | ||
79 | } | ||
80 | curPotentialLayerAndPublishers.add(offering.getPublisherId()); | ||
81 | |||
82 | // Add dependencies for availability calculation. | ||
83 | Set<Set<VmsLayer>> curDependencies = | ||
84 | mPotentialLayersAndDependencies.get(layer); | ||
85 | if (curDependencies == null) { | ||
86 | curDependencies = new HashSet<>(); | ||
87 | mPotentialLayersAndDependencies.put(layer, curDependencies); | ||
88 | } | ||
89 | curDependencies.add(dependency.getDependencies()); | ||
90 | } | ||
91 | } | ||
92 | calculateLayers(); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * Returns a collection of all the layers which may be published. | ||
98 | */ | ||
99 | public Set<VmsAssociatedLayer> getAvailableLayers() { | ||
100 | synchronized (mLock) { | ||
101 | return mAvailableAssociatedLayers; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * Returns a collection of all the layers which publishers could have published if the | ||
107 | * dependencies were satisfied. | ||
108 | */ | ||
109 | public Set<VmsAssociatedLayer> getUnavailableLayers() { | ||
110 | synchronized (mLock) { | ||
111 | return mUnavailableAssociatedLayers; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | private void reset() { | ||
116 | synchronized (mLock) { | ||
117 | mPotentialLayersAndDependencies.clear(); | ||
118 | mPotentialLayersAndPublishers.clear(); | ||
119 | mAvailableAssociatedLayers = Collections.EMPTY_SET; | ||
120 | mUnavailableAssociatedLayers = Collections.EMPTY_SET; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | private void calculateLayers() { | ||
125 | synchronized (mLock) { | ||
126 | Set<VmsLayer> availableLayersSet = new HashSet<>(); | ||
127 | Set<VmsLayer> cyclicAvoidanceAuxiliarySet = new HashSet<>(); | ||
128 | |||
129 | for (VmsLayer layer : mPotentialLayersAndDependencies.keySet()) { | ||
130 | addLayerToAvailabilityCalculationLocked(layer, | ||
131 | availableLayersSet, | ||
132 | cyclicAvoidanceAuxiliarySet); | ||
133 | } | ||
134 | |||
135 | mAvailableAssociatedLayers = Collections.unmodifiableSet( | ||
136 | availableLayersSet | ||
137 | .stream() | ||
138 | .map(l -> new VmsAssociatedLayer(l, mPotentialLayersAndPublishers.get(l))) | ||
139 | .collect(Collectors.toSet())); | ||
140 | |||
141 | mUnavailableAssociatedLayers = Collections.unmodifiableSet( | ||
142 | mPotentialLayersAndDependencies.keySet() | ||
143 | .stream() | ||
144 | .filter(l -> !availableLayersSet.contains(l)) | ||
145 | .map(l -> new VmsAssociatedLayer(l, mPotentialLayersAndPublishers.get(l))) | ||
146 | .collect(Collectors.toSet())); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | private void addLayerToAvailabilityCalculationLocked(VmsLayer layer, | ||
151 | Set<VmsLayer> currentAvailableLayers, | ||
152 | Set<VmsLayer> cyclicAvoidanceSet) { | ||
153 | if (DBG) { | ||
154 | Log.d(TAG, "addLayerToAvailabilityCalculationLocked: checking layer: " + layer); | ||
155 | } | ||
156 | // If we already know that this layer is supported then we are done. | ||
157 | if (currentAvailableLayers.contains(layer)) { | ||
158 | return; | ||
159 | } | ||
160 | // If there is no offering for this layer we're done. | ||
161 | if (!mPotentialLayersAndDependencies.containsKey(layer)) { | ||
162 | return; | ||
163 | } | ||
164 | // Avoid cyclic dependency. | ||
165 | if (cyclicAvoidanceSet.contains(layer)) { | ||
166 | Log.e(TAG, "Detected a cyclic dependency: " + cyclicAvoidanceSet + " -> " + layer); | ||
167 | return; | ||
168 | } | ||
169 | // A layer may have multiple dependency sets. The layer is available if any dependency | ||
170 | // set is satisfied | ||
171 | for (Set<VmsLayer> dependencies : mPotentialLayersAndDependencies.get(layer)) { | ||
172 | // If layer does not have any dependencies then add to supported. | ||
173 | if (dependencies == null || dependencies.isEmpty()) { | ||
174 | currentAvailableLayers.add(layer); | ||
175 | return; | ||
176 | } | ||
177 | // Add the layer to cyclic avoidance set | ||
178 | cyclicAvoidanceSet.add(layer); | ||
179 | |||
180 | boolean isSupported = true; | ||
181 | for (VmsLayer dependency : dependencies) { | ||
182 | addLayerToAvailabilityCalculationLocked(dependency, | ||
183 | currentAvailableLayers, | ||
184 | cyclicAvoidanceSet); | ||
185 | |||
186 | if (!currentAvailableLayers.contains(dependency)) { | ||
187 | isSupported = false; | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | cyclicAvoidanceSet.remove(layer); | ||
192 | |||
193 | if (isSupported) { | ||
194 | currentAvailableLayers.add(layer); | ||
195 | return; | ||
196 | } | ||
197 | } | ||
198 | return; | ||
199 | } | ||
200 | } | ||
diff --git a/service/src/com/android/car/VmsPublisherService.java b/service/src/com/android/car/VmsPublisherService.java deleted file mode 100644 index 8a293e5e..00000000 --- a/service/src/com/android/car/VmsPublisherService.java +++ /dev/null | |||
@@ -1,336 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.car.vms.IVmsSubscriberClient; | ||
21 | import android.car.vms.IVmsPublisherClient; | ||
22 | import android.car.vms.IVmsPublisherService; | ||
23 | import android.car.vms.VmsLayer; | ||
24 | import android.car.vms.VmsLayersOffering; | ||
25 | import android.car.vms.VmsSubscriptionState; | ||
26 | import android.content.ComponentName; | ||
27 | import android.content.Context; | ||
28 | import android.content.Intent; | ||
29 | import android.content.ServiceConnection; | ||
30 | import android.content.pm.PackageInfo; | ||
31 | import android.content.pm.PackageManager; | ||
32 | import android.os.Binder; | ||
33 | import android.os.IBinder; | ||
34 | import android.os.RemoteException; | ||
35 | import android.os.UserHandle; | ||
36 | import android.text.TextUtils; | ||
37 | import android.util.Log; | ||
38 | import com.android.car.hal.VmsHalService; | ||
39 | import com.android.internal.annotations.GuardedBy; | ||
40 | import java.io.PrintWriter; | ||
41 | import java.lang.ref.WeakReference; | ||
42 | import java.util.ArrayList; | ||
43 | import java.util.Arrays; | ||
44 | import java.util.HashMap; | ||
45 | import java.util.HashSet; | ||
46 | import java.util.List; | ||
47 | import java.util.Map; | ||
48 | import java.util.Set; | ||
49 | |||
50 | /** | ||
51 | * + Receives HAL updates by implementing VmsHalService.VmsHalListener. | ||
52 | * + Binds to publishers and configures them to use this service. | ||
53 | * + Notifies publishers of subscription changes. | ||
54 | */ | ||
55 | @FutureFeature | ||
56 | public class VmsPublisherService extends IVmsPublisherService.Stub | ||
57 | implements CarServiceBase, VmsHalService.VmsHalPublisherListener { | ||
58 | private static final boolean DBG = true; | ||
59 | private static final String TAG = "VmsPublisherService"; | ||
60 | |||
61 | private final Context mContext; | ||
62 | private final VmsHalService mHal; | ||
63 | private final VmsPublisherManager mPublisherManager; | ||
64 | private Set<String> mSafePermissions; | ||
65 | |||
66 | public VmsPublisherService(Context context, VmsHalService hal) { | ||
67 | mContext = context; | ||
68 | mHal = hal; | ||
69 | mPublisherManager = new VmsPublisherManager(this); | ||
70 | } | ||
71 | |||
72 | // Implements CarServiceBase interface. | ||
73 | @Override | ||
74 | public void init() { | ||
75 | mHal.addPublisherListener(this); | ||
76 | // Load permissions that can be granted to publishers. | ||
77 | mSafePermissions = new HashSet<>( | ||
78 | Arrays.asList(mContext.getResources().getStringArray(R.array.vmsSafePermissions))); | ||
79 | // Launch publishers. | ||
80 | String[] publisherNames = mContext.getResources().getStringArray( | ||
81 | R.array.vmsPublisherClients); | ||
82 | for (String publisherName : publisherNames) { | ||
83 | if (TextUtils.isEmpty(publisherName)) { | ||
84 | Log.e(TAG, "empty publisher name"); | ||
85 | continue; | ||
86 | } | ||
87 | ComponentName name = ComponentName.unflattenFromString(publisherName); | ||
88 | if (name == null) { | ||
89 | Log.e(TAG, "invalid publisher name: " + publisherName); | ||
90 | } | ||
91 | mPublisherManager.bind(name); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public void release() { | ||
97 | mPublisherManager.release(); | ||
98 | mHal.removePublisherListener(this); | ||
99 | } | ||
100 | |||
101 | @Override | ||
102 | public void dump(PrintWriter writer) { | ||
103 | } | ||
104 | |||
105 | @Override | ||
106 | public void setLayersOffering(IBinder token, VmsLayersOffering offering) { | ||
107 | mHal.setPublisherLayersOffering(token, offering); | ||
108 | } | ||
109 | |||
110 | // Implements IVmsPublisherService interface. | ||
111 | @Override | ||
112 | public void publish(IBinder token, VmsLayer layer, int publisherId, byte[] payload) { | ||
113 | if (DBG) { | ||
114 | Log.d(TAG, "Publishing for layer: " + layer); | ||
115 | } | ||
116 | ICarImpl.assertVmsPublisherPermission(mContext); | ||
117 | |||
118 | // Send the message to application listeners. | ||
119 | Set<IVmsSubscriberClient> listeners = | ||
120 | mHal.getSubscribersForLayerFromPublisher(layer, publisherId); | ||
121 | |||
122 | if (DBG) { | ||
123 | Log.d(TAG, "Number of subscribed apps: " + listeners.size()); | ||
124 | } | ||
125 | for (IVmsSubscriberClient listener : listeners) { | ||
126 | try { | ||
127 | listener.onVmsMessageReceived(layer, payload); | ||
128 | } catch (RemoteException ex) { | ||
129 | Log.e(TAG, "unable to publish to listener: " + listener); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | // Send the message to HAL | ||
134 | if (mHal.isHalSubscribed(layer)) { | ||
135 | Log.d(TAG, "HAL is subscribed"); | ||
136 | mHal.setDataMessage(layer, payload); | ||
137 | } else { | ||
138 | Log.d(TAG, "HAL is NOT subscribed"); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | @Override | ||
143 | public VmsSubscriptionState getSubscriptions() { | ||
144 | ICarImpl.assertVmsPublisherPermission(mContext); | ||
145 | return mHal.getSubscriptionState(); | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public int getPublisherId(byte[] publisherInfo) { | ||
150 | ICarImpl.assertVmsPublisherPermission(mContext); | ||
151 | return mHal.getPublisherId(publisherInfo); | ||
152 | } | ||
153 | |||
154 | // Implements VmsHalListener interface | ||
155 | /** | ||
156 | * This method is only invoked by VmsHalService.notifyPublishers which is synchronized. | ||
157 | * Therefore this method only sees a non-decreasing sequence. | ||
158 | */ | ||
159 | @Override | ||
160 | public void onChange(VmsSubscriptionState subscriptionState) { | ||
161 | // Send the message to application listeners. | ||
162 | for (IVmsPublisherClient client : mPublisherManager.getClients()) { | ||
163 | try { | ||
164 | client.onVmsSubscriptionChange(subscriptionState); | ||
165 | } catch (RemoteException ex) { | ||
166 | Log.e(TAG, "unable to send notification to: " + client, ex); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * Keeps track of publishers that are using this service. | ||
173 | */ | ||
174 | private static class VmsPublisherManager { | ||
175 | /** | ||
176 | * Allows to modify mPublisherMap and mPublisherConnectionMap as a single unit. | ||
177 | */ | ||
178 | private final Object mLock = new Object(); | ||
179 | @GuardedBy("mLock") | ||
180 | private final Map<String, PublisherConnection> mPublisherConnectionMap = new HashMap<>(); | ||
181 | @GuardedBy("mLock") | ||
182 | private final Map<String, IVmsPublisherClient> mPublisherMap = new HashMap<>(); | ||
183 | private final WeakReference<VmsPublisherService> mPublisherService; | ||
184 | |||
185 | public VmsPublisherManager(VmsPublisherService publisherService) { | ||
186 | mPublisherService = new WeakReference<>(publisherService); | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * Tries to bind to a publisher. | ||
191 | * | ||
192 | * @param name publisher component name (e.g. android.car.vms.logger/.LoggingService). | ||
193 | */ | ||
194 | public void bind(ComponentName name) { | ||
195 | VmsPublisherService publisherService = mPublisherService.get(); | ||
196 | if (publisherService == null) return; | ||
197 | String publisherName = name.flattenToString(); | ||
198 | if (DBG) { | ||
199 | Log.d(TAG, "binding to: " + publisherName); | ||
200 | } | ||
201 | synchronized (mLock) { | ||
202 | if (mPublisherConnectionMap.containsKey(publisherName)) { | ||
203 | // Already registered, nothing to do. | ||
204 | return; | ||
205 | } | ||
206 | grantPermissions(name); | ||
207 | Intent intent = new Intent(); | ||
208 | intent.setComponent(name); | ||
209 | PublisherConnection connection = new PublisherConnection(); | ||
210 | if (publisherService.mContext.bindServiceAsUser(intent, connection, | ||
211 | Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { | ||
212 | mPublisherConnectionMap.put(publisherName, connection); | ||
213 | } else { | ||
214 | Log.e(TAG, "unable to bind to: " + publisherName); | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * Removes the publisher and associated connection. | ||
221 | * | ||
222 | * @param name publisher component name (e.g. android.car.vms.Logger). | ||
223 | */ | ||
224 | public void unbind(ComponentName name) { | ||
225 | VmsPublisherService publisherService = mPublisherService.get(); | ||
226 | if (publisherService == null) return; | ||
227 | String publisherName = name.flattenToString(); | ||
228 | if (DBG) { | ||
229 | Log.d(TAG, "unbinding from: " + publisherName); | ||
230 | } | ||
231 | synchronized (mLock) { | ||
232 | boolean found = mPublisherMap.remove(publisherName) != null; | ||
233 | if (found) { | ||
234 | PublisherConnection connection = mPublisherConnectionMap.get(publisherName); | ||
235 | publisherService.mContext.unbindService(connection); | ||
236 | mPublisherConnectionMap.remove(publisherName); | ||
237 | } else { | ||
238 | Log.e(TAG, "unbind: unknown publisher." + publisherName); | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * Returns the list of publishers currently registered. | ||
245 | * | ||
246 | * @return list of publishers. | ||
247 | */ | ||
248 | public List<IVmsPublisherClient> getClients() { | ||
249 | synchronized (mLock) { | ||
250 | return new ArrayList<>(mPublisherMap.values()); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | public void release() { | ||
255 | VmsPublisherService publisherService = mPublisherService.get(); | ||
256 | if (publisherService == null) return; | ||
257 | for (PublisherConnection connection : mPublisherConnectionMap.values()) { | ||
258 | publisherService.mContext.unbindService(connection); | ||
259 | } | ||
260 | mPublisherConnectionMap.clear(); | ||
261 | mPublisherMap.clear(); | ||
262 | } | ||
263 | |||
264 | private void grantPermissions(ComponentName component) { | ||
265 | VmsPublisherService publisherService = mPublisherService.get(); | ||
266 | if (publisherService == null) return; | ||
267 | final PackageManager packageManager = publisherService.mContext.getPackageManager(); | ||
268 | final String packageName = component.getPackageName(); | ||
269 | PackageInfo packageInfo; | ||
270 | try { | ||
271 | packageInfo = packageManager.getPackageInfo(packageName, | ||
272 | PackageManager.GET_PERMISSIONS); | ||
273 | } catch (PackageManager.NameNotFoundException e) { | ||
274 | Log.e(TAG, "Error getting package info for " + packageName, e); | ||
275 | return; | ||
276 | } | ||
277 | if (packageInfo.requestedPermissions == null) return; | ||
278 | for (String permission : packageInfo.requestedPermissions) { | ||
279 | if (!publisherService.mSafePermissions.contains(permission)) { | ||
280 | continue; | ||
281 | } | ||
282 | if (packageManager.checkPermission(permission, packageName) | ||
283 | == PackageManager.PERMISSION_GRANTED) { | ||
284 | continue; | ||
285 | } | ||
286 | try { | ||
287 | packageManager.grantRuntimePermission(packageName, permission, | ||
288 | UserHandle.SYSTEM); | ||
289 | Log.d(TAG, "Permission " + permission + " granted to " + packageName); | ||
290 | } catch (SecurityException | IllegalArgumentException e) { | ||
291 | Log.e(TAG, "Error while trying to grant " + permission + " to " + packageName, | ||
292 | e); | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | |||
297 | class PublisherConnection implements ServiceConnection { | ||
298 | |||
299 | private final IBinder mToken = new Binder(); | ||
300 | |||
301 | /** | ||
302 | * Once the service binds to a publisher service, the publisher binder is added to | ||
303 | * mPublisherMap | ||
304 | * and the publisher is configured to use this service. | ||
305 | */ | ||
306 | @Override | ||
307 | public void onServiceConnected(ComponentName name, IBinder binder) { | ||
308 | VmsPublisherService publisherService = mPublisherService.get(); | ||
309 | if (publisherService == null) return; | ||
310 | if (DBG) { | ||
311 | Log.d(TAG, "onServiceConnected, name: " + name + ", binder: " + binder); | ||
312 | } | ||
313 | IVmsPublisherClient service = IVmsPublisherClient.Stub.asInterface(binder); | ||
314 | synchronized (mLock) { | ||
315 | mPublisherMap.put(name.flattenToString(), service); | ||
316 | } | ||
317 | try { | ||
318 | service.setVmsPublisherService(mToken, publisherService); | ||
319 | } catch (RemoteException e) { | ||
320 | Log.e(TAG, "unable to configure publisher: " + name); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Tries to rebind to the publisher service. | ||
326 | */ | ||
327 | @Override | ||
328 | public void onServiceDisconnected(ComponentName name) { | ||
329 | String publisherName = name.flattenToString(); | ||
330 | Log.d(TAG, "onServiceDisconnected, name: " + publisherName); | ||
331 | VmsPublisherManager.this.unbind(name); | ||
332 | VmsPublisherManager.this.bind(name); | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | } | ||
diff --git a/service/src/com/android/car/VmsPublishersInfo.java b/service/src/com/android/car/VmsPublishersInfo.java deleted file mode 100644 index 04ee82f7..00000000 --- a/service/src/com/android/car/VmsPublishersInfo.java +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | |||
20 | import android.car.annotation.FutureFeature; | ||
21 | import java.util.HashMap; | ||
22 | import java.util.Map; | ||
23 | import java.util.List; | ||
24 | import java.util.ArrayList; | ||
25 | import java.util.Arrays; | ||
26 | import com.android.internal.annotations.GuardedBy; | ||
27 | import android.util.Log; | ||
28 | |||
29 | @FutureFeature | ||
30 | public class VmsPublishersInfo { | ||
31 | private static final String TAG = "VmsPublishersInfo"; | ||
32 | private static final boolean DBG = true; | ||
33 | private final Object mLock = new Object(); | ||
34 | @GuardedBy("mLock") | ||
35 | private final Map<InfoWrapper, Integer> mPublishersIds = new HashMap(); | ||
36 | @GuardedBy("mLock") | ||
37 | private final Map<Integer, byte[]> mPublishersInfo = new HashMap(); | ||
38 | |||
39 | private static class InfoWrapper { | ||
40 | private final byte[] mInfo; | ||
41 | |||
42 | public InfoWrapper(byte[] info) { | ||
43 | mInfo = info; | ||
44 | } | ||
45 | |||
46 | public byte[] getInfo() { | ||
47 | return mInfo; | ||
48 | } | ||
49 | |||
50 | @Override | ||
51 | public boolean equals(Object o) { | ||
52 | if (!(o instanceof InfoWrapper)) { | ||
53 | return false; | ||
54 | } | ||
55 | InfoWrapper p = (InfoWrapper) o; | ||
56 | return Arrays.equals(this.mInfo, p.mInfo); | ||
57 | } | ||
58 | |||
59 | @Override | ||
60 | public int hashCode() { | ||
61 | return Arrays.hashCode(mInfo); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * Returns the ID associated with the publisher info. When called for the first time for a | ||
67 | * publisher info will store the info and assign an ID | ||
68 | */ | ||
69 | public int getIdForInfo(byte[] publisherInfo) { | ||
70 | Integer publisherId; | ||
71 | InfoWrapper wrappedPublisherInfo = new InfoWrapper(publisherInfo); | ||
72 | synchronized (mLock) { | ||
73 | maybeAddPublisherInfoLocked(wrappedPublisherInfo); | ||
74 | publisherId = mPublishersIds.get(wrappedPublisherInfo); | ||
75 | } | ||
76 | if (DBG) { | ||
77 | Log.i(TAG, "Publisher ID is: " + publisherId); | ||
78 | } | ||
79 | return publisherId; | ||
80 | } | ||
81 | |||
82 | public byte[] getPublisherInfo(int publisherId) { | ||
83 | synchronized (mLock) { | ||
84 | return mPublishersInfo.get(publisherId).clone(); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | private void maybeAddPublisherInfoLocked(InfoWrapper wrappedPublisherInfo) { | ||
89 | if (!mPublishersIds.containsKey(wrappedPublisherInfo)) { | ||
90 | // Assign ID to the info | ||
91 | Integer publisherId = mPublishersIds.size(); | ||
92 | |||
93 | mPublishersIds.put(wrappedPublisherInfo, publisherId); | ||
94 | mPublishersInfo.put(publisherId, wrappedPublisherInfo.getInfo()); | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | |||
diff --git a/service/src/com/android/car/VmsRouting.java b/service/src/com/android/car/VmsRouting.java deleted file mode 100644 index 2e66781d..00000000 --- a/service/src/com/android/car/VmsRouting.java +++ /dev/null | |||
@@ -1,414 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.car.vms.IVmsSubscriberClient; | ||
21 | import android.car.vms.VmsAssociatedLayer; | ||
22 | import android.car.vms.VmsLayer; | ||
23 | import android.car.vms.VmsOperationRecorder; | ||
24 | import android.car.vms.VmsSubscriptionState; | ||
25 | |||
26 | import com.android.internal.annotations.GuardedBy; | ||
27 | |||
28 | import java.util.ArrayList; | ||
29 | import java.util.HashMap; | ||
30 | import java.util.HashSet; | ||
31 | import java.util.List; | ||
32 | import java.util.Map; | ||
33 | import java.util.Set; | ||
34 | import java.util.stream.Collectors; | ||
35 | |||
36 | /** | ||
37 | * Manages all the VMS subscriptions: | ||
38 | * + Subscriptions to data messages of individual layer + version. | ||
39 | * + Subscriptions to all data messages. | ||
40 | * + HAL subscriptions to layer + version. | ||
41 | */ | ||
42 | @FutureFeature | ||
43 | public class VmsRouting { | ||
44 | private final Object mLock = new Object(); | ||
45 | // A map of Layer + Version to subscribers. | ||
46 | @GuardedBy("mLock") | ||
47 | private Map<VmsLayer, Set<IVmsSubscriberClient>> mLayerSubscriptions = new HashMap<>(); | ||
48 | |||
49 | @GuardedBy("mLock") | ||
50 | private Map<VmsLayer, Map<Integer, Set<IVmsSubscriberClient>>> mLayerSubscriptionsToPublishers = | ||
51 | new HashMap<>(); | ||
52 | // A set of subscribers that are interested in any layer + version. | ||
53 | @GuardedBy("mLock") | ||
54 | private Set<IVmsSubscriberClient> mPromiscuousSubscribers = new HashSet<>(); | ||
55 | |||
56 | // A set of all the layers + versions the HAL is subscribed to. | ||
57 | @GuardedBy("mLock") | ||
58 | private Set<VmsLayer> mHalSubscriptions = new HashSet<>(); | ||
59 | |||
60 | @GuardedBy("mLock") | ||
61 | private Map<VmsLayer, Set<Integer>> mHalSubscriptionsToPublishers = new HashMap<>(); | ||
62 | // A sequence number that is increased every time the subscription state is modified. Note that | ||
63 | // modifying the list of promiscuous subscribers does not affect the subscription state. | ||
64 | @GuardedBy("mLock") | ||
65 | private int mSequenceNumber = 0; | ||
66 | |||
67 | /** | ||
68 | * Add a subscriber subscription to data messages from a VMS layer. | ||
69 | * | ||
70 | * @param subscriber a VMS subscriber. | ||
71 | * @param layer the layer subscribing to. | ||
72 | */ | ||
73 | public void addSubscription(IVmsSubscriberClient subscriber, VmsLayer layer) { | ||
74 | //TODO(b/36902947): revise if need to sync, and return value. | ||
75 | synchronized (mLock) { | ||
76 | ++mSequenceNumber; | ||
77 | // Get or create the list of subscribers for layer and version. | ||
78 | Set<IVmsSubscriberClient> subscribers = mLayerSubscriptions.get(layer); | ||
79 | |||
80 | if (subscribers == null) { | ||
81 | subscribers = new HashSet<>(); | ||
82 | mLayerSubscriptions.put(layer, subscribers); | ||
83 | } | ||
84 | // Add the subscriber to the list. | ||
85 | subscribers.add(subscriber); | ||
86 | VmsOperationRecorder.get().addSubscription(mSequenceNumber, layer); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * Add a subscriber subscription to all data messages. | ||
92 | * | ||
93 | * @param subscriber a VMS subscriber. | ||
94 | */ | ||
95 | public void addSubscription(IVmsSubscriberClient subscriber) { | ||
96 | synchronized (mLock) { | ||
97 | ++mSequenceNumber; | ||
98 | mPromiscuousSubscribers.add(subscriber); | ||
99 | VmsOperationRecorder.get().addPromiscuousSubscription(mSequenceNumber); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * Add a subscriber subscription to data messages from a VMS layer from a specific publisher. | ||
105 | * | ||
106 | * @param subscriber a VMS subscriber. | ||
107 | * @param layer the layer to subscribing to. | ||
108 | * @param publisherId the publisher ID. | ||
109 | */ | ||
110 | public void addSubscription(IVmsSubscriberClient subscriber, VmsLayer layer, int publisherId) { | ||
111 | synchronized (mLock) { | ||
112 | ++mSequenceNumber; | ||
113 | |||
114 | Map<Integer, Set<IVmsSubscriberClient>> publisherIdsToSubscribersForLayer = | ||
115 | mLayerSubscriptionsToPublishers.get(layer); | ||
116 | |||
117 | if (publisherIdsToSubscribersForLayer == null) { | ||
118 | publisherIdsToSubscribersForLayer = new HashMap<>(); | ||
119 | mLayerSubscriptionsToPublishers.put(layer, publisherIdsToSubscribersForLayer); | ||
120 | } | ||
121 | |||
122 | Set<IVmsSubscriberClient> subscribersForPublisher = | ||
123 | publisherIdsToSubscribersForLayer.get(publisherId); | ||
124 | |||
125 | if (subscribersForPublisher == null) { | ||
126 | subscribersForPublisher = new HashSet<>(); | ||
127 | publisherIdsToSubscribersForLayer.put(publisherId, subscribersForPublisher); | ||
128 | } | ||
129 | |||
130 | // Add the subscriber to the list. | ||
131 | subscribersForPublisher.add(subscriber); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * Remove a subscription for a layer + version and make sure to remove the key if there are no | ||
137 | * more subscribers. | ||
138 | * | ||
139 | * @param subscriber to remove. | ||
140 | * @param layer of the subscription. | ||
141 | */ | ||
142 | public void removeSubscription(IVmsSubscriberClient subscriber, VmsLayer layer) { | ||
143 | synchronized (mLock) { | ||
144 | ++mSequenceNumber; | ||
145 | Set<IVmsSubscriberClient> subscribers = mLayerSubscriptions.get(layer); | ||
146 | |||
147 | // If there are no subscribers we are done. | ||
148 | if (subscribers == null) { | ||
149 | return; | ||
150 | } | ||
151 | subscribers.remove(subscriber); | ||
152 | VmsOperationRecorder.get().removeSubscription(mSequenceNumber, layer); | ||
153 | |||
154 | // If there are no more subscribers then remove the list. | ||
155 | if (subscribers.isEmpty()) { | ||
156 | mLayerSubscriptions.remove(layer); | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * Remove a subscriber subscription to all data messages. | ||
163 | * | ||
164 | * @param subscriber a VMS subscriber. | ||
165 | */ | ||
166 | public void removeSubscription(IVmsSubscriberClient subscriber) { | ||
167 | synchronized (mLock) { | ||
168 | ++mSequenceNumber; | ||
169 | mPromiscuousSubscribers.remove(subscriber); | ||
170 | VmsOperationRecorder.get().removePromiscuousSubscription(mSequenceNumber); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Remove a subscription to data messages from a VMS layer from a specific publisher. | ||
176 | * | ||
177 | * @param subscriber a VMS subscriber. | ||
178 | * @param layer the layer to unsubscribing from. | ||
179 | * @param publisherId the publisher ID. | ||
180 | */ | ||
181 | public void removeSubscription(IVmsSubscriberClient subscriber, | ||
182 | VmsLayer layer, | ||
183 | int publisherId) { | ||
184 | synchronized (mLock) { | ||
185 | ++mSequenceNumber; | ||
186 | |||
187 | Map<Integer, Set<IVmsSubscriberClient>> subscribersToPublishers = | ||
188 | mLayerSubscriptionsToPublishers.get(layer); | ||
189 | |||
190 | if (subscribersToPublishers == null) { | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | Set<IVmsSubscriberClient> subscribers = subscribersToPublishers.get(publisherId); | ||
195 | |||
196 | if (subscribers == null) { | ||
197 | return; | ||
198 | } | ||
199 | subscribers.remove(subscriber); | ||
200 | |||
201 | if (subscribers.isEmpty()) { | ||
202 | subscribersToPublishers.remove(publisherId); | ||
203 | } | ||
204 | |||
205 | if (subscribersToPublishers.isEmpty()) { | ||
206 | mLayerSubscriptionsToPublishers.remove(layer); | ||
207 | } | ||
208 | } | ||
209 | } | ||
210 | |||
211 | /** | ||
212 | * Remove a subscriber from all routes (optional operation). | ||
213 | * | ||
214 | * @param subscriber a VMS subscriber. | ||
215 | */ | ||
216 | public void removeDeadSubscriber(IVmsSubscriberClient subscriber) { | ||
217 | synchronized (mLock) { | ||
218 | // Remove the subscriber from all the routes. | ||
219 | for (VmsLayer layer : mLayerSubscriptions.keySet()) { | ||
220 | removeSubscription(subscriber, layer); | ||
221 | } | ||
222 | // Remove the subscriber from the loggers. | ||
223 | removeSubscription(subscriber); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * Returns a list of all the subscribers for a layer from a publisher. This includes | ||
229 | * subscribers that subscribed to this layer from all publishers, subscribed to this layer | ||
230 | * from a specific publisher, and the promiscuous subscribers. | ||
231 | * | ||
232 | * @param layer The layer of the message. | ||
233 | * @param publisherId the ID of the client that published the message to be routed. | ||
234 | * @return a list of the subscribers. | ||
235 | */ | ||
236 | public Set<IVmsSubscriberClient> getSubscribersForLayerFromPublisher(VmsLayer layer, | ||
237 | int publisherId) { | ||
238 | Set<IVmsSubscriberClient> subscribers = new HashSet<>(); | ||
239 | synchronized (mLock) { | ||
240 | // Add the subscribers which explicitly subscribed to this layer | ||
241 | if (mLayerSubscriptions.containsKey(layer)) { | ||
242 | subscribers.addAll(mLayerSubscriptions.get(layer)); | ||
243 | } | ||
244 | |||
245 | // Add the subscribers which explicitly subscribed to this layer and publisher | ||
246 | if (mLayerSubscriptionsToPublishers.containsKey(layer)) { | ||
247 | if (mLayerSubscriptionsToPublishers.get(layer).containsKey(publisherId)) { | ||
248 | subscribers.addAll(mLayerSubscriptionsToPublishers.get(layer).get(publisherId)); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | // Add the promiscuous subscribers. | ||
253 | subscribers.addAll(mPromiscuousSubscribers); | ||
254 | } | ||
255 | return subscribers; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * Returns a list with all the subscribers. | ||
260 | */ | ||
261 | public Set<IVmsSubscriberClient> getAllSubscribers() { | ||
262 | Set<IVmsSubscriberClient> subscribers = new HashSet<>(); | ||
263 | synchronized (mLock) { | ||
264 | for (VmsLayer layer : mLayerSubscriptions.keySet()) { | ||
265 | subscribers.addAll(mLayerSubscriptions.get(layer)); | ||
266 | } | ||
267 | // Add the promiscuous subscribers. | ||
268 | subscribers.addAll(mPromiscuousSubscribers); | ||
269 | } | ||
270 | return subscribers; | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * Checks if a subscriber is subscribed to any messages. | ||
275 | * | ||
276 | * @param subscriber that may have subscription. | ||
277 | * @return true if the subscriber uis subscribed to messages. | ||
278 | */ | ||
279 | public boolean containsSubscriber(IVmsSubscriberClient subscriber) { | ||
280 | synchronized (mLock) { | ||
281 | // Check if subscriber is subscribed to a layer. | ||
282 | for (Set<IVmsSubscriberClient> layerSubscribers : mLayerSubscriptions.values()) { | ||
283 | if (layerSubscribers.contains(subscriber)) { | ||
284 | return true; | ||
285 | } | ||
286 | } | ||
287 | // Check is subscriber is subscribed to all data messages. | ||
288 | return mPromiscuousSubscribers.contains(subscriber); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * Add a layer and version to the HAL subscriptions. | ||
294 | * | ||
295 | * @param layer the HAL subscribes to. | ||
296 | */ | ||
297 | public void addHalSubscription(VmsLayer layer) { | ||
298 | synchronized (mLock) { | ||
299 | ++mSequenceNumber; | ||
300 | mHalSubscriptions.add(layer); | ||
301 | VmsOperationRecorder.get().addHalSubscription(mSequenceNumber, layer); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | public void addHalSubscriptionToPublisher(VmsLayer layer, int publisherId) { | ||
306 | synchronized (mLock) { | ||
307 | ++mSequenceNumber; | ||
308 | |||
309 | Set<Integer> publisherIdsForLayer = mHalSubscriptionsToPublishers.get(layer); | ||
310 | if (publisherIdsForLayer == null) { | ||
311 | publisherIdsForLayer = new HashSet<>(); | ||
312 | mHalSubscriptionsToPublishers.put(layer, publisherIdsForLayer); | ||
313 | } | ||
314 | publisherIdsForLayer.add(publisherId); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * remove a layer and version to the HAL subscriptions. | ||
320 | * | ||
321 | * @param layer the HAL unsubscribes from. | ||
322 | */ | ||
323 | public void removeHalSubscription(VmsLayer layer) { | ||
324 | synchronized (mLock) { | ||
325 | ++mSequenceNumber; | ||
326 | mHalSubscriptions.remove(layer); | ||
327 | VmsOperationRecorder.get().removeHalSubscription(mSequenceNumber, layer); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | public void removeHalSubscriptionToPublisher(VmsLayer layer, int publisherId) { | ||
332 | synchronized (mLock) { | ||
333 | ++mSequenceNumber; | ||
334 | |||
335 | Set<Integer> publisherIdsForLayer = mHalSubscriptionsToPublishers.get(layer); | ||
336 | if (publisherIdsForLayer == null) { | ||
337 | return; | ||
338 | } | ||
339 | publisherIdsForLayer.remove(publisherId); | ||
340 | |||
341 | if (publisherIdsForLayer.isEmpty()) { | ||
342 | mHalSubscriptionsToPublishers.remove(layer); | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * checks if the HAL is subscribed to a layer. | ||
349 | * | ||
350 | * @param layer | ||
351 | * @return true if the HAL is subscribed to layer. | ||
352 | */ | ||
353 | public boolean isHalSubscribed(VmsLayer layer) { | ||
354 | synchronized (mLock) { | ||
355 | return mHalSubscriptions.contains(layer); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | /** | ||
360 | * checks if there are subscribers to a layer. | ||
361 | * | ||
362 | * @param layer | ||
363 | * @return true if there are subscribers to layer. | ||
364 | */ | ||
365 | public boolean hasLayerSubscriptions(VmsLayer layer) { | ||
366 | synchronized (mLock) { | ||
367 | return mLayerSubscriptions.containsKey(layer) || mHalSubscriptions.contains(layer); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * returns true if there is already a subscription for the layer from publisherId. | ||
373 | * | ||
374 | * @param layer | ||
375 | * @param publisherId | ||
376 | * @return | ||
377 | */ | ||
378 | public boolean hasLayerFromPublisherSubscriptions(VmsLayer layer, int publisherId) { | ||
379 | synchronized (mLock) { | ||
380 | boolean hasClientSubscription = | ||
381 | mLayerSubscriptionsToPublishers.containsKey(layer) && | ||
382 | mLayerSubscriptionsToPublishers.get(layer).containsKey(publisherId); | ||
383 | |||
384 | boolean hasHalSubscription = mHalSubscriptionsToPublishers.containsKey(layer) && | ||
385 | mHalSubscriptionsToPublishers.get(layer).contains(publisherId); | ||
386 | |||
387 | return hasClientSubscription || hasHalSubscription; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * @return a Set of layers and versions which VMS clients are subscribed to. | ||
393 | */ | ||
394 | public VmsSubscriptionState getSubscriptionState() { | ||
395 | synchronized (mLock) { | ||
396 | Set<VmsLayer> layers = new HashSet<>(); | ||
397 | layers.addAll(mLayerSubscriptions.keySet()); | ||
398 | layers.addAll(mHalSubscriptions); | ||
399 | |||
400 | |||
401 | Set<VmsAssociatedLayer> layersFromPublishers = new HashSet<>(); | ||
402 | layersFromPublishers.addAll(mLayerSubscriptionsToPublishers.entrySet() | ||
403 | .stream() | ||
404 | .map(e -> new VmsAssociatedLayer(e.getKey(), e.getValue().keySet())) | ||
405 | .collect(Collectors.toSet())); | ||
406 | layersFromPublishers.addAll(mHalSubscriptionsToPublishers.entrySet() | ||
407 | .stream() | ||
408 | .map(e -> new VmsAssociatedLayer(e.getKey(), e.getValue())) | ||
409 | .collect(Collectors.toSet())); | ||
410 | |||
411 | return new VmsSubscriptionState(mSequenceNumber, layers, layersFromPublishers); | ||
412 | } | ||
413 | } | ||
414 | } \ No newline at end of file | ||
diff --git a/service/src/com/android/car/VmsSubscriberService.java b/service/src/com/android/car/VmsSubscriberService.java deleted file mode 100644 index 94f08445..00000000 --- a/service/src/com/android/car/VmsSubscriberService.java +++ /dev/null | |||
@@ -1,353 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | import android.car.Car; | ||
20 | import android.car.annotation.FutureFeature; | ||
21 | import android.car.vms.IVmsSubscriberClient; | ||
22 | import android.car.vms.IVmsSubscriberService; | ||
23 | import android.car.vms.VmsAssociatedLayer; | ||
24 | import android.car.vms.VmsLayer; | ||
25 | import android.content.Context; | ||
26 | import android.os.IBinder; | ||
27 | import android.os.RemoteException; | ||
28 | import android.util.Log; | ||
29 | |||
30 | import com.android.car.hal.VmsHalService; | ||
31 | import com.android.internal.annotations.GuardedBy; | ||
32 | |||
33 | import java.io.PrintWriter; | ||
34 | import java.util.ArrayList; | ||
35 | import java.util.Collections; | ||
36 | import java.util.HashMap; | ||
37 | import java.util.HashSet; | ||
38 | import java.util.List; | ||
39 | import java.util.Map; | ||
40 | import java.util.Set; | ||
41 | |||
42 | /** | ||
43 | * + Receives HAL updates by implementing VmsHalService.VmsHalListener. | ||
44 | * + Offers subscriber/publisher services by implementing IVmsService.Stub. | ||
45 | */ | ||
46 | @FutureFeature | ||
47 | public class VmsSubscriberService extends IVmsSubscriberService.Stub | ||
48 | implements CarServiceBase, VmsHalService.VmsHalSubscriberListener { | ||
49 | private static final boolean DBG = true; | ||
50 | private static final String PERMISSION = Car.PERMISSION_VMS_SUBSCRIBER; | ||
51 | private static final String TAG = "VmsSubscriberService"; | ||
52 | |||
53 | private final Context mContext; | ||
54 | private final VmsHalService mHal; | ||
55 | |||
56 | @GuardedBy("mSubscriberServiceLock") | ||
57 | private final VmsSubscribersManager mSubscribersManager = new VmsSubscribersManager(); | ||
58 | private final Object mSubscriberServiceLock = new Object(); | ||
59 | |||
60 | /** | ||
61 | * Keeps track of subscribers of this service. | ||
62 | */ | ||
63 | class VmsSubscribersManager { | ||
64 | /** | ||
65 | * Allows to modify mSubscriberMap and mListenerDeathRecipientMap as a single unit. | ||
66 | */ | ||
67 | private final Object mListenerManagerLock = new Object(); | ||
68 | @GuardedBy("mListenerManagerLock") | ||
69 | private final Map<IBinder, ListenerDeathRecipient> mListenerDeathRecipientMap = | ||
70 | new HashMap<>(); | ||
71 | @GuardedBy("mListenerManagerLock") | ||
72 | private final Map<IBinder, IVmsSubscriberClient> mSubscriberMap = new HashMap<>(); | ||
73 | |||
74 | class ListenerDeathRecipient implements IBinder.DeathRecipient { | ||
75 | private IBinder mSubscriberBinder; | ||
76 | |||
77 | ListenerDeathRecipient(IBinder subscriberBinder) { | ||
78 | mSubscriberBinder = subscriberBinder; | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * Listener died. Remove it from this service. | ||
83 | */ | ||
84 | @Override | ||
85 | public void binderDied() { | ||
86 | if (DBG) { | ||
87 | Log.d(TAG, "binderDied " + mSubscriberBinder); | ||
88 | } | ||
89 | |||
90 | // Get the Listener from the Binder | ||
91 | IVmsSubscriberClient subscriber = mSubscriberMap.get(mSubscriberBinder); | ||
92 | |||
93 | // Remove the subscriber subscriptions. | ||
94 | if (subscriber != null) { | ||
95 | Log.d(TAG, "Removing subscriptions for dead subscriber: " + subscriber); | ||
96 | mHal.removeDeadSubscriber(subscriber); | ||
97 | } else { | ||
98 | Log.d(TAG, "Handling dead binder with no matching subscriber"); | ||
99 | |||
100 | } | ||
101 | |||
102 | // Remove binder | ||
103 | VmsSubscribersManager.this.removeListener(mSubscriberBinder); | ||
104 | } | ||
105 | |||
106 | void release() { | ||
107 | mSubscriberBinder.unlinkToDeath(this, 0); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | public void release() { | ||
112 | for (ListenerDeathRecipient recipient : mListenerDeathRecipientMap.values()) { | ||
113 | recipient.release(); | ||
114 | } | ||
115 | mListenerDeathRecipientMap.clear(); | ||
116 | mSubscriberMap.clear(); | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Adds the subscriber and a death recipient associated to it. | ||
121 | * | ||
122 | * @param subscriber to be added. | ||
123 | * @throws IllegalArgumentException if the subscriber is null. | ||
124 | * @throws IllegalStateException if it was not possible to link a death recipient to the | ||
125 | * subscriber. | ||
126 | */ | ||
127 | public void add(IVmsSubscriberClient subscriber) { | ||
128 | ICarImpl.assertPermission(mContext, PERMISSION); | ||
129 | if (subscriber == null) { | ||
130 | Log.e(TAG, "register: subscriber is null."); | ||
131 | throw new IllegalArgumentException("subscriber cannot be null."); | ||
132 | } | ||
133 | if (DBG) { | ||
134 | Log.d(TAG, "register: " + subscriber); | ||
135 | } | ||
136 | IBinder subscriberBinder = subscriber.asBinder(); | ||
137 | synchronized (mListenerManagerLock) { | ||
138 | if (mSubscriberMap.containsKey(subscriberBinder)) { | ||
139 | // Already registered, nothing to do. | ||
140 | return; | ||
141 | } | ||
142 | ListenerDeathRecipient deathRecipient = | ||
143 | new ListenerDeathRecipient(subscriberBinder); | ||
144 | try { | ||
145 | subscriberBinder.linkToDeath(deathRecipient, 0); | ||
146 | } catch (RemoteException e) { | ||
147 | Log.e(TAG, "Failed to link death for recipient. ", e); | ||
148 | throw new IllegalStateException(Car.CAR_NOT_CONNECTED_EXCEPTION_MSG); | ||
149 | } | ||
150 | mListenerDeathRecipientMap.put(subscriberBinder, deathRecipient); | ||
151 | mSubscriberMap.put(subscriberBinder, subscriber); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * Removes the subscriber and associated death recipient. | ||
157 | * | ||
158 | * @param subscriber to be removed. | ||
159 | * @throws IllegalArgumentException if subscriber is null. | ||
160 | */ | ||
161 | public void remove(IVmsSubscriberClient subscriber) { | ||
162 | if (DBG) { | ||
163 | Log.d(TAG, "unregisterListener"); | ||
164 | } | ||
165 | ICarImpl.assertPermission(mContext, PERMISSION); | ||
166 | if (subscriber == null) { | ||
167 | Log.e(TAG, "unregister: subscriber is null."); | ||
168 | throw new IllegalArgumentException("Listener is null"); | ||
169 | } | ||
170 | IBinder subscriberBinder = subscriber.asBinder(); | ||
171 | removeListener(subscriberBinder); | ||
172 | } | ||
173 | |||
174 | // Removes the subscriberBinder from the current state. | ||
175 | // The function assumes that binder will exist both in subscriber and death recipients list. | ||
176 | private void removeListener(IBinder subscriberBinder) { | ||
177 | synchronized (mListenerManagerLock) { | ||
178 | boolean found = mSubscriberMap.remove(subscriberBinder) != null; | ||
179 | if (found) { | ||
180 | mListenerDeathRecipientMap.get(subscriberBinder).release(); | ||
181 | mListenerDeathRecipientMap.remove(subscriberBinder); | ||
182 | } else { | ||
183 | Log.e(TAG, "removeListener: subscriber was not previously registered."); | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * Returns list of subscribers currently registered. | ||
190 | * | ||
191 | * @return list of subscribers. | ||
192 | */ | ||
193 | public List<IVmsSubscriberClient> getListeners() { | ||
194 | synchronized (mListenerManagerLock) { | ||
195 | return new ArrayList<>(mSubscriberMap.values()); | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | public VmsSubscriberService(Context context, VmsHalService hal) { | ||
201 | mContext = context; | ||
202 | mHal = hal; | ||
203 | } | ||
204 | |||
205 | // Implements CarServiceBase interface. | ||
206 | @Override | ||
207 | public void init() { | ||
208 | mHal.addSubscriberListener(this); | ||
209 | } | ||
210 | |||
211 | @Override | ||
212 | public void release() { | ||
213 | mSubscribersManager.release(); | ||
214 | mHal.removeSubscriberListener(this); | ||
215 | } | ||
216 | |||
217 | @Override | ||
218 | public void dump(PrintWriter writer) { | ||
219 | } | ||
220 | |||
221 | // Implements IVmsService interface. | ||
222 | @Override | ||
223 | public void addVmsSubscriberToNotifications(IVmsSubscriberClient subscriber) { | ||
224 | synchronized (mSubscriberServiceLock) { | ||
225 | // Add the subscriber so it can subscribe. | ||
226 | mSubscribersManager.add(subscriber); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | @Override | ||
231 | public void removeVmsSubscriberToNotifications(IVmsSubscriberClient subscriber) { | ||
232 | synchronized (mSubscriberServiceLock) { | ||
233 | if (mHal.containsSubscriber(subscriber)) { | ||
234 | throw new IllegalArgumentException("Subscriber has active subscriptions."); | ||
235 | } | ||
236 | mSubscribersManager.remove(subscriber); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | @Override | ||
241 | public void addVmsSubscriber(IVmsSubscriberClient subscriber, VmsLayer layer) { | ||
242 | synchronized (mSubscriberServiceLock) { | ||
243 | // Add the subscriber so it can subscribe. | ||
244 | mSubscribersManager.add(subscriber); | ||
245 | |||
246 | // Add the subscription for the layer. | ||
247 | mHal.addSubscription(subscriber, layer); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | @Override | ||
252 | public void removeVmsSubscriber(IVmsSubscriberClient subscriber, VmsLayer layer) { | ||
253 | synchronized (mSubscriberServiceLock) { | ||
254 | // Remove the subscription. | ||
255 | mHal.removeSubscription(subscriber, layer); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | @Override | ||
260 | public void addVmsSubscriberToPublisher(IVmsSubscriberClient subscriber, | ||
261 | VmsLayer layer, | ||
262 | int publisherId) { | ||
263 | synchronized (mSubscriberServiceLock) { | ||
264 | // Add the subscriber so it can subscribe. | ||
265 | mSubscribersManager.add(subscriber); | ||
266 | |||
267 | // Add the subscription for the layer. | ||
268 | mHal.addSubscription(subscriber, layer, publisherId); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | @Override | ||
273 | public void removeVmsSubscriberToPublisher(IVmsSubscriberClient subscriber, | ||
274 | VmsLayer layer, | ||
275 | int publisherId) { | ||
276 | synchronized (mSubscriberServiceLock) { | ||
277 | // Remove the subscription. | ||
278 | mHal.removeSubscription(subscriber, layer, publisherId); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | @Override | ||
283 | public void addVmsSubscriberPassive(IVmsSubscriberClient subscriber) { | ||
284 | synchronized (mSubscriberServiceLock) { | ||
285 | mSubscribersManager.add(subscriber); | ||
286 | mHal.addSubscription(subscriber); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | @Override | ||
291 | public void removeVmsSubscriberPassive(IVmsSubscriberClient subscriber) { | ||
292 | synchronized (mSubscriberServiceLock) { | ||
293 | // Remove the subscription. | ||
294 | mHal.removeSubscription(subscriber); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | @Override | ||
299 | public byte[] getPublisherInfo(int publisherId) { | ||
300 | synchronized (mSubscriberServiceLock) { | ||
301 | return mHal.getPublisherInfo(publisherId); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | @Override | ||
306 | public List<VmsLayer> getAvailableLayers() { | ||
307 | //TODO(asafro): return the list of available layers once logic is implemented. | ||
308 | return Collections.emptyList(); | ||
309 | } | ||
310 | |||
311 | // Implements VmsHalSubscriberListener interface | ||
312 | @Override | ||
313 | public void onDataMessage(VmsLayer layer, int publisherId, byte[] payload) { | ||
314 | if (DBG) { | ||
315 | Log.d(TAG, "Publishing a message for layer: " + layer); | ||
316 | } | ||
317 | |||
318 | Set<IVmsSubscriberClient> subscribers = | ||
319 | mHal.getSubscribersForLayerFromPublisher(layer, publisherId); | ||
320 | |||
321 | for (IVmsSubscriberClient subscriber : subscribers) { | ||
322 | try { | ||
323 | subscriber.onVmsMessageReceived(layer, payload); | ||
324 | } catch (RemoteException e) { | ||
325 | // If we could not send a record, its likely the connection snapped. Let the binder | ||
326 | // death handle the situation. | ||
327 | Log.e(TAG, "onVmsMessageReceived calling failed: ", e); | ||
328 | } | ||
329 | } | ||
330 | } | ||
331 | |||
332 | @Override | ||
333 | public void onLayersAvaiabilityChange(List<VmsAssociatedLayer> availableLayers) { | ||
334 | if (DBG) { | ||
335 | Log.d(TAG, "Publishing layers availability change: " + availableLayers); | ||
336 | } | ||
337 | |||
338 | Set<IVmsSubscriberClient> subscribers; | ||
339 | synchronized (mSubscriberServiceLock) { | ||
340 | subscribers = new HashSet<>(mSubscribersManager.getListeners()); | ||
341 | } | ||
342 | |||
343 | for (IVmsSubscriberClient subscriber : subscribers) { | ||
344 | try { | ||
345 | subscriber.onLayersAvailabilityChanged(availableLayers); | ||
346 | } catch (RemoteException e) { | ||
347 | // If we could not send a record, its likely the connection snapped. Let the binder | ||
348 | // death handle the situation. | ||
349 | Log.e(TAG, "onLayersAvailabilityChanged calling failed: ", e); | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | } | ||
diff --git a/service/src/com/android/car/hal/VehicleHal.java b/service/src/com/android/car/hal/VehicleHal.java index 21f8f511..44c81d7f 100644 --- a/service/src/com/android/car/hal/VehicleHal.java +++ b/service/src/com/android/car/hal/VehicleHal.java | |||
@@ -80,8 +80,6 @@ public class VehicleHal extends IVehicleCallback.Stub { | |||
80 | private final VendorExtensionHalService mVendorExtensionHal; | 80 | private final VendorExtensionHalService mVendorExtensionHal; |
81 | private DiagnosticHalService mDiagnosticHal = null; | 81 | private DiagnosticHalService mDiagnosticHal = null; |
82 | 82 | ||
83 | @FutureFeature | ||
84 | private VmsHalService mVmsHal; | ||
85 | 83 | ||
86 | 84 | ||
87 | /** Might be re-assigned if Vehicle HAL is reconnected. */ | 85 | /** Might be re-assigned if Vehicle HAL is reconnected. */ |
@@ -108,9 +106,6 @@ public class VehicleHal extends IVehicleCallback.Stub { | |||
108 | mHvacHal = new HvacHalService(this); | 106 | mHvacHal = new HvacHalService(this); |
109 | mInputHal = new InputHalService(this); | 107 | mInputHal = new InputHalService(this); |
110 | mVendorExtensionHal = new VendorExtensionHalService(this); | 108 | mVendorExtensionHal = new VendorExtensionHalService(this); |
111 | if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
112 | mVmsHal = new VmsHalService(this); | ||
113 | } | ||
114 | mDiagnosticHal = new DiagnosticHalService(this); | 109 | mDiagnosticHal = new DiagnosticHalService(this); |
115 | mAllServices.addAll(Arrays.asList(mPowerHal, | 110 | mAllServices.addAll(Arrays.asList(mPowerHal, |
116 | mSensorHal, | 111 | mSensorHal, |
@@ -122,9 +117,6 @@ public class VehicleHal extends IVehicleCallback.Stub { | |||
122 | mInputHal, | 117 | mInputHal, |
123 | mVendorExtensionHal, | 118 | mVendorExtensionHal, |
124 | mDiagnosticHal)); | 119 | mDiagnosticHal)); |
125 | if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
126 | mAllServices.add(mVmsHal); | ||
127 | } | ||
128 | 120 | ||
129 | mHalClient = new HalClient(vehicle, mHandlerThread.getLooper(), this /*IVehicleCallback*/); | 121 | mHalClient = new HalClient(vehicle, mHandlerThread.getLooper(), this /*IVehicleCallback*/); |
130 | } | 122 | } |
@@ -146,10 +138,6 @@ public class VehicleHal extends IVehicleCallback.Stub { | |||
146 | mVendorExtensionHal = null; | 138 | mVendorExtensionHal = null; |
147 | mDiagnosticHal = null; | 139 | mDiagnosticHal = null; |
148 | 140 | ||
149 | if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
150 | mVmsHal = null; | ||
151 | } | ||
152 | |||
153 | mHalClient = halClient; | 141 | mHalClient = halClient; |
154 | } | 142 | } |
155 | 143 | ||
@@ -169,7 +157,6 @@ public class VehicleHal extends IVehicleCallback.Stub { | |||
169 | mHvacHal = hvacHal; | 157 | mHvacHal = hvacHal; |
170 | mInputHal = null; | 158 | mInputHal = null; |
171 | mVendorExtensionHal = null; | 159 | mVendorExtensionHal = null; |
172 | mVmsHal = null; | ||
173 | mHalClient = halClient; | 160 | mHalClient = halClient; |
174 | mDiagnosticHal = diagnosticHal; | 161 | mDiagnosticHal = diagnosticHal; |
175 | } | 162 | } |
@@ -281,9 +268,6 @@ public class VehicleHal extends IVehicleCallback.Stub { | |||
281 | return mVendorExtensionHal; | 268 | return mVendorExtensionHal; |
282 | } | 269 | } |
283 | 270 | ||
284 | @FutureFeature | ||
285 | public VmsHalService getVmsHal() { return mVmsHal; } | ||
286 | |||
287 | private void assertServiceOwnerLocked(HalServiceBase service, int property) { | 271 | private void assertServiceOwnerLocked(HalServiceBase service, int property) { |
288 | if (service != mPropertyHandlers.get(property)) { | 272 | if (service != mPropertyHandlers.get(property)) { |
289 | throw new IllegalArgumentException("Property 0x" + toHexString(property) | 273 | throw new IllegalArgumentException("Property 0x" + toHexString(property) |
diff --git a/service/src/com/android/car/hal/VmsHalService.java b/service/src/com/android/car/hal/VmsHalService.java deleted file mode 100644 index d20a453f..00000000 --- a/service/src/com/android/car/hal/VmsHalService.java +++ /dev/null | |||
@@ -1,850 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | package com.android.car.hal; | ||
17 | |||
18 | import static com.android.car.CarServiceUtils.toByteArray; | ||
19 | import static java.lang.Integer.toHexString; | ||
20 | |||
21 | import android.car.VehicleAreaType; | ||
22 | import android.car.annotation.FutureFeature; | ||
23 | import android.car.vms.IVmsSubscriberClient; | ||
24 | import android.car.vms.VmsLayer; | ||
25 | import android.car.vms.VmsAssociatedLayer; | ||
26 | import android.car.vms.VmsLayerDependency; | ||
27 | import android.car.vms.VmsLayersOffering; | ||
28 | import android.car.vms.VmsOperationRecorder; | ||
29 | import android.car.vms.VmsSubscriptionState; | ||
30 | import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig; | ||
31 | import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; | ||
32 | import android.hardware.automotive.vehicle.V2_0.VehicleProperty; | ||
33 | import android.hardware.automotive.vehicle.V2_0.VmsBaseMessageIntegerValuesIndex; | ||
34 | import android.hardware.automotive.vehicle.V2_0.VmsMessageType; | ||
35 | import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerAndPublisherIdIntegerValuesIndex; | ||
36 | import android.hardware.automotive.vehicle.V2_0.VmsOfferingMessageIntegerValuesIndex; | ||
37 | import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex; | ||
38 | import android.os.Binder; | ||
39 | import android.os.IBinder; | ||
40 | import android.util.Log; | ||
41 | import com.android.car.CarLog; | ||
42 | import com.android.car.VmsLayersAvailability; | ||
43 | import com.android.car.VmsPublishersInfo; | ||
44 | import com.android.car.VmsRouting; | ||
45 | import com.android.internal.annotations.GuardedBy; | ||
46 | |||
47 | import java.io.PrintWriter; | ||
48 | import java.util.Arrays; | ||
49 | import java.util.ArrayList; | ||
50 | import java.util.Collection; | ||
51 | import java.util.Collections; | ||
52 | import java.util.HashMap; | ||
53 | import java.util.HashSet; | ||
54 | import java.util.LinkedList; | ||
55 | import java.util.List; | ||
56 | import java.util.Map; | ||
57 | import java.util.Set; | ||
58 | import java.util.concurrent.CopyOnWriteArrayList; | ||
59 | |||
60 | /** | ||
61 | * This is a glue layer between the VehicleHal and the VmsService. It sends VMS properties back and | ||
62 | * forth. | ||
63 | */ | ||
64 | @FutureFeature | ||
65 | public class VmsHalService extends HalServiceBase { | ||
66 | |||
67 | private static final boolean DBG = true; | ||
68 | private static final int HAL_PROPERTY_ID = VehicleProperty.VEHICLE_MAP_SERVICE; | ||
69 | private static final String TAG = "VmsHalService"; | ||
70 | |||
71 | private final static List<Integer> AVAILABILITY_MESSAGE_TYPES = Collections.unmodifiableList( | ||
72 | Arrays.asList( | ||
73 | VmsMessageType.AVAILABILITY_RESPONSE, | ||
74 | VmsMessageType.AVAILABILITY_CHANGE)); | ||
75 | |||
76 | private boolean mIsSupported = false; | ||
77 | private CopyOnWriteArrayList<VmsHalPublisherListener> mPublisherListeners = | ||
78 | new CopyOnWriteArrayList<>(); | ||
79 | private CopyOnWriteArrayList<VmsHalSubscriberListener> mSubscriberListeners = | ||
80 | new CopyOnWriteArrayList<>(); | ||
81 | |||
82 | private final IBinder mHalPublisherToken = new Binder(); | ||
83 | private final VehicleHal mVehicleHal; | ||
84 | |||
85 | private final Object mLock = new Object(); | ||
86 | private final VmsRouting mRouting = new VmsRouting(); | ||
87 | @GuardedBy("mLock") | ||
88 | private final Map<IBinder, VmsLayersOffering> mOfferings = new HashMap<>(); | ||
89 | @GuardedBy("mLock") | ||
90 | private final VmsLayersAvailability mAvailableLayers = new VmsLayersAvailability(); | ||
91 | private final VmsPublishersInfo mPublishersInfo = new VmsPublishersInfo(); | ||
92 | |||
93 | /** | ||
94 | * The VmsPublisherService implements this interface to receive data from the HAL. | ||
95 | */ | ||
96 | public interface VmsHalPublisherListener { | ||
97 | void onChange(VmsSubscriptionState subscriptionState); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * The VmsSubscriberService implements this interface to receive data from the HAL. | ||
102 | */ | ||
103 | public interface VmsHalSubscriberListener { | ||
104 | // Notifies the listener on a data Message from a publisher. | ||
105 | void onDataMessage(VmsLayer layer, int publisherId, byte[] payload); | ||
106 | |||
107 | // Notifies the listener on a change in available layers. | ||
108 | void onLayersAvaiabilityChange(List<VmsAssociatedLayer> availableLayers); | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * The VmsService implements this interface to receive data from the HAL. | ||
113 | */ | ||
114 | protected VmsHalService(VehicleHal vehicleHal) { | ||
115 | mVehicleHal = vehicleHal; | ||
116 | if (DBG) { | ||
117 | Log.d(TAG, "started VmsHalService!"); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | public void addPublisherListener(VmsHalPublisherListener listener) { | ||
122 | mPublisherListeners.add(listener); | ||
123 | } | ||
124 | |||
125 | public void addSubscriberListener(VmsHalSubscriberListener listener) { | ||
126 | mSubscriberListeners.add(listener); | ||
127 | } | ||
128 | |||
129 | public void removePublisherListener(VmsHalPublisherListener listener) { | ||
130 | mPublisherListeners.remove(listener); | ||
131 | } | ||
132 | |||
133 | public void removeSubscriberListener(VmsHalSubscriberListener listener) { | ||
134 | mSubscriberListeners.remove(listener); | ||
135 | } | ||
136 | |||
137 | public void addSubscription(IVmsSubscriberClient listener, VmsLayer layer) { | ||
138 | boolean firstSubscriptionForLayer = false; | ||
139 | synchronized (mLock) { | ||
140 | // Check if publishers need to be notified about this change in subscriptions. | ||
141 | firstSubscriptionForLayer = !mRouting.hasLayerSubscriptions(layer); | ||
142 | |||
143 | // Add the listeners subscription to the layer | ||
144 | mRouting.addSubscription(listener, layer); | ||
145 | } | ||
146 | if (firstSubscriptionForLayer) { | ||
147 | notifyHalPublishers(layer, true); | ||
148 | notifyClientPublishers(); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | public void removeSubscription(IVmsSubscriberClient listener, VmsLayer layer) { | ||
153 | boolean layerHasSubscribers = true; | ||
154 | synchronized (mLock) { | ||
155 | if (!mRouting.hasLayerSubscriptions(layer)) { | ||
156 | Log.i(TAG, "Trying to remove a layer with no subscription: " + layer); | ||
157 | return; | ||
158 | } | ||
159 | |||
160 | // Remove the listeners subscription to the layer | ||
161 | mRouting.removeSubscription(listener, layer); | ||
162 | |||
163 | // Check if publishers need to be notified about this change in subscriptions. | ||
164 | layerHasSubscribers = mRouting.hasLayerSubscriptions(layer); | ||
165 | } | ||
166 | if (!layerHasSubscribers) { | ||
167 | notifyHalPublishers(layer, false); | ||
168 | notifyClientPublishers(); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | public void addSubscription(IVmsSubscriberClient listener) { | ||
173 | synchronized (mLock) { | ||
174 | mRouting.addSubscription(listener); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | public void removeSubscription(IVmsSubscriberClient listener) { | ||
179 | synchronized (mLock) { | ||
180 | mRouting.removeSubscription(listener); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | public void addSubscription(IVmsSubscriberClient listener, VmsLayer layer, int publisherId) { | ||
185 | boolean firstSubscriptionForLayer = false; | ||
186 | synchronized (mLock) { | ||
187 | // Check if publishers need to be notified about this change in subscriptions. | ||
188 | firstSubscriptionForLayer = !(mRouting.hasLayerSubscriptions(layer) || | ||
189 | mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId)); | ||
190 | |||
191 | // Add the listeners subscription to the layer | ||
192 | mRouting.addSubscription(listener, layer, publisherId); | ||
193 | } | ||
194 | if (firstSubscriptionForLayer) { | ||
195 | notifyHalPublishers(layer, true); | ||
196 | notifyClientPublishers(); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | public void removeSubscription(IVmsSubscriberClient listener, VmsLayer layer, int publisherId) { | ||
201 | boolean layerHasSubscribers = true; | ||
202 | synchronized (mLock) { | ||
203 | if (!mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId)) { | ||
204 | Log.i(TAG, "Trying to remove a layer with no subscription: " + | ||
205 | layer + ", publisher ID:" + publisherId); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | // Remove the listeners subscription to the layer | ||
210 | mRouting.removeSubscription(listener, layer, publisherId); | ||
211 | |||
212 | // Check if publishers need to be notified about this change in subscriptions. | ||
213 | layerHasSubscribers = mRouting.hasLayerSubscriptions(layer) || | ||
214 | mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId); | ||
215 | } | ||
216 | if (!layerHasSubscribers) { | ||
217 | notifyHalPublishers(layer, false); | ||
218 | notifyClientPublishers(); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | public void removeDeadSubscriber(IVmsSubscriberClient listener) { | ||
223 | synchronized (mLock) { | ||
224 | mRouting.removeDeadSubscriber(listener); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | public Set<IVmsSubscriberClient> getSubscribersForLayerFromPublisher(VmsLayer layer, | ||
229 | int publisherId) { | ||
230 | synchronized (mLock) { | ||
231 | return mRouting.getSubscribersForLayerFromPublisher(layer, publisherId); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | public Set<IVmsSubscriberClient> getAllSubscribers() { | ||
236 | synchronized (mLock) { | ||
237 | return mRouting.getAllSubscribers(); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | public boolean isHalSubscribed(VmsLayer layer) { | ||
242 | synchronized (mLock) { | ||
243 | return mRouting.isHalSubscribed(layer); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | public VmsSubscriptionState getSubscriptionState() { | ||
248 | synchronized (mLock) { | ||
249 | return mRouting.getSubscriptionState(); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * Assigns an idempotent ID for publisherInfo and stores it. The idempotency in this case means | ||
255 | * that the same publisherInfo will always, within a trip of the vehicle, return the same ID. | ||
256 | * The publisherInfo should be static for a binary and should only change as part of a software | ||
257 | * update. The publisherInfo is a serialized proto message which VMS clients can interpret. | ||
258 | */ | ||
259 | public int getPublisherId(byte[] publisherInfo) { | ||
260 | if (DBG) { | ||
261 | Log.i(TAG, "Getting publisher static ID"); | ||
262 | } | ||
263 | synchronized (mLock) { | ||
264 | return mPublishersInfo.getIdForInfo(publisherInfo); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | public byte[] getPublisherInfo(int publisherId) { | ||
269 | if (DBG) { | ||
270 | Log.i(TAG, "Getting information for publisher ID: " + publisherId); | ||
271 | } | ||
272 | synchronized (mLock) { | ||
273 | return mPublishersInfo.getPublisherInfo(publisherId); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | private void addHalSubscription(VmsLayer layer) { | ||
278 | boolean firstSubscriptionForLayer = true; | ||
279 | synchronized (mLock) { | ||
280 | // Check if publishers need to be notified about this change in subscriptions. | ||
281 | firstSubscriptionForLayer = !mRouting.hasLayerSubscriptions(layer); | ||
282 | |||
283 | // Add the listeners subscription to the layer | ||
284 | mRouting.addHalSubscription(layer); | ||
285 | } | ||
286 | if (firstSubscriptionForLayer) { | ||
287 | notifyHalPublishers(layer, true); | ||
288 | notifyClientPublishers(); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | private void addHalSubscriptionToPublisher(VmsLayer layer, int publisherId) { | ||
293 | boolean firstSubscriptionForLayer = true; | ||
294 | synchronized (mLock) { | ||
295 | // Check if publishers need to be notified about this change in subscriptions. | ||
296 | firstSubscriptionForLayer = !(mRouting.hasLayerSubscriptions(layer) || | ||
297 | mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId)); | ||
298 | |||
299 | // Add the listeners subscription to the layer | ||
300 | mRouting.addHalSubscriptionToPublisher(layer, publisherId); | ||
301 | } | ||
302 | if (firstSubscriptionForLayer) { | ||
303 | notifyHalPublishers(layer, publisherId, true); | ||
304 | notifyClientPublishers(); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | private void removeHalSubscription(VmsLayer layer) { | ||
309 | boolean layerHasSubscribers = true; | ||
310 | synchronized (mLock) { | ||
311 | if (!mRouting.hasLayerSubscriptions(layer)) { | ||
312 | Log.i(TAG, "Trying to remove a layer with no subscription: " + layer); | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | // Remove the listeners subscription to the layer | ||
317 | mRouting.removeHalSubscription(layer); | ||
318 | |||
319 | // Check if publishers need to be notified about this change in subscriptions. | ||
320 | layerHasSubscribers = mRouting.hasLayerSubscriptions(layer); | ||
321 | } | ||
322 | if (!layerHasSubscribers) { | ||
323 | notifyHalPublishers(layer, false); | ||
324 | notifyClientPublishers(); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | public void removeHalSubscriptionFromPublisher(VmsLayer layer, int publisherId) { | ||
329 | boolean layerHasSubscribers = true; | ||
330 | synchronized (mLock) { | ||
331 | if (!mRouting.hasLayerSubscriptions(layer)) { | ||
332 | Log.i(TAG, "Trying to remove a layer with no subscription: " + layer); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | // Remove the listeners subscription to the layer | ||
337 | mRouting.removeHalSubscriptionToPublisher(layer, publisherId); | ||
338 | |||
339 | // Check if publishers need to be notified about this change in subscriptions. | ||
340 | layerHasSubscribers = mRouting.hasLayerSubscriptions(layer) || | ||
341 | mRouting.hasLayerFromPublisherSubscriptions(layer, publisherId); | ||
342 | } | ||
343 | if (!layerHasSubscribers) { | ||
344 | notifyHalPublishers(layer, publisherId, false); | ||
345 | notifyClientPublishers(); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | public boolean containsSubscriber(IVmsSubscriberClient subscriber) { | ||
350 | synchronized (mLock) { | ||
351 | return mRouting.containsSubscriber(subscriber); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | public void setPublisherLayersOffering(IBinder publisherToken, VmsLayersOffering offering) { | ||
356 | Set<VmsAssociatedLayer> availableLayers = Collections.EMPTY_SET; | ||
357 | synchronized (mLock) { | ||
358 | updateOffering(publisherToken, offering); | ||
359 | VmsOperationRecorder.get().setPublisherLayersOffering(offering); | ||
360 | availableLayers = mAvailableLayers.getAvailableLayers(); | ||
361 | } | ||
362 | notifyOfAvailabilityChange(availableLayers); | ||
363 | } | ||
364 | |||
365 | public Set<VmsAssociatedLayer> getAvailableLayers() { | ||
366 | //TODO(b/36872877): wrap available layers in VmsAvailabilityState similar to VmsSubscriptionState. | ||
367 | synchronized (mLock) { | ||
368 | return mAvailableLayers.getAvailableLayers(); | ||
369 | } | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * Notify all the publishers and the HAL on subscription changes regardless of who triggered | ||
374 | * the change. | ||
375 | * | ||
376 | * @param layer layer which is being subscribed to or unsubscribed from. | ||
377 | * @param hasSubscribers indicates if the notification is for subscription or unsubscription. | ||
378 | */ | ||
379 | private void notifyHalPublishers(VmsLayer layer, boolean hasSubscribers) { | ||
380 | // notify the HAL | ||
381 | setSubscriptionRequest(layer, hasSubscribers); | ||
382 | } | ||
383 | |||
384 | private void notifyHalPublishers(VmsLayer layer, int publisherId, boolean hasSubscribers) { | ||
385 | // notify the HAL | ||
386 | setSubscriptionToPublisherRequest(layer, publisherId, hasSubscribers); | ||
387 | } | ||
388 | |||
389 | private void notifyClientPublishers() { | ||
390 | // Notify the App publishers | ||
391 | for (VmsHalPublisherListener listener : mPublisherListeners) { | ||
392 | // Besides the list of layers, also a timestamp is provided to the clients. | ||
393 | // They should ignore any notification with a timestamp that is older than the most | ||
394 | // recent timestamp they have seen. | ||
395 | listener.onChange(getSubscriptionState()); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | /** | ||
400 | * Notify all the subscribers and the HAL on layers availability change. | ||
401 | * | ||
402 | * @param availableLayers the layers which publishers claim they made publish. | ||
403 | */ | ||
404 | private void notifyOfAvailabilityChange(Set<VmsAssociatedLayer> availableLayers) { | ||
405 | // notify the HAL | ||
406 | notifyAvailabilityChangeToHal(availableLayers); | ||
407 | |||
408 | // Notify the App subscribers | ||
409 | for (VmsHalSubscriberListener listener : mSubscriberListeners) { | ||
410 | listener.onLayersAvaiabilityChange(new ArrayList<>(availableLayers)); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | @Override | ||
415 | public void init() { | ||
416 | if (DBG) { | ||
417 | Log.d(TAG, "init()"); | ||
418 | } | ||
419 | if (mIsSupported) { | ||
420 | mVehicleHal.subscribeProperty(this, HAL_PROPERTY_ID); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | @Override | ||
425 | public void release() { | ||
426 | if (DBG) { | ||
427 | Log.d(TAG, "release()"); | ||
428 | } | ||
429 | if (mIsSupported) { | ||
430 | mVehicleHal.unsubscribeProperty(this, HAL_PROPERTY_ID); | ||
431 | } | ||
432 | mPublisherListeners.clear(); | ||
433 | mSubscriberListeners.clear(); | ||
434 | } | ||
435 | |||
436 | @Override | ||
437 | public Collection<VehiclePropConfig> takeSupportedProperties( | ||
438 | Collection<VehiclePropConfig> allProperties) { | ||
439 | List<VehiclePropConfig> taken = new LinkedList<>(); | ||
440 | for (VehiclePropConfig p : allProperties) { | ||
441 | if (p.prop == HAL_PROPERTY_ID) { | ||
442 | taken.add(p); | ||
443 | mIsSupported = true; | ||
444 | if (DBG) { | ||
445 | Log.d(TAG, "takeSupportedProperties: " + toHexString(p.prop)); | ||
446 | } | ||
447 | break; | ||
448 | } | ||
449 | } | ||
450 | return taken; | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * Consumes/produces HAL messages. The format of these messages is defined in: | ||
455 | * hardware/interfaces/automotive/vehicle/2.1/types.hal | ||
456 | */ | ||
457 | @Override | ||
458 | public void handleHalEvents(List<VehiclePropValue> values) { | ||
459 | if (DBG) { | ||
460 | Log.d(TAG, "Handling a VMS property change"); | ||
461 | } | ||
462 | for (VehiclePropValue v : values) { | ||
463 | ArrayList<Integer> vec = v.value.int32Values; | ||
464 | int messageType = vec.get(VmsBaseMessageIntegerValuesIndex.MESSAGE_TYPE); | ||
465 | |||
466 | if (DBG) { | ||
467 | Log.d(TAG, "Handling VMS message type: " + messageType); | ||
468 | } | ||
469 | switch (messageType) { | ||
470 | case VmsMessageType.DATA: | ||
471 | handleDataEvent(vec, toByteArray(v.value.bytes)); | ||
472 | break; | ||
473 | case VmsMessageType.SUBSCRIBE: | ||
474 | handleSubscribeEvent(vec); | ||
475 | break; | ||
476 | case VmsMessageType.UNSUBSCRIBE: | ||
477 | handleUnsubscribeEvent(vec); | ||
478 | break; | ||
479 | case VmsMessageType.SUBSCRIBE_TO_PUBLISHER: | ||
480 | handleSubscribeToPublisherEvent(vec); | ||
481 | break; | ||
482 | case VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER: | ||
483 | handleUnsubscribeFromPublisherEvent(vec); | ||
484 | break; | ||
485 | case VmsMessageType.OFFERING: | ||
486 | handleOfferingEvent(vec); | ||
487 | break; | ||
488 | case VmsMessageType.AVAILABILITY_REQUEST: | ||
489 | handleHalAvailabilityRequestEvent(); | ||
490 | break; | ||
491 | case VmsMessageType.SUBSCRIPTIONS_REQUEST: | ||
492 | handleSubscriptionRequestEvent(); | ||
493 | break; | ||
494 | default: | ||
495 | throw new IllegalArgumentException("Unexpected message type: " + messageType); | ||
496 | } | ||
497 | } | ||
498 | } | ||
499 | |||
500 | private VmsLayer parseVmsLayerFromSimpleMessageIntegerValues(List<Integer> integerValues) { | ||
501 | return new VmsLayer(integerValues.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_TYPE), | ||
502 | integerValues.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_SUBTYPE), | ||
503 | integerValues.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_VERSION)); | ||
504 | } | ||
505 | |||
506 | private VmsLayer parseVmsLayerFromDataMessageIntegerValues(List<Integer> integerValues) { | ||
507 | return parseVmsLayerFromSimpleMessageIntegerValues(integerValues); | ||
508 | } | ||
509 | |||
510 | private int parsePublisherIdFromDataMessageIntegerValues(List<Integer> integerValues) { | ||
511 | return integerValues.get(VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.PUBLISHER_ID); | ||
512 | } | ||
513 | |||
514 | |||
515 | /** | ||
516 | * Data message format: | ||
517 | * <ul> | ||
518 | * <li>Message type. | ||
519 | * <li>Layer id. | ||
520 | * <li>Layer version. | ||
521 | * <li>Layer subtype. | ||
522 | * <li>Publisher ID. | ||
523 | * <li>Payload. | ||
524 | * </ul> | ||
525 | */ | ||
526 | private void handleDataEvent(List<Integer> integerValues, byte[] payload) { | ||
527 | VmsLayer vmsLayer = parseVmsLayerFromDataMessageIntegerValues(integerValues); | ||
528 | int publisherId = parsePublisherIdFromDataMessageIntegerValues(integerValues); | ||
529 | if (DBG) { | ||
530 | Log.d(TAG, "Handling a data event for Layer: " + vmsLayer); | ||
531 | } | ||
532 | |||
533 | // Send the message. | ||
534 | for (VmsHalSubscriberListener listener : mSubscriberListeners) { | ||
535 | listener.onDataMessage(vmsLayer, publisherId, payload); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * Subscribe message format: | ||
541 | * <ul> | ||
542 | * <li>Message type. | ||
543 | * <li>Layer id. | ||
544 | * <li>Layer version. | ||
545 | * <li>Layer subtype. | ||
546 | * </ul> | ||
547 | */ | ||
548 | private void handleSubscribeEvent(List<Integer> integerValues) { | ||
549 | VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues); | ||
550 | if (DBG) { | ||
551 | Log.d(TAG, "Handling a subscribe event for Layer: " + vmsLayer); | ||
552 | } | ||
553 | addHalSubscription(vmsLayer); | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * Subscribe message format: | ||
558 | * <ul> | ||
559 | * <li>Message type. | ||
560 | * <li>Layer id. | ||
561 | * <li>Layer version. | ||
562 | * <li>Layer subtype. | ||
563 | * <li>Publisher ID | ||
564 | * </ul> | ||
565 | */ | ||
566 | private void handleSubscribeToPublisherEvent(List<Integer> integerValues) { | ||
567 | VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues); | ||
568 | if (DBG) { | ||
569 | Log.d(TAG, "Handling a subscribe event for Layer: " + vmsLayer); | ||
570 | } | ||
571 | int publisherId = | ||
572 | integerValues.get(VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.PUBLISHER_ID); | ||
573 | addHalSubscriptionToPublisher(vmsLayer, publisherId); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * Unsubscribe message format: | ||
578 | * <ul> | ||
579 | * <li>Message type. | ||
580 | * <li>Layer id. | ||
581 | * <li>Layer version. | ||
582 | * </ul> | ||
583 | */ | ||
584 | private void handleUnsubscribeEvent(List<Integer> integerValues) { | ||
585 | VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues); | ||
586 | if (DBG) { | ||
587 | Log.d(TAG, "Handling an unsubscribe event for Layer: " + vmsLayer); | ||
588 | } | ||
589 | removeHalSubscription(vmsLayer); | ||
590 | } | ||
591 | |||
592 | /** | ||
593 | * Unsubscribe message format: | ||
594 | * <ul> | ||
595 | * <li>Message type. | ||
596 | * <li>Layer id. | ||
597 | * <li>Layer version. | ||
598 | * </ul> | ||
599 | */ | ||
600 | private void handleUnsubscribeFromPublisherEvent(List<Integer> integerValues) { | ||
601 | VmsLayer vmsLayer = parseVmsLayerFromSimpleMessageIntegerValues(integerValues); | ||
602 | int publisherId = | ||
603 | integerValues.get(VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.PUBLISHER_ID); | ||
604 | if (DBG) { | ||
605 | Log.d(TAG, "Handling an unsubscribe event for Layer: " + vmsLayer); | ||
606 | } | ||
607 | removeHalSubscriptionFromPublisher(vmsLayer, publisherId); | ||
608 | } | ||
609 | |||
610 | private static int NUM_INTEGERS_IN_VMS_LAYER = 3; | ||
611 | |||
612 | private VmsLayer parseVmsLayerFromIndex(List<Integer> integerValues, int index) { | ||
613 | int layerType = integerValues.get(index++); | ||
614 | int layerSutype = integerValues.get(index++); | ||
615 | int layerVersion = integerValues.get(index++); | ||
616 | return new VmsLayer(layerType, layerSutype, layerVersion); | ||
617 | } | ||
618 | |||
619 | /** | ||
620 | * Offering message format: | ||
621 | * <ul> | ||
622 | * <li>Message type. | ||
623 | * <li>Publisher ID. | ||
624 | * <li>Number of offerings. | ||
625 | * <li>Each offering consists of: | ||
626 | * <ul> | ||
627 | * <li>Layer id. | ||
628 | * <li>Layer version. | ||
629 | * <li>Number of layer dependencies. | ||
630 | * <li>Layer type/subtype/version. | ||
631 | * </ul> | ||
632 | * </ul> | ||
633 | */ | ||
634 | private void handleOfferingEvent(List<Integer> integerValues) { | ||
635 | int publisherId = integerValues.get(VmsOfferingMessageIntegerValuesIndex.PUBLISHER_ID); | ||
636 | int numLayersDependencies = | ||
637 | integerValues.get( | ||
638 | VmsOfferingMessageIntegerValuesIndex.NUMBER_OF_OFFERS); | ||
639 | int idx = VmsOfferingMessageIntegerValuesIndex.OFFERING_START; | ||
640 | |||
641 | Set<VmsLayerDependency> offeredLayers = new HashSet<>(); | ||
642 | |||
643 | // An offering is layerId, LayerVersion, LayerType, NumDeps, <LayerId, LayerVersion> X NumDeps. | ||
644 | for (int i = 0; i < numLayersDependencies; i++) { | ||
645 | VmsLayer offeredLayer = parseVmsLayerFromIndex(integerValues, idx); | ||
646 | idx += NUM_INTEGERS_IN_VMS_LAYER; | ||
647 | |||
648 | int numDependenciesForLayer = integerValues.get(idx++); | ||
649 | if (numDependenciesForLayer == 0) { | ||
650 | offeredLayers.add(new VmsLayerDependency(offeredLayer)); | ||
651 | } else { | ||
652 | Set<VmsLayer> dependencies = new HashSet<>(); | ||
653 | |||
654 | for (int j = 0; j < numDependenciesForLayer; j++) { | ||
655 | VmsLayer dependantLayer = parseVmsLayerFromIndex(integerValues, idx); | ||
656 | idx += NUM_INTEGERS_IN_VMS_LAYER; | ||
657 | dependencies.add(dependantLayer); | ||
658 | } | ||
659 | offeredLayers.add(new VmsLayerDependency(offeredLayer, dependencies)); | ||
660 | } | ||
661 | } | ||
662 | // Store the HAL offering. | ||
663 | VmsLayersOffering offering = new VmsLayersOffering(offeredLayers, publisherId); | ||
664 | synchronized (mLock) { | ||
665 | updateOffering(mHalPublisherToken, offering); | ||
666 | VmsOperationRecorder.get().setHalPublisherLayersOffering(offering); | ||
667 | } | ||
668 | } | ||
669 | |||
670 | /** | ||
671 | * Availability message format: | ||
672 | * <ul> | ||
673 | * <li>Message type. | ||
674 | * <li>Number of layers. | ||
675 | * <li>Layer type/subtype/version. | ||
676 | * </ul> | ||
677 | */ | ||
678 | private void handleHalAvailabilityRequestEvent() { | ||
679 | synchronized (mLock) { | ||
680 | Collection<VmsAssociatedLayer> availableLayers = mAvailableLayers.getAvailableLayers(); | ||
681 | VehiclePropValue vehiclePropertyValue = | ||
682 | toAvailabilityUpdateVehiclePropValue( | ||
683 | availableLayers, | ||
684 | VmsMessageType.AVAILABILITY_RESPONSE); | ||
685 | |||
686 | setPropertyValue(vehiclePropertyValue); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | /** | ||
691 | * VmsSubscriptionRequestFormat: | ||
692 | * <ul> | ||
693 | * <li>Message type. | ||
694 | * </ul> | ||
695 | * <p> | ||
696 | * VmsSubscriptionResponseFormat: | ||
697 | * <ul> | ||
698 | * <li>Message type. | ||
699 | * <li>Sequence number. | ||
700 | * <li>Number of layers. | ||
701 | * <li>Layer type/subtype/version. | ||
702 | * </ul> | ||
703 | */ | ||
704 | private void handleSubscriptionRequestEvent() { | ||
705 | VmsSubscriptionState subscription = getSubscriptionState(); | ||
706 | VehiclePropValue vehicleProp = | ||
707 | toTypedVmsVehiclePropValue(VmsMessageType.SUBSCRIPTIONS_RESPONSE); | ||
708 | VehiclePropValue.RawValue v = vehicleProp.value; | ||
709 | v.int32Values.add(subscription.getSequenceNumber()); | ||
710 | Set<VmsLayer> layers = subscription.getLayers(); | ||
711 | v.int32Values.add(layers.size()); | ||
712 | |||
713 | //TODO(asafro): get the real number of associated layers in the subscriptions | ||
714 | // state and send the associated layers themselves. | ||
715 | v.int32Values.add(0); | ||
716 | |||
717 | for (VmsLayer layer : layers) { | ||
718 | v.int32Values.add(layer.getType()); | ||
719 | v.int32Values.add(layer.getSubtype()); | ||
720 | v.int32Values.add(layer.getVersion()); | ||
721 | } | ||
722 | setPropertyValue(vehicleProp); | ||
723 | } | ||
724 | |||
725 | private void updateOffering(IBinder publisherToken, VmsLayersOffering offering) { | ||
726 | Set<VmsAssociatedLayer> availableLayers = Collections.EMPTY_SET; | ||
727 | synchronized (mLock) { | ||
728 | mOfferings.put(publisherToken, offering); | ||
729 | |||
730 | // Update layers availability. | ||
731 | mAvailableLayers.setPublishersOffering(mOfferings.values()); | ||
732 | |||
733 | availableLayers = mAvailableLayers.getAvailableLayers(); | ||
734 | } | ||
735 | notifyOfAvailabilityChange(availableLayers); | ||
736 | } | ||
737 | |||
738 | @Override | ||
739 | public void dump(PrintWriter writer) { | ||
740 | writer.println(TAG); | ||
741 | writer.println("VmsProperty " + (mIsSupported ? "" : "not") + " supported."); | ||
742 | } | ||
743 | |||
744 | /** | ||
745 | * Updates the VMS HAL property with the given value. | ||
746 | * | ||
747 | * @param layer layer data to update the hal property. | ||
748 | * @param hasSubscribers if it is a subscribe or unsubscribe message. | ||
749 | * @return true if the call to the HAL to update the property was successful. | ||
750 | */ | ||
751 | public boolean setSubscriptionRequest(VmsLayer layer, boolean hasSubscribers) { | ||
752 | VehiclePropValue vehiclePropertyValue = toTypedVmsVehiclePropValueWithLayer( | ||
753 | hasSubscribers ? VmsMessageType.SUBSCRIBE : VmsMessageType.UNSUBSCRIBE, layer); | ||
754 | return setPropertyValue(vehiclePropertyValue); | ||
755 | } | ||
756 | |||
757 | public boolean setSubscriptionToPublisherRequest(VmsLayer layer, | ||
758 | int publisherId, | ||
759 | boolean hasSubscribers) { | ||
760 | VehiclePropValue vehiclePropertyValue = toTypedVmsVehiclePropValueWithLayer( | ||
761 | hasSubscribers ? | ||
762 | VmsMessageType.SUBSCRIBE_TO_PUBLISHER : | ||
763 | VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER, layer); | ||
764 | vehiclePropertyValue.value.int32Values.add(publisherId); | ||
765 | return setPropertyValue(vehiclePropertyValue); | ||
766 | } | ||
767 | |||
768 | public boolean setDataMessage(VmsLayer layer, byte[] payload) { | ||
769 | VehiclePropValue vehiclePropertyValue = | ||
770 | toTypedVmsVehiclePropValueWithLayer(VmsMessageType.DATA, layer); | ||
771 | VehiclePropValue.RawValue v = vehiclePropertyValue.value; | ||
772 | v.bytes.ensureCapacity(payload.length); | ||
773 | for (byte b : payload) { | ||
774 | v.bytes.add(b); | ||
775 | } | ||
776 | return setPropertyValue(vehiclePropertyValue); | ||
777 | } | ||
778 | |||
779 | public boolean notifyAvailabilityChangeToHal(Collection<VmsAssociatedLayer> availableLayers) { | ||
780 | VehiclePropValue vehiclePropertyValue = | ||
781 | toAvailabilityUpdateVehiclePropValue( | ||
782 | availableLayers, | ||
783 | VmsMessageType.AVAILABILITY_CHANGE); | ||
784 | |||
785 | return setPropertyValue(vehiclePropertyValue); | ||
786 | } | ||
787 | |||
788 | public boolean setPropertyValue(VehiclePropValue vehiclePropertyValue) { | ||
789 | try { | ||
790 | mVehicleHal.set(vehiclePropertyValue); | ||
791 | return true; | ||
792 | } catch (PropertyTimeoutException e) { | ||
793 | Log.e(CarLog.TAG_PROPERTY, "set, property not ready 0x" + toHexString(HAL_PROPERTY_ID)); | ||
794 | } | ||
795 | return false; | ||
796 | } | ||
797 | |||
798 | private static VehiclePropValue toTypedVmsVehiclePropValue(int messageType) { | ||
799 | VehiclePropValue vehicleProp = new VehiclePropValue(); | ||
800 | vehicleProp.prop = HAL_PROPERTY_ID; | ||
801 | vehicleProp.areaId = VehicleAreaType.VEHICLE_AREA_TYPE_NONE; | ||
802 | VehiclePropValue.RawValue v = vehicleProp.value; | ||
803 | |||
804 | v.int32Values.add(messageType); | ||
805 | return vehicleProp; | ||
806 | } | ||
807 | |||
808 | /** | ||
809 | * Creates a {@link VehiclePropValue} | ||
810 | */ | ||
811 | private static VehiclePropValue toTypedVmsVehiclePropValueWithLayer( | ||
812 | int messageType, VmsLayer layer) { | ||
813 | VehiclePropValue vehicleProp = toTypedVmsVehiclePropValue(messageType); | ||
814 | VehiclePropValue.RawValue v = vehicleProp.value; | ||
815 | v.int32Values.add(layer.getType()); | ||
816 | v.int32Values.add(layer.getSubtype()); | ||
817 | v.int32Values.add(layer.getVersion()); | ||
818 | return vehicleProp; | ||
819 | } | ||
820 | |||
821 | private static VehiclePropValue toAvailabilityUpdateVehiclePropValue( | ||
822 | Collection<VmsAssociatedLayer> availableAssociatedLayers, int messageType) { | ||
823 | |||
824 | if (!AVAILABILITY_MESSAGE_TYPES.contains(messageType)) { | ||
825 | throw new IllegalArgumentException("Unsupported availability type: " + messageType); | ||
826 | } | ||
827 | VehiclePropValue vehicleProp = | ||
828 | toTypedVmsVehiclePropValue(messageType); | ||
829 | populateAvailabilityPropValueFields(availableAssociatedLayers, vehicleProp); | ||
830 | return vehicleProp; | ||
831 | |||
832 | } | ||
833 | |||
834 | private static void populateAvailabilityPropValueFields( | ||
835 | Collection<VmsAssociatedLayer> availableAssociatedLayers, | ||
836 | VehiclePropValue vehicleProp) { | ||
837 | VehiclePropValue.RawValue v = vehicleProp.value; | ||
838 | int numLayers = availableAssociatedLayers.size(); | ||
839 | v.int32Values.add(numLayers); | ||
840 | for (VmsAssociatedLayer layer : availableAssociatedLayers) { | ||
841 | v.int32Values.add(layer.getVmsLayer().getType()); | ||
842 | v.int32Values.add(layer.getVmsLayer().getSubtype()); | ||
843 | v.int32Values.add(layer.getVmsLayer().getVersion()); | ||
844 | v.int32Values.add(layer.getPublisherIds().size()); | ||
845 | for (int publisherId : layer.getPublisherIds()) { | ||
846 | v.int32Values.add(publisherId); | ||
847 | } | ||
848 | } | ||
849 | } | ||
850 | } | ||
diff --git a/tests/VmsPublisherClientSample/Android.mk b/tests/VmsPublisherClientSample/Android.mk deleted file mode 100644 index 2aa6c401..00000000 --- a/tests/VmsPublisherClientSample/Android.mk +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | # Copyright (C) 2017 The Android Open Source Project | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | # | ||
15 | # | ||
16 | |||
17 | LOCAL_PATH:= $(call my-dir) | ||
18 | |||
19 | include $(CLEAR_VARS) | ||
20 | |||
21 | LOCAL_SRC_FILES := $(call all-java-files-under, src) | ||
22 | |||
23 | LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res | ||
24 | |||
25 | LOCAL_PACKAGE_NAME := VmsPublisherClientSample | ||
26 | |||
27 | LOCAL_MODULE_TAGS := optional | ||
28 | |||
29 | LOCAL_PRIVILEGED_MODULE := true | ||
30 | |||
31 | LOCAL_CERTIFICATE := testkey | ||
32 | |||
33 | LOCAL_PROGUARD_ENABLED := disabled | ||
34 | |||
35 | LOCAL_JAVA_LIBRARIES += android.car | ||
36 | |||
37 | include $(BUILD_PACKAGE) \ No newline at end of file | ||
diff --git a/tests/VmsPublisherClientSample/AndroidManifest.xml b/tests/VmsPublisherClientSample/AndroidManifest.xml deleted file mode 100644 index fdc1a318..00000000 --- a/tests/VmsPublisherClientSample/AndroidManifest.xml +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (C) 2017 The Android Open Source Project | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | --> | ||
16 | |||
17 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
18 | package="com.google.android.car.vms.publisher"> | ||
19 | |||
20 | <uses-permission android:name="android.car.permission.VMS_PUBLISHER" /> | ||
21 | <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> | ||
22 | <uses-permission android:name="android.permission.CAMERA"/> | ||
23 | |||
24 | <uses-sdk android:minSdkVersion="25" android:targetSdkVersion='25'/> | ||
25 | |||
26 | <application android:label="@string/app_name" | ||
27 | android:icon="@mipmap/ic_launcher" | ||
28 | android:directBootAware="true"> | ||
29 | <service android:name=".VmsPublisherClientSampleService" | ||
30 | android:exported="true" | ||
31 | android:singleUser="true"> | ||
32 | </service> | ||
33 | </application> | ||
34 | </manifest> | ||
diff --git a/tests/VmsPublisherClientSample/res/mipmap-hdpi/ic_launcher.png b/tests/VmsPublisherClientSample/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bcc..00000000 --- a/tests/VmsPublisherClientSample/res/mipmap-hdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsPublisherClientSample/res/mipmap-mdpi/ic_launcher.png b/tests/VmsPublisherClientSample/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cb..00000000 --- a/tests/VmsPublisherClientSample/res/mipmap-mdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsPublisherClientSample/res/mipmap-xhdpi/ic_launcher.png b/tests/VmsPublisherClientSample/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e..00000000 --- a/tests/VmsPublisherClientSample/res/mipmap-xhdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsPublisherClientSample/res/mipmap-xxhdpi/ic_launcher.png b/tests/VmsPublisherClientSample/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72cd..00000000 --- a/tests/VmsPublisherClientSample/res/mipmap-xxhdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsPublisherClientSample/res/mipmap-xxxhdpi/ic_launcher.png b/tests/VmsPublisherClientSample/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index aee44e13..00000000 --- a/tests/VmsPublisherClientSample/res/mipmap-xxxhdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsPublisherClientSample/res/values/strings.xml b/tests/VmsPublisherClientSample/res/values/strings.xml deleted file mode 100644 index df8bf057..00000000 --- a/tests/VmsPublisherClientSample/res/values/strings.xml +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (C) 2017 The Android Open Source Project | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | --> | ||
16 | <resources> | ||
17 | <string name="app_name">VmsPublisherClientSample</string> | ||
18 | </resources> | ||
diff --git a/tests/VmsPublisherClientSample/src/com/google/android/car/vms/publisher/VmsPublisherClientSampleService.java b/tests/VmsPublisherClientSample/src/com/google/android/car/vms/publisher/VmsPublisherClientSampleService.java deleted file mode 100644 index e235f1e9..00000000 --- a/tests/VmsPublisherClientSample/src/com/google/android/car/vms/publisher/VmsPublisherClientSampleService.java +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.google.android.car.vms.publisher; | ||
18 | |||
19 | import android.car.vms.VmsLayer; | ||
20 | import android.car.vms.VmsPublisherClientService; | ||
21 | import android.car.vms.VmsSubscriptionState; | ||
22 | import android.os.Handler; | ||
23 | import android.os.Message; | ||
24 | |||
25 | import java.util.concurrent.atomic.AtomicBoolean; | ||
26 | |||
27 | /** | ||
28 | * This service is launched during the initialization of the VMS publisher service. | ||
29 | * Once onVmsPublisherServiceReady is invoked, it starts publishing a single byte every second. | ||
30 | */ | ||
31 | public class VmsPublisherClientSampleService extends VmsPublisherClientService { | ||
32 | public static final int PUBLISH_EVENT = 0; | ||
33 | public static final VmsLayer TEST_LAYER = new VmsLayer(0, 0, 0); | ||
34 | public static final int PUBLISHER_ID = 1; | ||
35 | |||
36 | private byte mCounter = 0; | ||
37 | private AtomicBoolean mInitialized = new AtomicBoolean(false); | ||
38 | |||
39 | private final Handler mHandler = new Handler() { | ||
40 | @Override | ||
41 | public void handleMessage(Message msg) { | ||
42 | if (msg.what == PUBLISH_EVENT && mInitialized.get()) { | ||
43 | periodicPublish(); | ||
44 | } | ||
45 | } | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * Notifies that the publisher services are ready to be used: {@link #publish(VmsLayer, byte[])} | ||
50 | * and {@link #getSubscriptions()}. | ||
51 | */ | ||
52 | @Override | ||
53 | public void onVmsPublisherServiceReady() { | ||
54 | VmsSubscriptionState subscriptionState = getSubscriptions(); | ||
55 | onVmsSubscriptionChange(subscriptionState); | ||
56 | } | ||
57 | |||
58 | @Override | ||
59 | public void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState) { | ||
60 | if (mInitialized.compareAndSet(false, true)) { | ||
61 | for (VmsLayer layer : subscriptionState.getLayers()) { | ||
62 | if (layer.equals(TEST_LAYER)) { | ||
63 | mHandler.sendEmptyMessage(PUBLISH_EVENT); | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public void onDestroy() { | ||
71 | super.onDestroy(); | ||
72 | mInitialized.set(false); | ||
73 | mHandler.removeMessages(PUBLISH_EVENT); | ||
74 | } | ||
75 | |||
76 | private void periodicPublish() { | ||
77 | publish(TEST_LAYER, PUBLISHER_ID, new byte[]{mCounter}); | ||
78 | ++mCounter; | ||
79 | mHandler.sendEmptyMessageDelayed(PUBLISH_EVENT, 1000); | ||
80 | } | ||
81 | } | ||
diff --git a/tests/VmsSubscriberClientSample/Android.mk b/tests/VmsSubscriberClientSample/Android.mk deleted file mode 100644 index f59e2679..00000000 --- a/tests/VmsSubscriberClientSample/Android.mk +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | # Copyright (C) 2017 The Android Open Source Project | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | # | ||
15 | # | ||
16 | |||
17 | LOCAL_PATH:= $(call my-dir) | ||
18 | |||
19 | include $(CLEAR_VARS) | ||
20 | |||
21 | LOCAL_SRC_FILES := $(call all-java-files-under, src) | ||
22 | |||
23 | LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res | ||
24 | |||
25 | LOCAL_PACKAGE_NAME := VmsSubscriberClientSample | ||
26 | |||
27 | LOCAL_MODULE_TAGS := optional | ||
28 | |||
29 | LOCAL_PRIVILEGED_MODULE := true | ||
30 | |||
31 | LOCAL_CERTIFICATE := platform | ||
32 | |||
33 | LOCAL_PROGUARD_ENABLED := disabled | ||
34 | |||
35 | LOCAL_JAVA_LIBRARIES += android.car | ||
36 | |||
37 | include packages/services/Car/car-support-lib/car-support.mk | ||
38 | |||
39 | include $(BUILD_PACKAGE) \ No newline at end of file | ||
diff --git a/tests/VmsSubscriberClientSample/AndroidManifest.xml b/tests/VmsSubscriberClientSample/AndroidManifest.xml deleted file mode 100644 index bc798d77..00000000 --- a/tests/VmsSubscriberClientSample/AndroidManifest.xml +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (C) 2017 The Android Open Source Project | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | --> | ||
16 | |||
17 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
18 | xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" | ||
19 | package="com.google.android.car.vms.subscriber" | ||
20 | android:sharedUserId="android.uid.system"> | ||
21 | <uses-sdk android:minSdkVersion="25" android:targetSdkVersion='25'/> | ||
22 | |||
23 | <application android:label="@string/app_name" | ||
24 | android:icon="@mipmap/ic_launcher"> | ||
25 | <meta-data | ||
26 | android:name="android.car.application" | ||
27 | android:resource="@xml/automotive_app_desc"/> | ||
28 | <activity android:name=".VmsSubscriberClientSampleActivity"> | ||
29 | <intent-filter> | ||
30 | <action android:name="android.intent.action.MAIN"/> | ||
31 | <category android:name="android.intent.category.LAUNCHER"/> | ||
32 | </intent-filter> | ||
33 | </activity> | ||
34 | </application> | ||
35 | </manifest> \ No newline at end of file | ||
diff --git a/tests/VmsSubscriberClientSample/res/layout/activity_main.xml b/tests/VmsSubscriberClientSample/res/layout/activity_main.xml deleted file mode 100644 index ce05a4d2..00000000 --- a/tests/VmsSubscriberClientSample/res/layout/activity_main.xml +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <RelativeLayout | ||
3 | xmlns:android="http://schemas.android.com/apk/res/android" | ||
4 | xmlns:tools="http://schemas.android.com/tools" | ||
5 | android:id="@+id/activity_main" | ||
6 | android:layout_width="match_parent" | ||
7 | android:layout_height="match_parent" | ||
8 | android:paddingTop="@dimen/activity_vertical_margin" | ||
9 | android:paddingBottom="@dimen/activity_vertical_margin" | ||
10 | android:paddingLeft="@dimen/activity_horizontal_margin" | ||
11 | android:paddingRight="@dimen/activity_horizontal_margin" | ||
12 | tools:context="vms.apps.android.google.com.java.myapplication.MainActivity"> | ||
13 | |||
14 | <TextView | ||
15 | android:layout_width="match_parent" | ||
16 | android:layout_height="wrap_content" | ||
17 | android:textAppearance="?android:attr/textAppearanceLarge" | ||
18 | android:text="" | ||
19 | android:id="@+id/textview"/> | ||
20 | </RelativeLayout> | ||
diff --git a/tests/VmsSubscriberClientSample/res/mipmap-hdpi/ic_launcher.png b/tests/VmsSubscriberClientSample/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bcc..00000000 --- a/tests/VmsSubscriberClientSample/res/mipmap-hdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsSubscriberClientSample/res/mipmap-mdpi/ic_launcher.png b/tests/VmsSubscriberClientSample/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cb..00000000 --- a/tests/VmsSubscriberClientSample/res/mipmap-mdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsSubscriberClientSample/res/mipmap-xhdpi/ic_launcher.png b/tests/VmsSubscriberClientSample/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e..00000000 --- a/tests/VmsSubscriberClientSample/res/mipmap-xhdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsSubscriberClientSample/res/mipmap-xxhdpi/ic_launcher.png b/tests/VmsSubscriberClientSample/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72cd..00000000 --- a/tests/VmsSubscriberClientSample/res/mipmap-xxhdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsSubscriberClientSample/res/mipmap-xxxhdpi/ic_launcher.png b/tests/VmsSubscriberClientSample/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index aee44e13..00000000 --- a/tests/VmsSubscriberClientSample/res/mipmap-xxxhdpi/ic_launcher.png +++ /dev/null | |||
Binary files differ | |||
diff --git a/tests/VmsSubscriberClientSample/res/values-w820dp/dimens.xml b/tests/VmsSubscriberClientSample/res/values-w820dp/dimens.xml deleted file mode 100644 index 308a1947..00000000 --- a/tests/VmsSubscriberClientSample/res/values-w820dp/dimens.xml +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | <resources> | ||
2 | <!-- Example customization of dimensions originally defined in res/values/dimens.xml | ||
3 | (such as screen margins) for screens with more than 820dp of available width. This | ||
4 | would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> | ||
5 | <dimen name="activity_horizontal_margin">64dp</dimen> | ||
6 | </resources> | ||
diff --git a/tests/VmsSubscriberClientSample/res/values/colors.xml b/tests/VmsSubscriberClientSample/res/values/colors.xml deleted file mode 100644 index 5a077b3a..00000000 --- a/tests/VmsSubscriberClientSample/res/values/colors.xml +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <resources> | ||
3 | <color name="colorPrimary">#3F51B5</color> | ||
4 | <color name="colorPrimaryDark">#303F9F</color> | ||
5 | <color name="colorAccent">#FF4081</color> | ||
6 | </resources> | ||
diff --git a/tests/VmsSubscriberClientSample/res/values/dimens.xml b/tests/VmsSubscriberClientSample/res/values/dimens.xml deleted file mode 100644 index acf94cc6..00000000 --- a/tests/VmsSubscriberClientSample/res/values/dimens.xml +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | <resources> | ||
2 | <!-- Default screen margins, per the Android Design guidelines. --> | ||
3 | <dimen name="activity_horizontal_margin">16dp</dimen> | ||
4 | <dimen name="activity_vertical_margin">16dp</dimen> | ||
5 | </resources> | ||
diff --git a/tests/VmsSubscriberClientSample/res/values/strings.xml b/tests/VmsSubscriberClientSample/res/values/strings.xml deleted file mode 100644 index 24df55ea..00000000 --- a/tests/VmsSubscriberClientSample/res/values/strings.xml +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | <resources> | ||
2 | <string name="app_name">VmsSubscriberClientSample</string> | ||
3 | </resources> | ||
diff --git a/tests/VmsSubscriberClientSample/res/values/styles.xml b/tests/VmsSubscriberClientSample/res/values/styles.xml deleted file mode 100644 index a7a06158..00000000 --- a/tests/VmsSubscriberClientSample/res/values/styles.xml +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | <resources> | ||
2 | |||
3 | <!-- Base application theme. --> | ||
4 | <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar"> | ||
5 | <!-- Customize your theme here. --> | ||
6 | </style> | ||
7 | |||
8 | </resources> | ||
diff --git a/tests/VmsSubscriberClientSample/res/xml/automotive_app_desc.xml b/tests/VmsSubscriberClientSample/res/xml/automotive_app_desc.xml deleted file mode 100644 index b10ddd01..00000000 --- a/tests/VmsSubscriberClientSample/res/xml/automotive_app_desc.xml +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <!-- Copyright (C) 2015 The Android Open Source Project | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | --> | ||
16 | <automotiveApp> | ||
17 | <uses name="service" /> | ||
18 | <uses name="projection" /> | ||
19 | <uses name="activity" class="com.google.android.car.vms.subscriber.VmsSubscriberClientSampleActivity" /> | ||
20 | </automotiveApp> | ||
diff --git a/tests/VmsSubscriberClientSample/src/com/google/android/car/vms/subscriber/VmsSubscriberClientSampleActivity.java b/tests/VmsSubscriberClientSample/src/com/google/android/car/vms/subscriber/VmsSubscriberClientSampleActivity.java deleted file mode 100644 index 3ac07072..00000000 --- a/tests/VmsSubscriberClientSample/src/com/google/android/car/vms/subscriber/VmsSubscriberClientSampleActivity.java +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.google.android.car.vms.subscriber; | ||
18 | |||
19 | import android.app.Activity; | ||
20 | import android.car.vms.VmsLayer; | ||
21 | import android.car.vms.VmsSubscriberManager; | ||
22 | import android.content.pm.PackageManager; | ||
23 | import android.os.Bundle; | ||
24 | import android.support.car.Car; | ||
25 | import android.support.car.CarConnectionCallback; | ||
26 | import android.util.Log; | ||
27 | import android.widget.TextView; | ||
28 | |||
29 | import java.util.List; | ||
30 | |||
31 | /** | ||
32 | * Connects to the Car service during onCreate. CarConnectionCallback.onConnected is invoked when | ||
33 | * the connection is ready. Then, it subscribes to a VMS layer/version and updates the TextView when | ||
34 | * a message is received. | ||
35 | */ | ||
36 | public class VmsSubscriberClientSampleActivity extends Activity { | ||
37 | private static final String TAG = "VmsSampleActivity"; | ||
38 | // The layer id and version should match the ones defined in | ||
39 | // com.google.android.car.vms.publisher.VmsPublisherClientSampleService | ||
40 | public static final VmsLayer TEST_LAYER = new VmsLayer(0, 0, 0); | ||
41 | |||
42 | private Car mCarApi; | ||
43 | private TextView mTextView; | ||
44 | private VmsSubscriberManager mVmsSubscriberManager; | ||
45 | |||
46 | @Override | ||
47 | protected void onCreate(Bundle savedInstanceState) { | ||
48 | super.onCreate(savedInstanceState); | ||
49 | setContentView(R.layout.activity_main); | ||
50 | mTextView = (TextView) findViewById(R.id.textview); | ||
51 | if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { | ||
52 | mCarApi = Car.createCar(this, mCarConnectionCallback); | ||
53 | mCarApi.connect(); | ||
54 | } else { | ||
55 | Log.d(TAG, "No automotive feature."); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | @Override | ||
60 | protected void onDestroy() { | ||
61 | super.onDestroy(); | ||
62 | if (mCarApi != null) { | ||
63 | mCarApi.disconnect(); | ||
64 | } | ||
65 | Log.i(TAG, "onDestroy"); | ||
66 | } | ||
67 | |||
68 | private final CarConnectionCallback mCarConnectionCallback = new CarConnectionCallback() { | ||
69 | @Override | ||
70 | public void onConnected(Car car) { | ||
71 | Log.d(TAG, "Connected to Car Service"); | ||
72 | mVmsSubscriberManager = getVmsSubscriberManager(); | ||
73 | configureSubscriptions(mVmsSubscriberManager); | ||
74 | } | ||
75 | |||
76 | @Override | ||
77 | public void onDisconnected(Car car) { | ||
78 | Log.d(TAG, "Disconnect from Car Service"); | ||
79 | } | ||
80 | |||
81 | private VmsSubscriberManager getVmsSubscriberManager() { | ||
82 | try { | ||
83 | return (VmsSubscriberManager) mCarApi.getCarManager( | ||
84 | android.car.Car.VMS_SUBSCRIBER_SERVICE); | ||
85 | } catch (android.support.car.CarNotConnectedException e) { | ||
86 | Log.e(TAG, "Car is not connected!", e); | ||
87 | } | ||
88 | return null; | ||
89 | } | ||
90 | |||
91 | private void configureSubscriptions(VmsSubscriberManager vmsSubscriberManager) { | ||
92 | try { | ||
93 | vmsSubscriberManager.registerClientCallback(mClientCallback); | ||
94 | vmsSubscriberManager.subscribe(TEST_LAYER); | ||
95 | } catch (android.car.CarNotConnectedException e) { | ||
96 | Log.e(TAG, "Car is not connected!", e); | ||
97 | } | ||
98 | } | ||
99 | }; | ||
100 | |||
101 | private final VmsSubscriberManager.VmsSubscriberClientCallback mClientCallback = | ||
102 | new VmsSubscriberManager.VmsSubscriberClientCallback() { | ||
103 | @Override | ||
104 | public void onVmsMessageReceived(VmsLayer layer, byte[] payload) { | ||
105 | mTextView.setText(String.valueOf(payload[0])); | ||
106 | } | ||
107 | |||
108 | @Override | ||
109 | public void onLayersAvailabilityChanged(List<VmsLayer> availableLayers) { | ||
110 | mTextView.setText(String.valueOf(availableLayers)); | ||
111 | } | ||
112 | }; | ||
113 | } | ||
diff --git a/tests/carservice_test/AndroidManifest.xml b/tests/carservice_test/AndroidManifest.xml index 6f7ba349..6a1e2bfc 100644 --- a/tests/carservice_test/AndroidManifest.xml +++ b/tests/carservice_test/AndroidManifest.xml | |||
@@ -43,9 +43,5 @@ | |||
43 | android:process="com.android.car.carservicetest.activityC"/> | 43 | android:process="com.android.car.carservicetest.activityC"/> |
44 | <activity android:name="com.android.car.test.SystemActivityMonitoringServiceTest$BlockingActivity" | 44 | <activity android:name="com.android.car.test.SystemActivityMonitoringServiceTest$BlockingActivity" |
45 | android:taskAffinity="com.android.car.carservicetest.block"/> | 45 | android:taskAffinity="com.android.car.carservicetest.block"/> |
46 | <service android:name=".SimpleVmsPublisherClientService" | ||
47 | android:exported="true" | ||
48 | /> | ||
49 | <service android:name=".VmsPublisherClientMockService" android:exported="true" /> | ||
50 | </application> | 46 | </application> |
51 | </manifest> | 47 | </manifest> |
diff --git a/tests/carservice_test/src/com/android/car/test/SimpleVmsPublisherClientService.java b/tests/carservice_test/src/com/android/car/test/SimpleVmsPublisherClientService.java deleted file mode 100644 index c3c15f5b..00000000 --- a/tests/carservice_test/src/com/android/car/test/SimpleVmsPublisherClientService.java +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.car.vms.VmsPublisherClientService; | ||
21 | import android.car.vms.VmsSubscriptionState; | ||
22 | |||
23 | /** | ||
24 | * This service is launched during the tests in VmsPublisherClientServiceTest. | ||
25 | */ | ||
26 | @FutureFeature | ||
27 | public class SimpleVmsPublisherClientService extends VmsPublisherClientService { | ||
28 | @Override | ||
29 | public void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState) { | ||
30 | |||
31 | } | ||
32 | |||
33 | @Override | ||
34 | public void onVmsPublisherServiceReady() { | ||
35 | // Publish a property that is going to be verified in the test. | ||
36 | publish(VmsPublisherClientServiceTest.MOCK_PUBLISHER_LAYER, | ||
37 | VmsPublisherClientServiceTest.MOCK_PUBLISHER_ID, | ||
38 | VmsPublisherClientServiceTest.PAYLOAD); | ||
39 | } | ||
40 | } | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsHalServiceSubscriptionEventTest.java b/tests/carservice_test/src/com/android/car/test/VmsHalServiceSubscriptionEventTest.java deleted file mode 100644 index cad30860..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsHalServiceSubscriptionEventTest.java +++ /dev/null | |||
@@ -1,181 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import static org.junit.Assume.assumeTrue; | ||
20 | |||
21 | import android.car.VehicleAreaType; | ||
22 | import android.car.annotation.FutureFeature; | ||
23 | import android.car.vms.VmsLayer; | ||
24 | import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; | ||
25 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; | ||
26 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; | ||
27 | import android.hardware.automotive.vehicle.V2_0.VehicleProperty; | ||
28 | import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex; | ||
29 | import android.hardware.automotive.vehicle.V2_0.VmsMessageType; | ||
30 | import android.hardware.automotive.vehicle.V2_0.VmsSubscriptionsStateIntegerValuesIndex; | ||
31 | import android.test.suitebuilder.annotation.MediumTest; | ||
32 | |||
33 | import com.android.car.vehiclehal.VehiclePropValueBuilder; | ||
34 | import com.android.car.vehiclehal.test.MockedVehicleHal; | ||
35 | import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; | ||
36 | |||
37 | import java.util.ArrayList; | ||
38 | import java.util.Arrays; | ||
39 | import java.util.HashSet; | ||
40 | import java.util.List; | ||
41 | import java.util.concurrent.Semaphore; | ||
42 | import java.util.concurrent.TimeUnit; | ||
43 | |||
44 | @FutureFeature | ||
45 | @MediumTest | ||
46 | public class VmsHalServiceSubscriptionEventTest extends MockedCarTestBase { | ||
47 | private static final String TAG = "VmsHalServiceTest"; | ||
48 | |||
49 | private HalHandler mHalHandler; | ||
50 | private MockedVehicleHal mHal; | ||
51 | // Used to block until the HAL property is updated in HalHandler.onPropertySet. | ||
52 | private Semaphore mHalHandlerSemaphore; | ||
53 | |||
54 | @Override | ||
55 | protected synchronized void configureMockedHal() { | ||
56 | mHalHandler = new HalHandler(); | ||
57 | addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler) | ||
58 | .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE) | ||
59 | .setAccess(VehiclePropertyAccess.READ_WRITE) | ||
60 | .setSupportedAreas(VehicleAreaType.VEHICLE_AREA_TYPE_NONE); | ||
61 | } | ||
62 | |||
63 | @Override | ||
64 | protected void setUp() throws Exception { | ||
65 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
66 | super.setUp(); | ||
67 | mHal = getMockedVehicleHal(); | ||
68 | mHalHandlerSemaphore = new Semaphore(0); | ||
69 | } | ||
70 | |||
71 | @Override | ||
72 | protected synchronized void tearDown() throws Exception { | ||
73 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
74 | super.tearDown(); | ||
75 | } | ||
76 | |||
77 | public void testEmptySubscriptions() throws Exception { | ||
78 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
79 | List<VmsLayer> layers = new ArrayList<>(); | ||
80 | subscriptionTestLogic(layers); | ||
81 | } | ||
82 | |||
83 | public void testOneSubscription() throws Exception { | ||
84 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
85 | List<VmsLayer> layers = Arrays.asList(new VmsLayer(8, 0, 3)); | ||
86 | subscriptionTestLogic(layers); | ||
87 | } | ||
88 | |||
89 | public void testManySubscriptions() throws Exception { | ||
90 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
91 | List<VmsLayer> layers = Arrays.asList( | ||
92 | new VmsLayer(8, 1, 3), | ||
93 | new VmsLayer(5, 2, 1), | ||
94 | new VmsLayer(3, 3, 9), | ||
95 | new VmsLayer(2, 4, 7), | ||
96 | new VmsLayer(9, 5, 3)); | ||
97 | subscriptionTestLogic(layers); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * First, it subscribes to the given layers. Then it validates that a subscription request | ||
102 | * responds with the same layers. | ||
103 | */ | ||
104 | private void subscriptionTestLogic(List<VmsLayer> layers) throws Exception { | ||
105 | for (VmsLayer layer : layers) { | ||
106 | subscribeViaHal(layer); | ||
107 | } | ||
108 | // Send subscription request. | ||
109 | mHal.injectEvent(createHalSubscriptionRequest()); | ||
110 | // Wait for response. | ||
111 | assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
112 | // Validate response. | ||
113 | ArrayList<Integer> v = mHalHandler.getValues(); | ||
114 | int messageType = v.get(VmsSubscriptionsStateIntegerValuesIndex.MESSAGE_TYPE); | ||
115 | int sequenceNumber = v.get(VmsSubscriptionsStateIntegerValuesIndex.SEQUENCE_NUMBER); | ||
116 | int numberLayers = v.get(VmsSubscriptionsStateIntegerValuesIndex.NUMBER_OF_LAYERS); | ||
117 | assertEquals(VmsMessageType.SUBSCRIPTIONS_RESPONSE, messageType); | ||
118 | //TODO(asafro): This assertion makes no sense. need to fix. | ||
119 | //assertEquals(layers.size(), sequenceNumber); | ||
120 | assertEquals(layers.size(), numberLayers); | ||
121 | List<VmsLayer> receivedLayers = new ArrayList<>(); | ||
122 | int start = VmsSubscriptionsStateIntegerValuesIndex.SUBSCRIPTIONS_START; | ||
123 | int end = VmsSubscriptionsStateIntegerValuesIndex.SUBSCRIPTIONS_START + 3 * numberLayers; | ||
124 | while (start < end) { | ||
125 | int type = v.get(start++); | ||
126 | int subtype = v.get(start++); | ||
127 | int version = v.get(start++); | ||
128 | receivedLayers.add(new VmsLayer(type, subtype, version)); | ||
129 | } | ||
130 | assertEquals(new HashSet<>(layers), new HashSet<>(receivedLayers)); | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * Subscribes to a layer, waits for the event to propagate back to the HAL layer and validates | ||
135 | * the propagated message. | ||
136 | */ | ||
137 | private void subscribeViaHal(VmsLayer layer) throws Exception { | ||
138 | // Send subscribe request. | ||
139 | mHal.injectEvent(createHalSubscribeRequest(layer)); | ||
140 | // Wait for response. | ||
141 | assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
142 | // Validate response. | ||
143 | ArrayList<Integer> v = mHalHandler.getValues(); | ||
144 | int messsageType = v.get(VmsMessageWithLayerIntegerValuesIndex.MESSAGE_TYPE); | ||
145 | int layerId = v.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_TYPE); | ||
146 | int layerVersion = v.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_VERSION); | ||
147 | int fused = v.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_SUBTYPE); | ||
148 | assertEquals(VmsMessageType.SUBSCRIBE, messsageType); | ||
149 | assertEquals(layer.getType(), layerId); | ||
150 | assertEquals(layer.getVersion(), layerVersion); | ||
151 | } | ||
152 | |||
153 | private VehiclePropValue createHalSubscribeRequest(VmsLayer layer) { | ||
154 | return VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
155 | .addIntValue(VmsMessageType.SUBSCRIBE) | ||
156 | .addIntValue(layer.getType()) | ||
157 | .addIntValue(layer.getSubtype()) | ||
158 | .addIntValue(layer.getVersion()) | ||
159 | .build(); | ||
160 | } | ||
161 | |||
162 | private VehiclePropValue createHalSubscriptionRequest() { | ||
163 | return VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
164 | .addIntValue(VmsMessageType.SUBSCRIPTIONS_REQUEST) | ||
165 | .build(); | ||
166 | } | ||
167 | |||
168 | private class HalHandler implements VehicleHalPropertyHandler { | ||
169 | private ArrayList<Integer> mValues; | ||
170 | |||
171 | @Override | ||
172 | public synchronized void onPropertySet(VehiclePropValue value) { | ||
173 | mValues = value.value.int32Values; | ||
174 | mHalHandlerSemaphore.release(); | ||
175 | } | ||
176 | |||
177 | public ArrayList<Integer> getValues() { | ||
178 | return mValues; | ||
179 | } | ||
180 | } | ||
181 | } \ No newline at end of file | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsOperationRecorderTest.java b/tests/carservice_test/src/com/android/car/test/VmsOperationRecorderTest.java deleted file mode 100644 index 179a1945..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsOperationRecorderTest.java +++ /dev/null | |||
@@ -1,245 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import android.car.vms.VmsLayer; | ||
20 | import android.car.vms.VmsLayerDependency; | ||
21 | import android.car.vms.VmsLayersOffering; | ||
22 | import android.car.vms.VmsOperationRecorder; | ||
23 | import android.test.suitebuilder.annotation.MediumTest; | ||
24 | import android.util.Log; | ||
25 | |||
26 | import junit.framework.TestCase; | ||
27 | |||
28 | import org.json.JSONArray; | ||
29 | import org.json.JSONException; | ||
30 | import org.json.JSONObject; | ||
31 | |||
32 | import java.util.ArrayList; | ||
33 | import java.util.Arrays; | ||
34 | import java.util.HashSet; | ||
35 | |||
36 | @MediumTest | ||
37 | public class VmsOperationRecorderTest extends TestCase { | ||
38 | |||
39 | /** | ||
40 | * Capture messages that VmsOperationRecorder.Writer would normally pass to Log.d(...). | ||
41 | */ | ||
42 | class TestWriter extends VmsOperationRecorder.Writer { | ||
43 | public String mMsg; | ||
44 | |||
45 | @Override | ||
46 | public boolean isEnabled() { | ||
47 | return true; | ||
48 | } | ||
49 | |||
50 | @Override | ||
51 | public void write(String msg) { | ||
52 | super.write(msg); | ||
53 | mMsg = msg; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | private TestWriter mWriter; | ||
58 | private VmsOperationRecorder mRecorder; | ||
59 | private static final String TAG = "VmsOperationRecorderTest"; | ||
60 | |||
61 | private static final VmsLayer layer1 = new VmsLayer(1, 3, 2); | ||
62 | private static final VmsLayer layer2 = new VmsLayer(2, 4, 3); | ||
63 | private static final VmsLayer layer3 = new VmsLayer(3, 5, 4); | ||
64 | |||
65 | private static final VmsLayerDependency layerDependency1 = new VmsLayerDependency(layer3); | ||
66 | private static final VmsLayerDependency layerDependency2 = new VmsLayerDependency(layer1, | ||
67 | new HashSet<VmsLayer>(Arrays.asList(layer2, layer3))); | ||
68 | |||
69 | private static final VmsLayersOffering layersOffering0 = new VmsLayersOffering( | ||
70 | new HashSet<VmsLayerDependency>(), 66); | ||
71 | private static final VmsLayersOffering layersOffering1 = new VmsLayersOffering( | ||
72 | new HashSet<>(Arrays.asList(layerDependency1)), 66); | ||
73 | private static final VmsLayersOffering layersOffering2 = new VmsLayersOffering( | ||
74 | new HashSet<>(Arrays.asList(layerDependency1, layerDependency2)), 66); | ||
75 | |||
76 | public void setUp() { | ||
77 | mWriter = new TestWriter(); | ||
78 | mRecorder = new VmsOperationRecorder(mWriter); | ||
79 | } | ||
80 | |||
81 | public void testSubscribe() throws Exception { | ||
82 | mRecorder.subscribe(layer1); | ||
83 | assertJsonMsgEquals("{'subscribe':{'layer':{'subtype':3,'type':1,'version':2}}}"); | ||
84 | } | ||
85 | |||
86 | public void testUnsubscribe() throws Exception { | ||
87 | mRecorder.unsubscribe(layer1); | ||
88 | assertJsonMsgEquals("{'unsubscribe':{'layer':{'type':1,'subtype':3,'version':2}}}"); | ||
89 | } | ||
90 | |||
91 | public void testStartMonitoring() throws Exception { | ||
92 | mRecorder.startMonitoring(); | ||
93 | assertJsonMsgEquals("{'startMonitoring':{}}"); | ||
94 | } | ||
95 | |||
96 | public void testStopMonitoring() throws Exception { | ||
97 | mRecorder.stopMonitoring(); | ||
98 | assertJsonMsgEquals("{'stopMonitoring':{}}"); | ||
99 | } | ||
100 | |||
101 | public void testSetLayersOffering0() throws Exception { | ||
102 | mRecorder.setLayersOffering(layersOffering0); | ||
103 | assertJsonMsgEquals("{'setLayersOffering':{}}"); | ||
104 | } | ||
105 | |||
106 | public void testSetLayersOffering2() throws Exception { | ||
107 | mRecorder.setLayersOffering(layersOffering2); | ||
108 | assertJsonMsgEquals("{'setLayersOffering':{'layerDependency':[" | ||
109 | + "{'layer':{'type':3,'subtype':5,'version':4}}," | ||
110 | + "{'layer':{'type':1,'subtype':3,'version':2},'dependency':[" | ||
111 | + "{'type':2,'subtype':4,'version':3},{'type':3,'subtype':5,'version':4}]}" | ||
112 | + "]}}"); | ||
113 | } | ||
114 | |||
115 | public void testGetPublisherId() throws Exception { | ||
116 | mRecorder.getPublisherId(9); | ||
117 | assertJsonMsgEquals("{'getPublisherId':{'publisherId':9}}"); | ||
118 | } | ||
119 | |||
120 | public void testAddSubscription() throws Exception { | ||
121 | mRecorder.addSubscription(42, layer1); | ||
122 | assertJsonMsgEquals( | ||
123 | "{'addSubscription':{'sequenceNumber':42,'layer':{'type':1,'subtype':3,'version':2}}}" | ||
124 | ); | ||
125 | } | ||
126 | |||
127 | public void testRemoveSubscription() throws Exception { | ||
128 | mRecorder.removeSubscription(42, layer1); | ||
129 | assertJsonMsgEquals("{'removeSubscription':" | ||
130 | + "{'sequenceNumber':42,'layer':{'type':1,'subtype':3,'version':2}}}"); | ||
131 | } | ||
132 | |||
133 | public void testAddPromiscuousSubscription() throws Exception { | ||
134 | mRecorder.addPromiscuousSubscription(42); | ||
135 | assertJsonMsgEquals("{'addPromiscuousSubscription':{'sequenceNumber':42}}"); | ||
136 | } | ||
137 | |||
138 | public void testRemovePromiscuousSubscription() throws Exception { | ||
139 | mRecorder.removePromiscuousSubscription(42); | ||
140 | assertJsonMsgEquals("{'removePromiscuousSubscription':{'sequenceNumber':42}}"); | ||
141 | } | ||
142 | |||
143 | public void testAddHalSubscription() throws Exception { | ||
144 | mRecorder.addHalSubscription(42, layer1); | ||
145 | assertJsonMsgEquals("{'addHalSubscription':" | ||
146 | + "{'sequenceNumber':42,'layer':{'type':1,'subtype':3,'version':2}}}"); | ||
147 | } | ||
148 | |||
149 | public void testRemoveHalSubscription() throws Exception { | ||
150 | mRecorder.removeHalSubscription(42, layer1); | ||
151 | assertJsonMsgEquals("{'removeHalSubscription':" | ||
152 | + "{'sequenceNumber':42,'layer':{'type':1,'subtype':3,'version':2}}}"); | ||
153 | } | ||
154 | |||
155 | public void testSetPublisherLayersOffering() throws Exception { | ||
156 | mRecorder.setPublisherLayersOffering(layersOffering1); | ||
157 | assertJsonMsgEquals("{'setPublisherLayersOffering':{'layerDependency':[" | ||
158 | + "{'layer':{'type':3,'subtype':5,'version':4}}]}}"); | ||
159 | } | ||
160 | |||
161 | public void testSetHalPublisherLayersOffering() throws Exception { | ||
162 | mRecorder.setHalPublisherLayersOffering(layersOffering1); | ||
163 | assertJsonMsgEquals("{'setHalPublisherLayersOffering':{'layerDependency':[" | ||
164 | + "{'layer':{'type':3,'subtype':5,'version':4}}]}}"); | ||
165 | } | ||
166 | |||
167 | public void testSubscribeToPublisher() throws Exception { | ||
168 | mRecorder.subscribe(layer1, 99); | ||
169 | assertJsonMsgEquals( | ||
170 | "{'subscribe':{'publisherId':99, 'layer':{'type':1,'subtype':3,'version':2}}}"); | ||
171 | } | ||
172 | |||
173 | public void testUnsubscribeToPublisher() throws Exception { | ||
174 | mRecorder.unsubscribe(layer1, 99); | ||
175 | assertJsonMsgEquals( | ||
176 | "{'unsubscribe':{'publisherId':99, 'layer':{'type':1,'subtype':3,'version':2}}}}"); | ||
177 | } | ||
178 | |||
179 | private void assertJsonMsgEquals(String expectJson) throws Exception { | ||
180 | // Escaping double quotes in a JSON string is really noisy. The test data uses single | ||
181 | // quotes instead, which gets replaced here. | ||
182 | JSONObject expect = new JSONObject(expectJson.replace("'", "\"")); | ||
183 | JSONObject got = new JSONObject(mWriter.mMsg); | ||
184 | assertTrue(similar(expect, got)); | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Determine if two JSONObjects are similar. | ||
189 | * They must contain the same set of names which must be associated with | ||
190 | * similar values. | ||
191 | */ | ||
192 | private boolean similar(JSONObject expect, JSONObject got) { | ||
193 | try { | ||
194 | if (!expect.keySet().equals(got.keySet())) { | ||
195 | return false; | ||
196 | } | ||
197 | |||
198 | for (String key : expect.keySet()) { | ||
199 | Object valueExpect = expect.get(key); | ||
200 | Object valueGot = got.get(key); | ||
201 | |||
202 | if (valueExpect == valueGot) { | ||
203 | continue; | ||
204 | } | ||
205 | |||
206 | if (valueExpect == null) { | ||
207 | return false; | ||
208 | } | ||
209 | |||
210 | if (valueExpect instanceof JSONObject) { | ||
211 | return similar((JSONObject) valueExpect, (JSONObject) valueGot); | ||
212 | } else if (valueExpect instanceof JSONArray) { | ||
213 | // Equal JSONArray have the same length and one contains the other. | ||
214 | JSONArray expectArray = (JSONArray) valueExpect; | ||
215 | JSONArray gotArray = (JSONArray) valueGot; | ||
216 | |||
217 | if (expectArray.length() != gotArray.length()) { | ||
218 | return false; | ||
219 | } | ||
220 | |||
221 | for (int i = 0; i < expectArray.length(); i++) { | ||
222 | boolean gotContainsSimilar = false; | ||
223 | for (int j = 0; j < gotArray.length(); j++) { | ||
224 | if (similar((JSONObject) expectArray.get(i), | ||
225 | (JSONObject) gotArray.get(j))) { | ||
226 | gotContainsSimilar = true; | ||
227 | break; | ||
228 | } | ||
229 | } | ||
230 | if (!gotContainsSimilar) { | ||
231 | return false; | ||
232 | } | ||
233 | } | ||
234 | } else if (!valueExpect.equals(valueGot)) { | ||
235 | return false; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | } catch (JSONException e) { | ||
240 | Log.d(TAG, "Could not compare JSONObjects: " + e); | ||
241 | return false; | ||
242 | } | ||
243 | return true; | ||
244 | } | ||
245 | } | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientMockService.java b/tests/carservice_test/src/com/android/car/test/VmsPublisherClientMockService.java deleted file mode 100644 index 0d5c4278..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientMockService.java +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.car.vms.VmsLayer; | ||
21 | import android.car.vms.VmsLayerDependency; | ||
22 | import android.car.vms.VmsLayersOffering; | ||
23 | import android.car.vms.VmsPublisherClientService; | ||
24 | import android.car.vms.VmsSubscriptionState; | ||
25 | import android.util.Log; | ||
26 | import java.util.ArrayList; | ||
27 | import java.util.HashSet; | ||
28 | import java.util.List; | ||
29 | import java.util.Set; | ||
30 | |||
31 | /** | ||
32 | * This service is launched during the tests in VmsPublisherSubscriberTest. It publishes a property | ||
33 | * that is going to be verified in the test. | ||
34 | * | ||
35 | * The service makes offering for pre-defined layers which verifies availability notifications for | ||
36 | * subscribers without them actively being subscribed to a layer, and also echos all the | ||
37 | * subscription requests with an offering for that layer. | ||
38 | * For example, without any subscription request from any client, this service will make offering | ||
39 | * to layer X. If a client will subscribe later to layer Y, this service will respond with offering | ||
40 | * to both layers X and Y. | ||
41 | * | ||
42 | * Note that the subscriber can subscribe before the publisher finishes initialization. To cover | ||
43 | * both potential scenarios, this service publishes the test message in onVmsSubscriptionChange | ||
44 | * and in onVmsPublisherServiceReady. See comments below. | ||
45 | */ | ||
46 | @FutureFeature | ||
47 | public class VmsPublisherClientMockService extends VmsPublisherClientService { | ||
48 | private static final String TAG = "VmsPublisherClientMockService"; | ||
49 | |||
50 | @Override | ||
51 | public void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState) { | ||
52 | // Case when the publisher finished initialization before the subscription request. | ||
53 | initializeMockPublisher(subscriptionState); | ||
54 | } | ||
55 | |||
56 | @Override | ||
57 | public void onVmsPublisherServiceReady() { | ||
58 | // Case when the subscription request was sent before the publisher was ready. | ||
59 | VmsSubscriptionState subscriptionState = getSubscriptions(); | ||
60 | initializeMockPublisher(subscriptionState); | ||
61 | } | ||
62 | |||
63 | private void initializeMockPublisher(VmsSubscriptionState subscriptionState) { | ||
64 | Log.d(TAG, "Initializing Mock publisher"); | ||
65 | int publisherId = getPublisherId(VmsPublisherSubscriberTest.PAYLOAD); | ||
66 | publishIfNeeded(subscriptionState); | ||
67 | declareOffering(subscriptionState, publisherId); | ||
68 | } | ||
69 | |||
70 | private void publishIfNeeded(VmsSubscriptionState subscriptionState) { | ||
71 | for (VmsLayer layer : subscriptionState.getLayers()) { | ||
72 | if (layer.equals(VmsPublisherSubscriberTest.LAYER)) { | ||
73 | publish(VmsPublisherSubscriberTest.LAYER, | ||
74 | VmsPublisherSubscriberTest.EXPECTED_PUBLISHER_ID, | ||
75 | VmsPublisherSubscriberTest.PAYLOAD); | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | private void declareOffering(VmsSubscriptionState subscriptionState, int publisherId) { | ||
81 | Set<VmsLayerDependency> dependencies = new HashSet<>(); | ||
82 | |||
83 | // Add all layers from the subscription state. | ||
84 | for( VmsLayer layer : subscriptionState.getLayers()) { | ||
85 | dependencies.add(new VmsLayerDependency(layer)); | ||
86 | } | ||
87 | |||
88 | // Add default test layers. | ||
89 | dependencies.add(new VmsLayerDependency(VmsPublisherSubscriberTest.LAYER)); | ||
90 | |||
91 | VmsLayersOffering offering = new VmsLayersOffering(dependencies, publisherId); | ||
92 | setLayersOffering(offering); | ||
93 | } | ||
94 | } | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientServiceTest.java b/tests/carservice_test/src/com/android/car/test/VmsPublisherClientServiceTest.java deleted file mode 100644 index 053bab73..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientServiceTest.java +++ /dev/null | |||
@@ -1,195 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import android.annotation.ArrayRes; | ||
20 | import android.car.VehicleAreaType; | ||
21 | import android.car.annotation.FutureFeature; | ||
22 | import android.car.vms.VmsLayer; | ||
23 | import android.content.Context; | ||
24 | import android.content.ContextWrapper; | ||
25 | import android.content.pm.PackageManager; | ||
26 | import android.content.res.Resources; | ||
27 | import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; | ||
28 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; | ||
29 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; | ||
30 | import android.hardware.automotive.vehicle.V2_0.VehicleProperty; | ||
31 | import android.hardware.automotive.vehicle.V2_0.VmsBaseMessageIntegerValuesIndex; | ||
32 | import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex; | ||
33 | import android.hardware.automotive.vehicle.V2_0.VmsMessageType; | ||
34 | import android.test.suitebuilder.annotation.MediumTest; | ||
35 | import android.util.Log; | ||
36 | |||
37 | import com.android.car.R; | ||
38 | import com.android.car.vehiclehal.VehiclePropValueBuilder; | ||
39 | import com.android.car.vehiclehal.test.MockedVehicleHal; | ||
40 | import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; | ||
41 | |||
42 | import java.util.ArrayList; | ||
43 | import java.util.Arrays; | ||
44 | import java.util.concurrent.Semaphore; | ||
45 | import java.util.concurrent.TimeUnit; | ||
46 | |||
47 | @FutureFeature | ||
48 | @MediumTest | ||
49 | public class VmsPublisherClientServiceTest extends MockedCarTestBase { | ||
50 | private static final String TAG = "VmsPublisherTest"; | ||
51 | private static final int MOCK_PUBLISHER_LAYER_ID = 12; | ||
52 | private static final int MOCK_PUBLISHER_LAYER_VERSION = 34; | ||
53 | private static final int MOCK_PUBLISHER_LAYER_SUBTYPE = 56; | ||
54 | public static final int MOCK_PUBLISHER_ID = 1234; | ||
55 | public static final VmsLayer MOCK_PUBLISHER_LAYER = | ||
56 | new VmsLayer(MOCK_PUBLISHER_LAYER_ID, | ||
57 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
58 | MOCK_PUBLISHER_LAYER_VERSION); | ||
59 | public static final byte[] PAYLOAD = new byte[]{1, 1, 2, 3, 5, 8, 13}; | ||
60 | |||
61 | private HalHandler mHalHandler; | ||
62 | // Used to block until the HAL property is updated in HalHandler.onPropertySet. | ||
63 | private Semaphore mHalHandlerSemaphore; | ||
64 | |||
65 | @Override | ||
66 | protected synchronized void configureMockedHal() { | ||
67 | mHalHandler = new HalHandler(); | ||
68 | addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler) | ||
69 | .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE) | ||
70 | .setAccess(VehiclePropertyAccess.READ_WRITE) | ||
71 | .setSupportedAreas(VehicleAreaType.VEHICLE_AREA_TYPE_NONE); | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * Creates a context with the resource vmsPublisherClients overridden. The overridden value | ||
76 | * contains the name of the test service defined also in this test package. | ||
77 | */ | ||
78 | @Override | ||
79 | protected Context getCarServiceContext() throws PackageManager.NameNotFoundException { | ||
80 | Context context = getContext() | ||
81 | .createPackageContext("com.android.car", Context.CONTEXT_IGNORE_SECURITY); | ||
82 | Resources resources = new Resources(context.getAssets(), | ||
83 | context.getResources().getDisplayMetrics(), | ||
84 | context.getResources().getConfiguration()) { | ||
85 | @Override | ||
86 | public String[] getStringArray(@ArrayRes int id) throws NotFoundException { | ||
87 | if (id == R.array.vmsPublisherClients) { | ||
88 | return new String[]{"com.android.car.test/.SimpleVmsPublisherClientService"}; | ||
89 | } | ||
90 | return super.getStringArray(id); | ||
91 | } | ||
92 | }; | ||
93 | ContextWrapper wrapper = new ContextWrapper(context) { | ||
94 | @Override | ||
95 | public Resources getResources() { | ||
96 | return resources; | ||
97 | } | ||
98 | }; | ||
99 | return wrapper; | ||
100 | } | ||
101 | |||
102 | private VehiclePropValue getHalSubscriptionRequest() { | ||
103 | return VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
104 | .addIntValue(VmsMessageType.SUBSCRIBE) | ||
105 | .addIntValue(MOCK_PUBLISHER_LAYER_ID) | ||
106 | .addIntValue(MOCK_PUBLISHER_LAYER_SUBTYPE) | ||
107 | .addIntValue(MOCK_PUBLISHER_LAYER_VERSION) | ||
108 | .build(); | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | protected void setUp() throws Exception { | ||
113 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
114 | /** | ||
115 | * First init the semaphore, setUp will start a series of events that will ultimately | ||
116 | * update the HAL layer and release this semaphore. | ||
117 | */ | ||
118 | mHalHandlerSemaphore = new Semaphore(0); | ||
119 | super.setUp(); | ||
120 | |||
121 | // Inject a subscribe event which simulates the HAL is subscribed to the Mock Publisher. | ||
122 | MockedVehicleHal mHal = getMockedVehicleHal(); | ||
123 | mHal.injectEvent(getHalSubscriptionRequest()); | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | protected synchronized void tearDown() throws Exception { | ||
128 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
129 | super.tearDown(); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * The method setUp initializes all the Car services, including the VmsPublisherService. | ||
134 | * The VmsPublisherService will start and configure its list of clients. This list was | ||
135 | * overridden in the method getCarServiceContext. | ||
136 | * Therefore, only SimpleVmsPublisherClientService will be started. | ||
137 | * The service SimpleVmsPublisherClientService will publish one message, which is validated in | ||
138 | * this test. | ||
139 | */ | ||
140 | public void testPublish() throws Exception { | ||
141 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
142 | //TODO: This test is using minial synchronisation between clients. | ||
143 | // If more complexity is added this may result in publisher | ||
144 | // publishing before the subscriber subscribed, in which case | ||
145 | // the semaphore will not be released. | ||
146 | assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
147 | VehiclePropValue.RawValue rawValue = mHalHandler.getValue().value; | ||
148 | int messageType = rawValue.int32Values.get(VmsMessageWithLayerIntegerValuesIndex.MESSAGE_TYPE); | ||
149 | int layerId = rawValue.int32Values.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_TYPE); | ||
150 | int layerVersion = rawValue.int32Values.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_VERSION); | ||
151 | byte[] payload = new byte[rawValue.bytes.size()]; | ||
152 | for (int i = 0; i < rawValue.bytes.size(); ++i) { | ||
153 | payload[i] = rawValue.bytes.get(i); | ||
154 | } | ||
155 | assertEquals(VmsMessageType.DATA, messageType); | ||
156 | assertEquals(MOCK_PUBLISHER_LAYER_ID, layerId); | ||
157 | assertEquals(MOCK_PUBLISHER_LAYER_VERSION, layerVersion); | ||
158 | assertTrue(Arrays.equals(PAYLOAD, payload)); | ||
159 | } | ||
160 | |||
161 | private class HalHandler implements VehicleHalPropertyHandler { | ||
162 | private VehiclePropValue mValue; | ||
163 | |||
164 | @Override | ||
165 | public synchronized void onPropertySet(VehiclePropValue value) { | ||
166 | mValue = value; | ||
167 | |||
168 | // If this is the data message release the semaphone so the test can continue. | ||
169 | ArrayList<Integer> int32Values = value.value.int32Values; | ||
170 | if (int32Values.get(VmsBaseMessageIntegerValuesIndex.MESSAGE_TYPE) == | ||
171 | VmsMessageType.DATA) { | ||
172 | mHalHandlerSemaphore.release(); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | @Override | ||
177 | public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) { | ||
178 | return mValue != null ? mValue : value; | ||
179 | } | ||
180 | |||
181 | @Override | ||
182 | public synchronized void onPropertySubscribe(int property, int zones, float sampleRate) { | ||
183 | Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate); | ||
184 | } | ||
185 | |||
186 | @Override | ||
187 | public synchronized void onPropertyUnsubscribe(int property) { | ||
188 | Log.d(TAG, "onPropertyUnSubscribe property " + property); | ||
189 | } | ||
190 | |||
191 | public VehiclePropValue getValue() { | ||
192 | return mValue; | ||
193 | } | ||
194 | } | ||
195 | } \ No newline at end of file | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherPermissionsTest.java b/tests/carservice_test/src/com/android/car/test/VmsPublisherPermissionsTest.java deleted file mode 100644 index 1d14c570..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsPublisherPermissionsTest.java +++ /dev/null | |||
@@ -1,160 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import android.annotation.ArrayRes; | ||
20 | import android.car.VehicleAreaType; | ||
21 | import android.car.annotation.FutureFeature; | ||
22 | import android.content.Context; | ||
23 | import android.content.ContextWrapper; | ||
24 | import android.content.pm.PackageManager; | ||
25 | import android.content.res.Resources; | ||
26 | import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; | ||
27 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; | ||
28 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; | ||
29 | import android.hardware.automotive.vehicle.V2_0.VehicleProperty; | ||
30 | import android.hardware.automotive.vehicle.V2_0.VmsBaseMessageIntegerValuesIndex; | ||
31 | import android.hardware.automotive.vehicle.V2_0.VmsMessageType; | ||
32 | import android.test.suitebuilder.annotation.MediumTest; | ||
33 | |||
34 | import com.android.car.R; | ||
35 | import com.android.car.vehiclehal.VehiclePropValueBuilder; | ||
36 | import com.android.car.vehiclehal.test.MockedVehicleHal; | ||
37 | import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; | ||
38 | |||
39 | import java.util.ArrayList; | ||
40 | import java.util.concurrent.Semaphore; | ||
41 | import java.util.concurrent.TimeUnit; | ||
42 | |||
43 | @FutureFeature | ||
44 | @MediumTest | ||
45 | public class VmsPublisherPermissionsTest extends MockedCarTestBase { | ||
46 | private static final String TAG = "VmsPublisherTest"; | ||
47 | private static final int MOCK_PUBLISHER_LAYER_ID = 0; | ||
48 | private static final int MOCK_PUBLISHER_LAYER_VERSION = 0; | ||
49 | private static final int MOCK_PUBLISHER_LAYER_FUSION_INT_VALUE = 0; | ||
50 | |||
51 | private HalHandler mHalHandler; | ||
52 | // Used to block until the HAL property is updated in HalHandler.onPropertySet. | ||
53 | private Semaphore mHalHandlerSemaphore; | ||
54 | |||
55 | @Override | ||
56 | protected synchronized void configureMockedHal() { | ||
57 | mHalHandler = new HalHandler(); | ||
58 | addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler) | ||
59 | .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE) | ||
60 | .setAccess(VehiclePropertyAccess.READ_WRITE) | ||
61 | .setSupportedAreas(VehicleAreaType.VEHICLE_AREA_TYPE_NONE); | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * Creates a context with the resource vmsPublisherClients overridden. The overridden value | ||
66 | * contains the name of the test service defined also in this test package. | ||
67 | */ | ||
68 | @Override | ||
69 | protected Context getCarServiceContext() throws PackageManager.NameNotFoundException { | ||
70 | Context context = getContext() | ||
71 | .createPackageContext("com.android.car", Context.CONTEXT_IGNORE_SECURITY); | ||
72 | Resources resources = new Resources(context.getAssets(), | ||
73 | context.getResources().getDisplayMetrics(), | ||
74 | context.getResources().getConfiguration()) { | ||
75 | @Override | ||
76 | public String[] getStringArray(@ArrayRes int id) throws NotFoundException { | ||
77 | if (id == R.array.vmsPublisherClients) { | ||
78 | return new String[]{ | ||
79 | "com.google.android.car.vms.publisher/" | ||
80 | + ".VmsPublisherClientSampleService"}; | ||
81 | } else if (id == R.array.vmsSafePermissions) { | ||
82 | return new String[]{"android.permission.ACCESS_FINE_LOCATION"}; | ||
83 | } | ||
84 | return super.getStringArray(id); | ||
85 | } | ||
86 | }; | ||
87 | ContextWrapper wrapper = new ContextWrapper(context) { | ||
88 | @Override | ||
89 | public Resources getResources() { | ||
90 | return resources; | ||
91 | } | ||
92 | }; | ||
93 | return wrapper; | ||
94 | } | ||
95 | |||
96 | private VehiclePropValue getHalSubscriptionRequest() { | ||
97 | return VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
98 | .addIntValue(VmsMessageType.SUBSCRIBE) | ||
99 | .addIntValue(MOCK_PUBLISHER_LAYER_ID) | ||
100 | .addIntValue(MOCK_PUBLISHER_LAYER_VERSION) | ||
101 | .addIntValue(MOCK_PUBLISHER_LAYER_FUSION_INT_VALUE) | ||
102 | .build(); | ||
103 | } | ||
104 | |||
105 | @Override | ||
106 | protected void setUp() throws Exception { | ||
107 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
108 | /** | ||
109 | * First init the semaphore, setUp will start a series of events that will ultimately | ||
110 | * update the HAL layer and release this semaphore. | ||
111 | */ | ||
112 | mHalHandlerSemaphore = new Semaphore(0); | ||
113 | super.setUp(); | ||
114 | |||
115 | // Inject a subscribe event which simulates the HAL is subscribed to the Sample Publisher. | ||
116 | MockedVehicleHal mHal = getMockedVehicleHal(); | ||
117 | mHal.injectEvent(getHalSubscriptionRequest()); | ||
118 | } | ||
119 | |||
120 | @Override | ||
121 | protected synchronized void tearDown() throws Exception { | ||
122 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
123 | super.tearDown(); | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * The method setUp initializes all the Car services, including the VmsPublisherService. | ||
128 | * The VmsPublisherService will start and configure its list of clients. This list was | ||
129 | * overridden in the method getCarServiceContext. | ||
130 | * Therefore, only VmsPublisherClientSampleService will be started. | ||
131 | * The service VmsPublisherClientSampleService will publish one message, which is validated in | ||
132 | * this test. | ||
133 | */ | ||
134 | public void testPermissions() throws Exception { | ||
135 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
136 | assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
137 | // At this point the client initialization finished. Let's validate the permissions. | ||
138 | // The VMS service is only allowed to grant ACCESS_FINE_LOCATION but not CAMERA. | ||
139 | assertTrue( | ||
140 | getContext().getPackageManager().checkPermission( | ||
141 | "android.permission.ACCESS_FINE_LOCATION", | ||
142 | "com.google.android.car.vms.publisher") | ||
143 | == PackageManager.PERMISSION_GRANTED); | ||
144 | assertFalse(getContext().getPackageManager().checkPermission( | ||
145 | "android.permission.CAMERA", "com.google.android.car.vms.publisher") | ||
146 | == PackageManager.PERMISSION_GRANTED); | ||
147 | } | ||
148 | |||
149 | private class HalHandler implements VehicleHalPropertyHandler { | ||
150 | @Override | ||
151 | public synchronized void onPropertySet(VehiclePropValue value) { | ||
152 | // If this is the data message release the semaphore so the test can continue. | ||
153 | ArrayList<Integer> int32Values = value.value.int32Values; | ||
154 | if (int32Values.get(VmsBaseMessageIntegerValuesIndex.MESSAGE_TYPE) == | ||
155 | VmsMessageType.DATA) { | ||
156 | mHalHandlerSemaphore.release(); | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | } | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherSubscriberTest.java b/tests/carservice_test/src/com/android/car/test/VmsPublisherSubscriberTest.java deleted file mode 100644 index 5b387d2e..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsPublisherSubscriberTest.java +++ /dev/null | |||
@@ -1,238 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import android.annotation.ArrayRes; | ||
20 | import android.car.Car; | ||
21 | import android.car.VehicleAreaType; | ||
22 | import android.car.annotation.FutureFeature; | ||
23 | import android.car.vms.VmsAssociatedLayer; | ||
24 | import android.car.vms.VmsLayer; | ||
25 | import android.car.vms.VmsSubscriberManager; | ||
26 | import android.content.Context; | ||
27 | import android.content.ContextWrapper; | ||
28 | import android.content.pm.PackageManager; | ||
29 | import android.content.res.Resources; | ||
30 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; | ||
31 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; | ||
32 | import android.hardware.automotive.vehicle.V2_0.VehicleProperty; | ||
33 | import android.test.suitebuilder.annotation.MediumTest; | ||
34 | |||
35 | import com.android.car.vehiclehal.test.MockedVehicleHal; | ||
36 | |||
37 | import java.util.ArrayList; | ||
38 | import java.util.Arrays; | ||
39 | import java.util.HashSet; | ||
40 | import java.util.List; | ||
41 | import java.util.concurrent.Semaphore; | ||
42 | import java.util.concurrent.TimeUnit; | ||
43 | |||
44 | @FutureFeature | ||
45 | @MediumTest | ||
46 | public class VmsPublisherSubscriberTest extends MockedCarTestBase { | ||
47 | private static final int LAYER_ID = 88; | ||
48 | private static final int LAYER_VERSION = 19; | ||
49 | private static final int LAYER_SUBTYPE = 55; | ||
50 | private static final String TAG = "VmsPubSubTest"; | ||
51 | |||
52 | // The expected publisher ID is 0 since it the expected assigned ID from the VMS core. | ||
53 | public static final int EXPECTED_PUBLISHER_ID = 0; | ||
54 | public static final VmsLayer LAYER = new VmsLayer(LAYER_ID, LAYER_SUBTYPE, LAYER_VERSION); | ||
55 | public static final VmsAssociatedLayer ASSOCIATED_LAYER = | ||
56 | new VmsAssociatedLayer(LAYER, new HashSet<>(Arrays.asList(EXPECTED_PUBLISHER_ID))); | ||
57 | public static final byte[] PAYLOAD = new byte[]{2, 3, 5, 7, 11, 13, 17}; | ||
58 | |||
59 | private static final List<VmsAssociatedLayer> AVAILABLE_ASSOCIATED_LAYERS = | ||
60 | new ArrayList<>(Arrays.asList(ASSOCIATED_LAYER)); | ||
61 | |||
62 | |||
63 | private static final int SUBSCRIBED_LAYER_ID = 89; | ||
64 | public static final VmsLayer SUBSCRIBED_LAYER = | ||
65 | new VmsLayer(SUBSCRIBED_LAYER_ID, LAYER_SUBTYPE, LAYER_VERSION); | ||
66 | public static final VmsAssociatedLayer ASSOCIATED_SUBSCRIBED_LAYER = | ||
67 | new VmsAssociatedLayer(SUBSCRIBED_LAYER, new HashSet<>(Arrays.asList(EXPECTED_PUBLISHER_ID))); | ||
68 | private static final List<VmsAssociatedLayer> AVAILABLE_ASSOCIATED_LAYERS_WITH_SUBSCRIBED_LAYER = | ||
69 | new ArrayList<>(Arrays.asList(ASSOCIATED_LAYER, ASSOCIATED_SUBSCRIBED_LAYER)); | ||
70 | |||
71 | |||
72 | private HalHandler mHalHandler; | ||
73 | // Used to block until a value is propagated to the TestClientCallback.onVmsMessageReceived. | ||
74 | private Semaphore mSubscriberSemaphore; | ||
75 | private Semaphore mAvailabilitySemaphore; | ||
76 | |||
77 | @Override | ||
78 | protected synchronized void configureMockedHal() { | ||
79 | mHalHandler = new HalHandler(); | ||
80 | addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler) | ||
81 | .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE) | ||
82 | .setAccess(VehiclePropertyAccess.READ_WRITE) | ||
83 | .setSupportedAreas(VehicleAreaType.VEHICLE_AREA_TYPE_NONE); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Creates a context with the resource vmsPublisherClients overridden. The overridden value | ||
88 | * contains the name of the test service defined also in this test package. | ||
89 | */ | ||
90 | @Override | ||
91 | protected Context getCarServiceContext() throws PackageManager.NameNotFoundException { | ||
92 | Context context = getContext() | ||
93 | .createPackageContext("com.android.car", Context.CONTEXT_IGNORE_SECURITY); | ||
94 | Resources resources = new Resources(context.getAssets(), | ||
95 | context.getResources().getDisplayMetrics(), | ||
96 | context.getResources().getConfiguration()) { | ||
97 | @Override | ||
98 | public String[] getStringArray(@ArrayRes int id) throws NotFoundException { | ||
99 | if (id == com.android.car.R.array.vmsPublisherClients) { | ||
100 | return new String[]{"com.android.car.test/.VmsPublisherClientMockService"}; | ||
101 | } | ||
102 | return super.getStringArray(id); | ||
103 | } | ||
104 | }; | ||
105 | ContextWrapper wrapper = new ContextWrapper(context) { | ||
106 | @Override | ||
107 | public Resources getResources() { | ||
108 | return resources; | ||
109 | } | ||
110 | }; | ||
111 | return wrapper; | ||
112 | } | ||
113 | |||
114 | @Override | ||
115 | protected void setUp() throws Exception { | ||
116 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
117 | super.setUp(); | ||
118 | mSubscriberSemaphore = new Semaphore(0); | ||
119 | mAvailabilitySemaphore = new Semaphore(0); | ||
120 | } | ||
121 | |||
122 | @Override | ||
123 | protected synchronized void tearDown() throws Exception { | ||
124 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
125 | super.tearDown(); | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * The method setUp initializes all the Car services, including the VmsPublisherService. | ||
130 | * The VmsPublisherService will start and configure its list of clients. This list was | ||
131 | * overridden in the method getCarServiceContext. Therefore, only VmsPublisherClientMockService | ||
132 | * will be started. This test method subscribes to a layer and triggers | ||
133 | * VmsPublisherClientMockService.onVmsSubscriptionChange. In turn, the mock service will publish | ||
134 | * a message, which is validated in this test. | ||
135 | */ | ||
136 | public void testPublisherToSubscriber() throws Exception { | ||
137 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
138 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
139 | Car.VMS_SUBSCRIBER_SERVICE); | ||
140 | TestClientCallback clientCallback = new TestClientCallback(); | ||
141 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
142 | vmsSubscriberManager.subscribe(LAYER); | ||
143 | |||
144 | assertTrue(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
145 | assertEquals(LAYER, clientCallback.getLayer()); | ||
146 | assertTrue(Arrays.equals(PAYLOAD, clientCallback.getPayload())); | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * The Mock service will get a publisher ID by sending its information when it will get | ||
151 | * ServiceReady as well as on SubscriptionChange. Since clients are not notified when | ||
152 | * publishers are assigned IDs, this test waits until the availability is changed which indicates | ||
153 | * that the Mock service has gotten its ServiceReady and publisherId. | ||
154 | */ | ||
155 | public void testPublisherInfo() throws Exception { | ||
156 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
157 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
158 | Car.VMS_SUBSCRIBER_SERVICE); | ||
159 | // Subscribe to layer as a way to make sure the mock client completed setting the information. | ||
160 | TestClientCallback clientCallback = new TestClientCallback(); | ||
161 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
162 | vmsSubscriberManager.subscribe(LAYER); | ||
163 | |||
164 | assertTrue(mAvailabilitySemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
165 | |||
166 | byte[] info = vmsSubscriberManager.getPublisherInfo(EXPECTED_PUBLISHER_ID); | ||
167 | assertTrue(Arrays.equals(PAYLOAD, info)); | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * The Mock service offers all the subscribed layers as available layers. | ||
172 | * In this test the client subscribes to a layer and verifies that it gets the | ||
173 | * notification that it is available. | ||
174 | */ | ||
175 | public void testAvailabilityWithSubscription() throws Exception { | ||
176 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
177 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
178 | Car.VMS_SUBSCRIBER_SERVICE); | ||
179 | TestClientCallback clientCallback = new TestClientCallback(); | ||
180 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
181 | vmsSubscriberManager.subscribe(SUBSCRIBED_LAYER); | ||
182 | |||
183 | assertTrue(mAvailabilitySemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
184 | assertEquals(AVAILABLE_ASSOCIATED_LAYERS_WITH_SUBSCRIBED_LAYER, clientCallback.getAvailalbeLayers()); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * The Mock service offers all the subscribed layers as available layers, so in this | ||
189 | * test the client subscribes to a layer and verifies that it gets the notification that it | ||
190 | * is available. | ||
191 | */ | ||
192 | public void testAvailabilityWithoutSubscription() throws Exception { | ||
193 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
194 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
195 | Car.VMS_SUBSCRIBER_SERVICE); | ||
196 | TestClientCallback clientCallback = new TestClientCallback(); | ||
197 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
198 | |||
199 | assertTrue(mAvailabilitySemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
200 | assertEquals(AVAILABLE_ASSOCIATED_LAYERS, clientCallback.getAvailalbeLayers()); | ||
201 | } | ||
202 | |||
203 | private class HalHandler implements MockedVehicleHal.VehicleHalPropertyHandler { | ||
204 | } | ||
205 | |||
206 | private class TestClientCallback implements VmsSubscriberManager.VmsSubscriberClientCallback { | ||
207 | private VmsLayer mLayer; | ||
208 | private byte[] mPayload; | ||
209 | private List<VmsLayer> mAvailableLayers; | ||
210 | |||
211 | @Override | ||
212 | public void onVmsMessageReceived(VmsLayer layer, byte[] payload) { | ||
213 | assertEquals(LAYER, layer); | ||
214 | assertTrue(Arrays.equals(PAYLOAD, payload)); | ||
215 | mLayer = layer; | ||
216 | mPayload = payload; | ||
217 | mSubscriberSemaphore.release(); | ||
218 | } | ||
219 | |||
220 | @Override | ||
221 | public void onLayersAvailabilityChanged(List<VmsLayer> availableLayers) { | ||
222 | mAvailableLayers = availableLayers; | ||
223 | mAvailabilitySemaphore.release(); | ||
224 | } | ||
225 | |||
226 | public VmsLayer getLayer() { | ||
227 | return mLayer; | ||
228 | } | ||
229 | |||
230 | public byte[] getPayload() { | ||
231 | return mPayload; | ||
232 | } | ||
233 | |||
234 | public List<VmsLayer> getAvailalbeLayers() { | ||
235 | return mAvailableLayers; | ||
236 | } | ||
237 | } | ||
238 | } | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsSubscriberManagerTest.java b/tests/carservice_test/src/com/android/car/test/VmsSubscriberManagerTest.java deleted file mode 100644 index 9e9a5d08..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsSubscriberManagerTest.java +++ /dev/null | |||
@@ -1,614 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car.test; | ||
18 | |||
19 | import static org.junit.Assume.assumeTrue; | ||
20 | |||
21 | import android.car.Car; | ||
22 | import android.car.VehicleAreaType; | ||
23 | import android.car.annotation.FutureFeature; | ||
24 | import android.car.vms.VmsAssociatedLayer; | ||
25 | import android.car.vms.VmsLayer; | ||
26 | import android.car.vms.VmsSubscriberManager; | ||
27 | import android.car.vms.VmsSubscriberManager.VmsSubscriberClientCallback; | ||
28 | import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; | ||
29 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; | ||
30 | import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; | ||
31 | import android.hardware.automotive.vehicle.V2_0.VehicleProperty; | ||
32 | import android.hardware.automotive.vehicle.V2_0.VmsMessageType; | ||
33 | import android.os.SystemClock; | ||
34 | import android.test.suitebuilder.annotation.MediumTest; | ||
35 | import android.util.Log; | ||
36 | import com.android.car.vehiclehal.VehiclePropValueBuilder; | ||
37 | import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; | ||
38 | |||
39 | import java.util.ArrayList; | ||
40 | import java.util.Arrays; | ||
41 | import java.util.HashSet; | ||
42 | import java.util.List; | ||
43 | import java.util.Set; | ||
44 | import java.util.concurrent.Semaphore; | ||
45 | import java.util.concurrent.TimeUnit; | ||
46 | |||
47 | @FutureFeature | ||
48 | @MediumTest | ||
49 | public class VmsSubscriberManagerTest extends MockedCarTestBase { | ||
50 | private static final String TAG = "VmsSubscriberManagerTest"; | ||
51 | private static final int PUBLISHER_ID = 17; | ||
52 | private static final int WRONG_PUBLISHER_ID = 26; | ||
53 | private static final Set<Integer> PUBLISHERS_LIST = new HashSet<Integer>(Arrays.asList(PUBLISHER_ID)); | ||
54 | |||
55 | private static final int SUBSCRIPTION_LAYER_ID = 2; | ||
56 | private static final int SUBSCRIPTION_LAYER_VERSION = 3; | ||
57 | private static final int MOCK_PUBLISHER_LAYER_SUBTYPE = 444; | ||
58 | private static final VmsLayer SUBSCRIPTION_LAYER = new VmsLayer(SUBSCRIPTION_LAYER_ID, | ||
59 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
60 | SUBSCRIPTION_LAYER_VERSION); | ||
61 | private static final VmsAssociatedLayer SUBSCRIPTION_ASSOCIATED_LAYER = | ||
62 | new VmsAssociatedLayer(SUBSCRIPTION_LAYER, PUBLISHERS_LIST); | ||
63 | |||
64 | private static final int SUBSCRIPTION_DEPENDANT_LAYER_ID_1 = 4; | ||
65 | private static final int SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1 = 5; | ||
66 | private static final VmsLayer SUBSCRIPTION_DEPENDANT_LAYER_1 = | ||
67 | new VmsLayer(SUBSCRIPTION_DEPENDANT_LAYER_ID_1, | ||
68 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
69 | SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1); | ||
70 | |||
71 | private static final VmsAssociatedLayer SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_1 = | ||
72 | new VmsAssociatedLayer(SUBSCRIPTION_DEPENDANT_LAYER_1, PUBLISHERS_LIST); | ||
73 | |||
74 | private static final int SUBSCRIPTION_DEPENDANT_LAYER_ID_2 = 6; | ||
75 | private static final int SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2 = 7; | ||
76 | private static final VmsLayer SUBSCRIPTION_DEPENDANT_LAYER_2 = | ||
77 | new VmsLayer(SUBSCRIPTION_DEPENDANT_LAYER_ID_2, | ||
78 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
79 | SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2); | ||
80 | |||
81 | private static final VmsAssociatedLayer SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_2 = | ||
82 | new VmsAssociatedLayer(SUBSCRIPTION_DEPENDANT_LAYER_2, PUBLISHERS_LIST); | ||
83 | |||
84 | private static final int SUBSCRIPTION_UNSUPPORTED_LAYER_ID = 100; | ||
85 | private static final int SUBSCRIPTION_UNSUPPORTED_LAYER_VERSION = 200; | ||
86 | |||
87 | |||
88 | private HalHandler mHalHandler; | ||
89 | // Used to block until the HAL property is updated in HalHandler.onPropertySet. | ||
90 | private Semaphore mHalHandlerSemaphore; | ||
91 | // Used to block until a value is propagated to the TestClientCallback.onVmsMessageReceived. | ||
92 | private Semaphore mSubscriberSemaphore; | ||
93 | |||
94 | @Override | ||
95 | protected synchronized void configureMockedHal() { | ||
96 | mHalHandler = new HalHandler(); | ||
97 | addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler) | ||
98 | .setChangeMode(VehiclePropertyChangeMode.ON_CHANGE) | ||
99 | .setAccess(VehiclePropertyAccess.READ_WRITE) | ||
100 | .setSupportedAreas(VehicleAreaType.VEHICLE_AREA_TYPE_NONE); | ||
101 | } | ||
102 | |||
103 | @Override | ||
104 | protected void setUp() throws Exception { | ||
105 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
106 | super.setUp(); | ||
107 | mSubscriberSemaphore = new Semaphore(0); | ||
108 | mHalHandlerSemaphore = new Semaphore(0); | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | protected synchronized void tearDown() throws Exception { | ||
113 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
114 | super.tearDown(); | ||
115 | } | ||
116 | |||
117 | // Test injecting a value in the HAL and verifying it propagates to a subscriber. | ||
118 | public void testSubscribe() throws Exception { | ||
119 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
120 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
121 | Car.VMS_SUBSCRIBER_SERVICE); | ||
122 | TestClientCallback clientCallback = new TestClientCallback(); | ||
123 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
124 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER); | ||
125 | |||
126 | // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived. | ||
127 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
128 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
129 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
130 | .build(); | ||
131 | v.value.int32Values.add(VmsMessageType.DATA); // MessageType | ||
132 | v.value.int32Values.add(SUBSCRIPTION_LAYER_ID); | ||
133 | v.value.int32Values.add(MOCK_PUBLISHER_LAYER_SUBTYPE); | ||
134 | v.value.int32Values.add(SUBSCRIPTION_LAYER_VERSION); | ||
135 | v.value.int32Values.add(PUBLISHER_ID); | ||
136 | v.value.bytes.add((byte) 0xa); | ||
137 | v.value.bytes.add((byte) 0xb); | ||
138 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
139 | |||
140 | getMockedVehicleHal().injectEvent(v); | ||
141 | assertTrue(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
142 | assertEquals(SUBSCRIPTION_LAYER, clientCallback.getLayer()); | ||
143 | byte[] expectedPayload = {(byte) 0xa, (byte) 0xb}; | ||
144 | assertTrue(Arrays.equals(expectedPayload, clientCallback.getPayload())); | ||
145 | } | ||
146 | |||
147 | |||
148 | // Test injecting a value in the HAL and verifying it propagates to a subscriber. | ||
149 | public void testSubscribeToPublisher() throws Exception { | ||
150 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
151 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
152 | Car.VMS_SUBSCRIBER_SERVICE); | ||
153 | TestClientCallback clientCallback = new TestClientCallback(); | ||
154 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
155 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID); | ||
156 | |||
157 | // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived. | ||
158 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
159 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
160 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
161 | .build(); | ||
162 | v.value.int32Values.add(VmsMessageType.DATA); // MessageType | ||
163 | v.value.int32Values.add(SUBSCRIPTION_LAYER_ID); | ||
164 | v.value.int32Values.add(MOCK_PUBLISHER_LAYER_SUBTYPE); | ||
165 | v.value.int32Values.add(SUBSCRIPTION_LAYER_VERSION); | ||
166 | v.value.int32Values.add(WRONG_PUBLISHER_ID); | ||
167 | v.value.bytes.add((byte) 0xa); | ||
168 | v.value.bytes.add((byte) 0xb); | ||
169 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
170 | |||
171 | getMockedVehicleHal().injectEvent(v); | ||
172 | |||
173 | assertFalse(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
174 | } | ||
175 | |||
176 | // Test injecting a value in the HAL and verifying it propagates to a subscriber. | ||
177 | public void testSubscribeFromPublisher() throws Exception { | ||
178 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
179 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
180 | Car.VMS_SUBSCRIBER_SERVICE); | ||
181 | TestClientCallback clientCallback = new TestClientCallback(); | ||
182 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
183 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID); | ||
184 | |||
185 | // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived. | ||
186 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
187 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
188 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
189 | .build(); | ||
190 | v.value.int32Values.add(VmsMessageType.DATA); // MessageType | ||
191 | v.value.int32Values.add(SUBSCRIPTION_LAYER_ID); | ||
192 | v.value.int32Values.add(MOCK_PUBLISHER_LAYER_SUBTYPE); //<- | ||
193 | v.value.int32Values.add(SUBSCRIPTION_LAYER_VERSION); | ||
194 | v.value.int32Values.add(PUBLISHER_ID); | ||
195 | v.value.bytes.add((byte) 0xa); | ||
196 | v.value.bytes.add((byte) 0xb); | ||
197 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
198 | |||
199 | getMockedVehicleHal().injectEvent(v); | ||
200 | assertTrue(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
201 | assertEquals(SUBSCRIPTION_LAYER, clientCallback.getLayer()); | ||
202 | byte[] expectedPayload = {(byte) 0xa, (byte) 0xb}; | ||
203 | assertTrue(Arrays.equals(expectedPayload, clientCallback.getPayload())); | ||
204 | } | ||
205 | |||
206 | // Test injecting a value in the HAL and verifying it does not propagate to a subscriber. | ||
207 | public void testUnsubscribe() throws Exception { | ||
208 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
209 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
210 | Car.VMS_SUBSCRIBER_SERVICE); | ||
211 | TestClientCallback clientCallback = new TestClientCallback(); | ||
212 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
213 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER); | ||
214 | vmsSubscriberManager.unsubscribe(SUBSCRIPTION_LAYER); | ||
215 | |||
216 | // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived. | ||
217 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
218 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
219 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
220 | .build(); | ||
221 | v.value.int32Values.add(VmsMessageType.DATA); // MessageType | ||
222 | v.value.int32Values.add(SUBSCRIPTION_LAYER_ID); | ||
223 | v.value.int32Values.add(MOCK_PUBLISHER_LAYER_SUBTYPE); | ||
224 | v.value.int32Values.add(SUBSCRIPTION_LAYER_VERSION); | ||
225 | v.value.int32Values.add(PUBLISHER_ID); | ||
226 | v.value.bytes.add((byte) 0xa); | ||
227 | v.value.bytes.add((byte) 0xb); | ||
228 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
229 | |||
230 | getMockedVehicleHal().injectEvent(v); | ||
231 | assertFalse(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
232 | } | ||
233 | |||
234 | // Test injecting a value in the HAL and verifying it does not propagate to a subscriber. | ||
235 | public void testSubscribeFromWrongPublisher() throws Exception { | ||
236 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
237 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
238 | Car.VMS_SUBSCRIBER_SERVICE); | ||
239 | TestClientCallback clientCallback = new TestClientCallback(); | ||
240 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
241 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID); | ||
242 | |||
243 | // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived. | ||
244 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
245 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
246 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
247 | .build(); | ||
248 | v.value.int32Values.add(VmsMessageType.DATA); // MessageType | ||
249 | v.value.int32Values.add(SUBSCRIPTION_LAYER_ID); | ||
250 | v.value.int32Values.add(MOCK_PUBLISHER_LAYER_SUBTYPE); | ||
251 | v.value.int32Values.add(SUBSCRIPTION_LAYER_VERSION); | ||
252 | v.value.int32Values.add(WRONG_PUBLISHER_ID); | ||
253 | v.value.bytes.add((byte) 0xa); | ||
254 | v.value.bytes.add((byte) 0xb); | ||
255 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
256 | |||
257 | getMockedVehicleHal().injectEvent(v); | ||
258 | assertFalse(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
259 | } | ||
260 | |||
261 | // Test injecting a value in the HAL and verifying it does not propagate to a subscriber. | ||
262 | public void testUnsubscribeFromPublisher() throws Exception { | ||
263 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
264 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
265 | Car.VMS_SUBSCRIBER_SERVICE); | ||
266 | TestClientCallback clientCallback = new TestClientCallback(); | ||
267 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
268 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID); | ||
269 | vmsSubscriberManager.unsubscribe(SUBSCRIPTION_LAYER, PUBLISHER_ID); | ||
270 | |||
271 | // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived. | ||
272 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
273 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
274 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
275 | .build(); | ||
276 | v.value.int32Values.add(VmsMessageType.DATA); // MessageType | ||
277 | v.value.int32Values.add(SUBSCRIPTION_LAYER_ID); | ||
278 | v.value.int32Values.add(MOCK_PUBLISHER_LAYER_SUBTYPE); | ||
279 | v.value.int32Values.add(SUBSCRIPTION_LAYER_VERSION); | ||
280 | v.value.int32Values.add(PUBLISHER_ID); | ||
281 | v.value.bytes.add((byte) 0xa); | ||
282 | v.value.bytes.add((byte) 0xb); | ||
283 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
284 | |||
285 | getMockedVehicleHal().injectEvent(v); | ||
286 | assertFalse(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
287 | } | ||
288 | |||
289 | |||
290 | // Test injecting a value in the HAL and verifying it propagates to a subscriber. | ||
291 | public void testSubscribeAll() throws Exception { | ||
292 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
293 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
294 | Car.VMS_SUBSCRIBER_SERVICE); | ||
295 | TestClientCallback clientCallback = new TestClientCallback(); | ||
296 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
297 | vmsSubscriberManager.startMonitoring(); | ||
298 | |||
299 | // Inject a value and wait for its callback in TestClientCallback.onVmsMessageReceived. | ||
300 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
301 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
302 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
303 | .build(); | ||
304 | v.value.int32Values.add(VmsMessageType.DATA); // MessageType | ||
305 | v.value.int32Values.add(SUBSCRIPTION_LAYER_ID); | ||
306 | v.value.int32Values.add(MOCK_PUBLISHER_LAYER_SUBTYPE); | ||
307 | v.value.int32Values.add(SUBSCRIPTION_LAYER_VERSION); | ||
308 | v.value.int32Values.add(PUBLISHER_ID); | ||
309 | v.value.bytes.add((byte) 0xa); | ||
310 | v.value.bytes.add((byte) 0xb); | ||
311 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
312 | |||
313 | getMockedVehicleHal().injectEvent(v); | ||
314 | assertTrue(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
315 | assertEquals(SUBSCRIPTION_LAYER, clientCallback.getLayer()); | ||
316 | byte[] expectedPayload = {(byte) 0xa, (byte) 0xb}; | ||
317 | assertTrue(Arrays.equals(expectedPayload, clientCallback.getPayload())); | ||
318 | } | ||
319 | |||
320 | // Test injecting a value in the HAL and verifying it propagates to a subscriber. | ||
321 | public void testSimpleAvailableLayers() throws Exception { | ||
322 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
323 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
324 | Car.VMS_SUBSCRIBER_SERVICE); | ||
325 | TestClientCallback clientCallback = new TestClientCallback(); | ||
326 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
327 | |||
328 | // Inject a value and wait for its callback in TestClientCallback.onLayersAvailabilityChanged. | ||
329 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
330 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
331 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
332 | .build(); | ||
333 | /* | ||
334 | Offering: | ||
335 | Layer | Dependency | ||
336 | =============================== | ||
337 | (2, 3, 444), [17] | {} | ||
338 | |||
339 | Expected availability: | ||
340 | {(2, 3, 444 [17])} | ||
341 | */ | ||
342 | v.value.int32Values.addAll( | ||
343 | Arrays.asList( | ||
344 | VmsMessageType.OFFERING, // MessageType | ||
345 | PUBLISHER_ID, | ||
346 | 1, // Number of offered layers | ||
347 | |||
348 | SUBSCRIPTION_LAYER_ID, | ||
349 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
350 | SUBSCRIPTION_LAYER_VERSION, | ||
351 | 0 // number of dependencies for layer | ||
352 | ) | ||
353 | ); | ||
354 | |||
355 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
356 | |||
357 | getMockedVehicleHal().injectEvent(v); | ||
358 | assertTrue(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
359 | List<VmsAssociatedLayer> expectedAvailableLayers = | ||
360 | new ArrayList<>(Arrays.asList(SUBSCRIPTION_ASSOCIATED_LAYER)); | ||
361 | assertTrue(expectedAvailableLayers.containsAll(clientCallback.getAvailableLayers())); | ||
362 | assertEquals(expectedAvailableLayers.size(), clientCallback.getAvailableLayers().size()); | ||
363 | } | ||
364 | |||
365 | // Test injecting a value in the HAL and verifying it propagates to a subscriber after it has | ||
366 | // subscribed to a layer. | ||
367 | public void testSimpleAvailableLayersAfterSubscription() throws Exception { | ||
368 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
369 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
370 | Car.VMS_SUBSCRIBER_SERVICE); | ||
371 | TestClientCallback clientCallback = new TestClientCallback(); | ||
372 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
373 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER); | ||
374 | |||
375 | // Inject a value and wait for its callback in TestClientCallback.onLayersAvailabilityChanged. | ||
376 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
377 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
378 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
379 | .build(); | ||
380 | /* | ||
381 | Offering: | ||
382 | Layer | Dependency | ||
383 | =============================== | ||
384 | (2, 3, 444), [17] | {} | ||
385 | |||
386 | Expected availability: | ||
387 | {(2, 3, 444 [17])} | ||
388 | */ | ||
389 | v.value.int32Values.addAll( | ||
390 | Arrays.asList( | ||
391 | VmsMessageType.OFFERING, // MessageType | ||
392 | PUBLISHER_ID, | ||
393 | 1, // Number of offered layers | ||
394 | |||
395 | SUBSCRIPTION_LAYER_ID, | ||
396 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
397 | SUBSCRIPTION_LAYER_VERSION, | ||
398 | 0 // number of dependencies for layer | ||
399 | ) | ||
400 | ); | ||
401 | |||
402 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
403 | |||
404 | getMockedVehicleHal().injectEvent(v); | ||
405 | assertTrue(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
406 | List<VmsAssociatedLayer> expectedAvailableLayers = | ||
407 | new ArrayList<>(Arrays.asList(SUBSCRIPTION_ASSOCIATED_LAYER)); | ||
408 | assertTrue(expectedAvailableLayers.containsAll(clientCallback.getAvailableLayers())); | ||
409 | assertEquals(expectedAvailableLayers.size(), clientCallback.getAvailableLayers().size()); | ||
410 | } | ||
411 | |||
412 | // Test injecting a value in the HAL and verifying it does not propagates to a subscriber after | ||
413 | // it has unregistered its callback. | ||
414 | public void testSimpleAvailableLayersAfterUnregister() throws Exception { | ||
415 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
416 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
417 | Car.VMS_SUBSCRIBER_SERVICE); | ||
418 | TestClientCallback clientCallback = new TestClientCallback(); | ||
419 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
420 | vmsSubscriberManager.unregisterClientCallback(); | ||
421 | |||
422 | |||
423 | // Inject a value and wait for its callback in TestClientCallback.onLayersAvailabilityChanged. | ||
424 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
425 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
426 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
427 | .build(); | ||
428 | /* | ||
429 | Offering: | ||
430 | Layer | Dependency | ||
431 | =============================== | ||
432 | (2, 3, 444), [17] | {} | ||
433 | |||
434 | Expected availability: | ||
435 | {(2, 3, 444 [17])} | ||
436 | */ | ||
437 | v.value.int32Values.addAll( | ||
438 | Arrays.asList( | ||
439 | VmsMessageType.OFFERING, // MessageType | ||
440 | PUBLISHER_ID, | ||
441 | 1, // Number of offered layers | ||
442 | |||
443 | SUBSCRIPTION_LAYER_ID, | ||
444 | SUBSCRIPTION_LAYER_VERSION, | ||
445 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
446 | 0 // number of dependencies for layer | ||
447 | ) | ||
448 | ); | ||
449 | |||
450 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
451 | getMockedVehicleHal().injectEvent(v); | ||
452 | assertFalse(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
453 | } | ||
454 | |||
455 | // Test injecting a value in the HAL and verifying it does not propagates to a subscriber after | ||
456 | // it has unregistered its callback. | ||
457 | public void testSomething() throws Exception { | ||
458 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
459 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
460 | Car.VMS_SUBSCRIBER_SERVICE); | ||
461 | TestClientCallback clientCallback = new TestClientCallback(); | ||
462 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
463 | vmsSubscriberManager.subscribe(SUBSCRIPTION_LAYER); | ||
464 | try { | ||
465 | vmsSubscriberManager.unregisterClientCallback(); | ||
466 | } catch (IllegalArgumentException e) { | ||
467 | return; | ||
468 | } | ||
469 | fail(); | ||
470 | } | ||
471 | |||
472 | |||
473 | // Test injecting a value in the HAL and verifying it propagates to a subscriber. | ||
474 | public void testComplexAvailableLayers() throws Exception { | ||
475 | if (!VmsTestUtils.canRunTest(TAG)) return; | ||
476 | VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager( | ||
477 | Car.VMS_SUBSCRIBER_SERVICE); | ||
478 | TestClientCallback clientCallback = new TestClientCallback(); | ||
479 | vmsSubscriberManager.registerClientCallback(clientCallback); | ||
480 | |||
481 | // Inject a value and wait for its callback in TestClientCallback.onLayersAvailabilityChanged. | ||
482 | VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE) | ||
483 | .setAreaId(VehicleAreaType.VEHICLE_AREA_TYPE_NONE) | ||
484 | .setTimestamp(SystemClock.elapsedRealtimeNanos()) | ||
485 | .build(); | ||
486 | /* | ||
487 | Offering: | ||
488 | Layer | Dependency | ||
489 | ==================== | ||
490 | (2, 3, 444), [17] | {} | ||
491 | (4, 5, 444), [17] | {(2, 3)} | ||
492 | (6, 7, 444), [17] | {(2, 3), (4, 5)} | ||
493 | (6, 7, 444), [17] | {(100, 200)} | ||
494 | |||
495 | Expected availability: | ||
496 | {(2, 3, 444 [17]), (4, 5, 444 [17]), (6, 7, 444 [17])} | ||
497 | */ | ||
498 | |||
499 | v.value.int32Values.addAll( | ||
500 | Arrays.asList( | ||
501 | VmsMessageType.OFFERING, // MessageType | ||
502 | PUBLISHER_ID, | ||
503 | 4, // Number of offered layers | ||
504 | |||
505 | SUBSCRIPTION_LAYER_ID, | ||
506 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
507 | SUBSCRIPTION_LAYER_VERSION, | ||
508 | 0, // number of dependencies for layer | ||
509 | |||
510 | SUBSCRIPTION_DEPENDANT_LAYER_ID_1, | ||
511 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
512 | SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1, | ||
513 | 1, // number of dependencies for layer | ||
514 | SUBSCRIPTION_LAYER_ID, | ||
515 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
516 | SUBSCRIPTION_LAYER_VERSION, | ||
517 | |||
518 | SUBSCRIPTION_DEPENDANT_LAYER_ID_2, | ||
519 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
520 | SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2, | ||
521 | 2, // number of dependencies for layer | ||
522 | SUBSCRIPTION_LAYER_ID, | ||
523 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
524 | SUBSCRIPTION_LAYER_VERSION, | ||
525 | SUBSCRIPTION_DEPENDANT_LAYER_ID_1, | ||
526 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
527 | SUBSCRIPTION_DEPENDANT_LAYER_VERSION_1, | ||
528 | |||
529 | SUBSCRIPTION_DEPENDANT_LAYER_ID_2, | ||
530 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
531 | SUBSCRIPTION_DEPENDANT_LAYER_VERSION_2, | ||
532 | 1, // number of dependencies for layer | ||
533 | SUBSCRIPTION_UNSUPPORTED_LAYER_ID, | ||
534 | MOCK_PUBLISHER_LAYER_SUBTYPE, | ||
535 | SUBSCRIPTION_UNSUPPORTED_LAYER_VERSION | ||
536 | ) | ||
537 | ); | ||
538 | |||
539 | assertEquals(0, mSubscriberSemaphore.availablePermits()); | ||
540 | |||
541 | List<VmsAssociatedLayer> expectedAvailableLayers = | ||
542 | new ArrayList<>(Arrays.asList( | ||
543 | SUBSCRIPTION_ASSOCIATED_LAYER, | ||
544 | SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_1, | ||
545 | SUBSCRIPTION_DEPENDANT_ASSOCIATED_LAYER_2 | ||
546 | )); | ||
547 | getMockedVehicleHal().injectEvent(v); | ||
548 | assertTrue(mSubscriberSemaphore.tryAcquire(2L, TimeUnit.SECONDS)); | ||
549 | assertTrue(expectedAvailableLayers.containsAll(clientCallback.getAvailableLayers())); | ||
550 | assertEquals(expectedAvailableLayers.size(), clientCallback.getAvailableLayers().size()); | ||
551 | } | ||
552 | |||
553 | private class HalHandler implements VehicleHalPropertyHandler { | ||
554 | private VehiclePropValue mValue; | ||
555 | |||
556 | @Override | ||
557 | public synchronized void onPropertySet(VehiclePropValue value) { | ||
558 | mValue = value; | ||
559 | mHalHandlerSemaphore.release(); | ||
560 | } | ||
561 | |||
562 | @Override | ||
563 | public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) { | ||
564 | return mValue != null ? mValue : value; | ||
565 | } | ||
566 | |||
567 | @Override | ||
568 | public synchronized void onPropertySubscribe(int property, int zones, float sampleRate) { | ||
569 | Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate); | ||
570 | } | ||
571 | |||
572 | @Override | ||
573 | public synchronized void onPropertyUnsubscribe(int property) { | ||
574 | Log.d(TAG, "onPropertyUnSubscribe property " + property); | ||
575 | } | ||
576 | |||
577 | public VehiclePropValue getValue() { | ||
578 | return mValue; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | private class TestClientCallback implements VmsSubscriberClientCallback { | ||
583 | private VmsLayer mLayer; | ||
584 | private byte[] mPayload; | ||
585 | private List<VmsLayer> mAvailableLayers = new ArrayList<>(); | ||
586 | |||
587 | @Override | ||
588 | public void onVmsMessageReceived(VmsLayer layer, byte[] payload) { | ||
589 | Log.d(TAG, "onVmsMessageReceived: layer: " + layer + " Payload: " + payload); | ||
590 | mLayer = layer; | ||
591 | mPayload = payload; | ||
592 | mSubscriberSemaphore.release(); | ||
593 | } | ||
594 | |||
595 | @Override | ||
596 | public void onLayersAvailabilityChanged(List<VmsLayer> availableLayers) { | ||
597 | Log.d(TAG, "onLayersAvailabilityChanged: Layers: " + availableLayers); | ||
598 | mAvailableLayers.addAll(availableLayers); | ||
599 | mSubscriberSemaphore.release(); | ||
600 | } | ||
601 | |||
602 | public VmsLayer getLayer() { | ||
603 | return mLayer; | ||
604 | } | ||
605 | |||
606 | public byte[] getPayload() { | ||
607 | return mPayload; | ||
608 | } | ||
609 | |||
610 | public List<VmsLayer> getAvailableLayers() { | ||
611 | return mAvailableLayers; | ||
612 | } | ||
613 | } | ||
614 | } | ||
diff --git a/tests/carservice_test/src/com/android/car/test/VmsTestUtils.java b/tests/carservice_test/src/com/android/car/test/VmsTestUtils.java deleted file mode 100644 index 2f3af52a..00000000 --- a/tests/carservice_test/src/com/android/car/test/VmsTestUtils.java +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | package com.android.car.test; | ||
2 | |||
3 | import android.car.annotation.FutureFeature; | ||
4 | import android.util.Log; | ||
5 | |||
6 | import com.android.car.internal.FeatureConfiguration; | ||
7 | |||
8 | @FutureFeature | ||
9 | public class VmsTestUtils { | ||
10 | public static boolean canRunTest(String tag) { | ||
11 | if (!FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { | ||
12 | Log.i(tag, "Skipping test because ENABLE_VEHICLE_MAP_SERVICE = false"); | ||
13 | } | ||
14 | return FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE; | ||
15 | } | ||
16 | } | ||
diff --git a/tests/carservice_unit_test/src/com/android/car/VmsLayersAvailabilityTest.java b/tests/carservice_unit_test/src/com/android/car/VmsLayersAvailabilityTest.java deleted file mode 100644 index 4a09d4f8..00000000 --- a/tests/carservice_unit_test/src/com/android/car/VmsLayersAvailabilityTest.java +++ /dev/null | |||
@@ -1,266 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | import android.car.vms.VmsAssociatedLayer; | ||
20 | import android.car.vms.VmsLayer; | ||
21 | import android.car.vms.VmsLayerDependency; | ||
22 | import android.car.vms.VmsLayersOffering; | ||
23 | import android.test.AndroidTestCase; | ||
24 | import android.test.suitebuilder.annotation.SmallTest; | ||
25 | |||
26 | import java.util.Arrays; | ||
27 | import java.util.Collections; | ||
28 | import java.util.HashSet; | ||
29 | import java.util.Set; | ||
30 | |||
31 | @SmallTest | ||
32 | public class VmsLayersAvailabilityTest extends AndroidTestCase { | ||
33 | |||
34 | private static final VmsLayer LAYER_X = new VmsLayer(1, 1, 2); | ||
35 | private static final VmsLayer LAYER_Y = new VmsLayer(3, 2, 4); | ||
36 | private static final VmsLayer LAYER_Z = new VmsLayer(5, 3, 6); | ||
37 | |||
38 | private static final int PUBLISHER_ID_1 = 19; | ||
39 | private static final int PUBLISHER_ID_2 = 28; | ||
40 | |||
41 | private static final Set<Integer> PUBLISHERS_1 = new HashSet<>(Arrays.asList(PUBLISHER_ID_1)); | ||
42 | private static final Set<Integer> PUBLISHERS_2 = new HashSet<>(Arrays.asList(PUBLISHER_ID_2)); | ||
43 | private static final Set<Integer> PUBLISHERS_1_AND_2 = | ||
44 | new HashSet<>(Arrays.asList(PUBLISHER_ID_1, PUBLISHER_ID_2)); | ||
45 | |||
46 | private static final VmsLayerDependency X_DEPENDS_ON_Y = | ||
47 | new VmsLayerDependency(LAYER_X, new HashSet<VmsLayer>(Arrays.asList(LAYER_Y))); | ||
48 | |||
49 | private static final VmsLayerDependency X_DEPENDS_ON_Z = | ||
50 | new VmsLayerDependency(LAYER_X, new HashSet<VmsLayer>(Arrays.asList(LAYER_Z))); | ||
51 | |||
52 | private static final VmsLayerDependency Y_DEPENDS_ON_Z = | ||
53 | new VmsLayerDependency(LAYER_Y, new HashSet<VmsLayer>(Arrays.asList(LAYER_Z))); | ||
54 | |||
55 | private static final VmsLayerDependency Y_DEPENDS_ON_X = | ||
56 | new VmsLayerDependency(LAYER_Y, new HashSet<VmsLayer>(Arrays.asList(LAYER_X))); | ||
57 | |||
58 | private static final VmsLayerDependency Z_DEPENDS_ON_X = | ||
59 | new VmsLayerDependency(LAYER_Z, new HashSet<VmsLayer>(Arrays.asList(LAYER_X))); | ||
60 | |||
61 | private static final VmsLayerDependency Z_DEPENDS_ON_NOTHING = | ||
62 | new VmsLayerDependency(LAYER_Z); | ||
63 | |||
64 | private static final VmsLayerDependency X_DEPENDS_ON_SELF = | ||
65 | new VmsLayerDependency(LAYER_X, new HashSet<VmsLayer>(Arrays.asList(LAYER_X))); | ||
66 | |||
67 | private Set<VmsLayersOffering> mOfferings; | ||
68 | private VmsLayersAvailability mLayersAvailability; | ||
69 | |||
70 | @Override | ||
71 | protected void setUp() throws Exception { | ||
72 | mLayersAvailability = new VmsLayersAvailability(); | ||
73 | mOfferings = new HashSet<>(); | ||
74 | super.setUp(); | ||
75 | } | ||
76 | |||
77 | public void testNoOffering() { | ||
78 | assertTrue(mLayersAvailability.getAvailableLayers().isEmpty()); | ||
79 | } | ||
80 | |||
81 | public void testEmptyOffering() { | ||
82 | mLayersAvailability.setPublishersOffering(Collections.EMPTY_LIST); | ||
83 | assertTrue(mLayersAvailability.getAvailableLayers().isEmpty()); | ||
84 | } | ||
85 | |||
86 | public void testSingleLayerNoDeps() throws Exception { | ||
87 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
88 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_2)); | ||
89 | |||
90 | VmsLayersOffering offering = | ||
91 | new VmsLayersOffering(new HashSet<>(Arrays.asList(new VmsLayerDependency(LAYER_X))), | ||
92 | PUBLISHER_ID_2); | ||
93 | |||
94 | mOfferings.add(offering); | ||
95 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
96 | |||
97 | assertEquals(expectedAvailableAssociatedLayers, mLayersAvailability.getAvailableLayers()); | ||
98 | } | ||
99 | |||
100 | public void testChainOfDependenciesSatisfied() throws Exception { | ||
101 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
102 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_1)); | ||
103 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Y, PUBLISHERS_1)); | ||
104 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Z, PUBLISHERS_1)); | ||
105 | |||
106 | VmsLayersOffering offering = | ||
107 | new VmsLayersOffering( | ||
108 | new HashSet<>(Arrays.asList(X_DEPENDS_ON_Y, Y_DEPENDS_ON_Z, Z_DEPENDS_ON_NOTHING)), | ||
109 | PUBLISHER_ID_1); | ||
110 | |||
111 | mOfferings.add(offering); | ||
112 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
113 | |||
114 | assertEquals(expectedAvailableAssociatedLayers, | ||
115 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getAvailableLayers())); | ||
116 | } | ||
117 | |||
118 | public void testChainOfDependenciesSatisfiedTwoOfferings() throws Exception { | ||
119 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
120 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_1)); | ||
121 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Y, PUBLISHERS_1)); | ||
122 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Z, PUBLISHERS_1)); | ||
123 | |||
124 | VmsLayersOffering offering1 = | ||
125 | new VmsLayersOffering( | ||
126 | new HashSet<>(Arrays.asList(X_DEPENDS_ON_Y, Y_DEPENDS_ON_Z)), | ||
127 | PUBLISHER_ID_1); | ||
128 | |||
129 | VmsLayersOffering offering2 = | ||
130 | new VmsLayersOffering(new HashSet<>(Arrays.asList(Z_DEPENDS_ON_NOTHING)), | ||
131 | PUBLISHER_ID_1); | ||
132 | |||
133 | mOfferings.add(offering1); | ||
134 | mOfferings.add(offering2); | ||
135 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
136 | |||
137 | assertEquals(expectedAvailableAssociatedLayers, | ||
138 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getAvailableLayers())); | ||
139 | } | ||
140 | |||
141 | public void testChainOfDependencieNotSatisfied() throws Exception { | ||
142 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
143 | VmsLayersOffering offering = | ||
144 | new VmsLayersOffering(new HashSet<>(Arrays.asList(X_DEPENDS_ON_Y, Y_DEPENDS_ON_Z)), | ||
145 | PUBLISHER_ID_1); | ||
146 | |||
147 | mOfferings.add(offering); | ||
148 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
149 | |||
150 | assertEquals(expectedAvailableAssociatedLayers, | ||
151 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getAvailableLayers())); | ||
152 | |||
153 | Set<VmsAssociatedLayer> expectedUnavailableAssociatedLayers = new HashSet<>(); | ||
154 | expectedUnavailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_1)); | ||
155 | expectedUnavailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Y, PUBLISHERS_1)); | ||
156 | |||
157 | |||
158 | assertEquals(expectedUnavailableAssociatedLayers, | ||
159 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getUnavailableLayers())); | ||
160 | } | ||
161 | |||
162 | public void testOneOfMultipleDependencySatisfied() throws Exception { | ||
163 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
164 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_1)); | ||
165 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Z, PUBLISHERS_1)); | ||
166 | |||
167 | |||
168 | VmsLayersOffering offering = | ||
169 | new VmsLayersOffering( | ||
170 | new HashSet<>(Arrays.asList( | ||
171 | X_DEPENDS_ON_Y, X_DEPENDS_ON_Z, Z_DEPENDS_ON_NOTHING)), | ||
172 | PUBLISHER_ID_1); | ||
173 | |||
174 | mOfferings.add(offering); | ||
175 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
176 | |||
177 | assertEquals(expectedAvailableAssociatedLayers, | ||
178 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getAvailableLayers())); | ||
179 | } | ||
180 | |||
181 | public void testCyclicDependency() throws Exception { | ||
182 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
183 | |||
184 | VmsLayersOffering offering = | ||
185 | new VmsLayersOffering( | ||
186 | new HashSet<>( | ||
187 | Arrays.asList(X_DEPENDS_ON_Y, Y_DEPENDS_ON_Z, Z_DEPENDS_ON_X)), | ||
188 | PUBLISHER_ID_1); | ||
189 | |||
190 | mOfferings.add(offering); | ||
191 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
192 | |||
193 | assertEquals(expectedAvailableAssociatedLayers, | ||
194 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getAvailableLayers())); | ||
195 | } | ||
196 | |||
197 | public void testAlmostCyclicDependency() throws Exception { | ||
198 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
199 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Z, PUBLISHERS_1_AND_2)); | ||
200 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_1)); | ||
201 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Y, PUBLISHERS_2)); | ||
202 | |||
203 | VmsLayersOffering offering1 = | ||
204 | new VmsLayersOffering( | ||
205 | new HashSet<>(Arrays.asList(X_DEPENDS_ON_Y, Z_DEPENDS_ON_NOTHING)), | ||
206 | PUBLISHER_ID_1); | ||
207 | |||
208 | VmsLayersOffering offering2 = | ||
209 | new VmsLayersOffering(new HashSet<>(Arrays.asList(Y_DEPENDS_ON_Z, Z_DEPENDS_ON_X)), | ||
210 | PUBLISHER_ID_2); | ||
211 | |||
212 | mOfferings.add(offering1); | ||
213 | mOfferings.add(offering2); | ||
214 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
215 | |||
216 | assertEquals(expectedAvailableAssociatedLayers, mLayersAvailability.getAvailableLayers()); | ||
217 | } | ||
218 | |||
219 | public void testCyclicDependencyAndLayerWithoutDependency() throws Exception { | ||
220 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
221 | expectedAvailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Z, PUBLISHERS_1)); | ||
222 | |||
223 | VmsLayersOffering offering1 = | ||
224 | new VmsLayersOffering( | ||
225 | new HashSet<>( | ||
226 | Arrays.asList(X_DEPENDS_ON_Y, Z_DEPENDS_ON_NOTHING)), | ||
227 | PUBLISHER_ID_1); | ||
228 | |||
229 | VmsLayersOffering offering2 = | ||
230 | new VmsLayersOffering(new HashSet<>(Arrays.asList(Y_DEPENDS_ON_X)), PUBLISHER_ID_2); | ||
231 | |||
232 | mOfferings.add(offering1); | ||
233 | mOfferings.add(offering2); | ||
234 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
235 | |||
236 | assertEquals(expectedAvailableAssociatedLayers, | ||
237 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getAvailableLayers())); | ||
238 | |||
239 | Set<VmsAssociatedLayer> expectedUnavailableAssociatedLayers = new HashSet<>(); | ||
240 | expectedUnavailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_1)); | ||
241 | expectedUnavailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_Y, PUBLISHERS_2)); | ||
242 | |||
243 | assertEquals(expectedUnavailableAssociatedLayers, | ||
244 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getUnavailableLayers())); | ||
245 | } | ||
246 | |||
247 | public void testSelfDependency() throws Exception { | ||
248 | Set<VmsAssociatedLayer> expectedAvailableAssociatedLayers = new HashSet<>(); | ||
249 | |||
250 | VmsLayersOffering offering = | ||
251 | new VmsLayersOffering(new HashSet<>(Arrays.asList(X_DEPENDS_ON_SELF)), | ||
252 | PUBLISHER_ID_1); | ||
253 | |||
254 | mOfferings.add(offering); | ||
255 | mLayersAvailability.setPublishersOffering(mOfferings); | ||
256 | |||
257 | assertEquals(expectedAvailableAssociatedLayers, | ||
258 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getAvailableLayers())); | ||
259 | |||
260 | Set<VmsAssociatedLayer> expectedUnavailableAssociatedLayers = new HashSet<>(); | ||
261 | expectedUnavailableAssociatedLayers.add(new VmsAssociatedLayer(LAYER_X, PUBLISHERS_1)); | ||
262 | |||
263 | assertEquals(expectedUnavailableAssociatedLayers, | ||
264 | new HashSet<VmsAssociatedLayer>(mLayersAvailability.getUnavailableLayers())); | ||
265 | } | ||
266 | } \ No newline at end of file | ||
diff --git a/tests/carservice_unit_test/src/com/android/car/VmsPublishersInfoTest.java b/tests/carservice_unit_test/src/com/android/car/VmsPublishersInfoTest.java deleted file mode 100644 index 2b750129..00000000 --- a/tests/carservice_unit_test/src/com/android/car/VmsPublishersInfoTest.java +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | import android.car.annotation.FutureFeature; | ||
20 | import android.test.AndroidTestCase; | ||
21 | import android.test.suitebuilder.annotation.SmallTest; | ||
22 | |||
23 | import java.util.Arrays; | ||
24 | import java.util.Map; | ||
25 | |||
26 | @FutureFeature | ||
27 | @SmallTest | ||
28 | public class VmsPublishersInfoTest extends AndroidTestCase { | ||
29 | public static final byte[] MOCK_INFO_0 = new byte[]{2, 3, 5, 7, 11, 13, 17}; | ||
30 | public static final byte[] SAME_MOCK_INFO_0 = new byte[]{2, 3, 5, 7, 11, 13, 17}; | ||
31 | public static final byte[] MOCK_INFO_1 = new byte[]{2, 3, 5, 7, 11, 13, 17, 19}; | ||
32 | |||
33 | private VmsPublishersInfo mVmsPublishersInfo; | ||
34 | |||
35 | @Override | ||
36 | protected void setUp() throws Exception { | ||
37 | super.setUp(); | ||
38 | mVmsPublishersInfo = new VmsPublishersInfo(); | ||
39 | } | ||
40 | |||
41 | // Test one info sanity | ||
42 | public void testSingleInfo() throws Exception { | ||
43 | int id = mVmsPublishersInfo.getIdForInfo(MOCK_INFO_0); | ||
44 | assertEquals(0, id); | ||
45 | |||
46 | byte[] info = mVmsPublishersInfo.getPublisherInfo(id); | ||
47 | assertTrue(Arrays.equals(MOCK_INFO_0, info)); | ||
48 | } | ||
49 | |||
50 | // Test one info sanity - wrong ID fails. | ||
51 | public void testSingleInfoWrongId() throws Exception { | ||
52 | int id = mVmsPublishersInfo.getIdForInfo(MOCK_INFO_0); | ||
53 | assertEquals(0, id); | ||
54 | |||
55 | try { | ||
56 | byte[] info = mVmsPublishersInfo.getPublisherInfo(id + 1); | ||
57 | } | ||
58 | catch (NullPointerException e) { | ||
59 | return; | ||
60 | } | ||
61 | fail(); | ||
62 | } | ||
63 | |||
64 | // Test two infos. | ||
65 | public void testTwoInfos() throws Exception { | ||
66 | int id0 = mVmsPublishersInfo.getIdForInfo(MOCK_INFO_0); | ||
67 | int id1 = mVmsPublishersInfo.getIdForInfo(MOCK_INFO_1); | ||
68 | assertEquals(0, id0); | ||
69 | assertEquals(1, id1); | ||
70 | |||
71 | byte[] info0 = mVmsPublishersInfo.getPublisherInfo(id0); | ||
72 | byte[] info1 = mVmsPublishersInfo.getPublisherInfo(id1); | ||
73 | assertTrue(Arrays.equals(MOCK_INFO_0, info0)); | ||
74 | assertTrue(Arrays.equals(MOCK_INFO_1, info1)); | ||
75 | } | ||
76 | |||
77 | // Test same info twice get the same ID. | ||
78 | public void testSingleInfoInsertedTwice() throws Exception { | ||
79 | int id = mVmsPublishersInfo.getIdForInfo(MOCK_INFO_0); | ||
80 | assertEquals(0, id); | ||
81 | |||
82 | int sameId = mVmsPublishersInfo.getIdForInfo(SAME_MOCK_INFO_0); | ||
83 | assertEquals(sameId, id); | ||
84 | } | ||
85 | } | ||
diff --git a/tests/carservice_unit_test/src/com/android/car/VmsRoutingTest.java b/tests/carservice_unit_test/src/com/android/car/VmsRoutingTest.java deleted file mode 100644 index 8fe849b7..00000000 --- a/tests/carservice_unit_test/src/com/android/car/VmsRoutingTest.java +++ /dev/null | |||
@@ -1,309 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package com.android.car; | ||
18 | |||
19 | import android.car.vms.IVmsSubscriberClient; | ||
20 | import android.car.vms.VmsAssociatedLayer; | ||
21 | import android.car.vms.VmsLayer; | ||
22 | import android.car.vms.VmsSubscriptionState; | ||
23 | import android.test.AndroidTestCase; | ||
24 | import android.test.suitebuilder.annotation.SmallTest; | ||
25 | |||
26 | import java.util.ArrayList; | ||
27 | import java.util.Arrays; | ||
28 | import java.util.HashMap; | ||
29 | import java.util.HashSet; | ||
30 | import java.util.List; | ||
31 | import java.util.Set; | ||
32 | import java.util.Map; | ||
33 | |||
34 | @SmallTest | ||
35 | public class VmsRoutingTest extends AndroidTestCase { | ||
36 | private static VmsLayer LAYER_WITH_SUBSCRIPTION_1 = new VmsLayer(1, 1, 2); | ||
37 | private static VmsLayer LAYER_WITH_SUBSCRIPTION_2 = new VmsLayer(1, 3, 3); | ||
38 | private static VmsLayer LAYER_WITHOUT_SUBSCRIPTION = | ||
39 | new VmsLayer(1, 7, 4); | ||
40 | private static int PUBLISHER_ID_1 = 123; | ||
41 | private static int PUBLISHER_ID_2 = 456; | ||
42 | private static int PUBLISHER_ID_UNLISTED = 789; | ||
43 | private VmsRouting mRouting; | ||
44 | |||
45 | @Override | ||
46 | protected void setUp() throws Exception { | ||
47 | super.setUp(); | ||
48 | mRouting = new VmsRouting(); | ||
49 | } | ||
50 | |||
51 | public void testAddingSubscribersAndHalLayersNoOverlap() throws Exception { | ||
52 | // Add a subscription to a layer. | ||
53 | MockVmsSubscriber subscriber = new MockVmsSubscriber(); | ||
54 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1); | ||
55 | |||
56 | // Add a HAL subscription. | ||
57 | mRouting.addHalSubscription(LAYER_WITH_SUBSCRIPTION_2); | ||
58 | |||
59 | // Verify expected subscriptions are in routing manager. | ||
60 | Set<VmsLayer> expectedSubscriptions = new HashSet<>(); | ||
61 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_1); | ||
62 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_2); | ||
63 | VmsSubscriptionState subscriptionState = mRouting.getSubscriptionState(); | ||
64 | assertEquals(2, subscriptionState.getSequenceNumber()); | ||
65 | assertEquals(expectedSubscriptions, | ||
66 | new HashSet<>(subscriptionState.getLayers())); | ||
67 | |||
68 | // Verify there is only a single subscriber. | ||
69 | assertEquals(1, | ||
70 | mRouting.getSubscribersForLayerFromPublisher( | ||
71 | LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1).size()); | ||
72 | } | ||
73 | |||
74 | public void testAddingSubscribersAndHalLayersWithOverlap() throws Exception { | ||
75 | // Add a subscription to a layer. | ||
76 | MockVmsSubscriber subscriber = new MockVmsSubscriber(); | ||
77 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1); | ||
78 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_2); | ||
79 | |||
80 | // Add a HAL subscription to a layer there is already another subscriber for. | ||
81 | mRouting.addHalSubscription(LAYER_WITH_SUBSCRIPTION_2); | ||
82 | |||
83 | // Verify expected subscriptions are in routing manager. | ||
84 | Set<VmsLayer> expectedSubscriptions = new HashSet<>(); | ||
85 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_1); | ||
86 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_2); | ||
87 | VmsSubscriptionState subscriptionState = mRouting.getSubscriptionState(); | ||
88 | assertEquals(3, subscriptionState.getSequenceNumber()); | ||
89 | assertEquals(expectedSubscriptions, | ||
90 | new HashSet<>(subscriptionState.getLayers())); | ||
91 | } | ||
92 | |||
93 | public void testAddingAndRemovingLayers() throws Exception { | ||
94 | // Add a subscription to a layer. | ||
95 | MockVmsSubscriber subscriber = new MockVmsSubscriber(); | ||
96 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1); | ||
97 | |||
98 | // Add a HAL subscription. | ||
99 | mRouting.addHalSubscription(LAYER_WITH_SUBSCRIPTION_2); | ||
100 | |||
101 | // Remove a subscription to a layer. | ||
102 | mRouting.removeSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1); | ||
103 | |||
104 | // Update the HAL subscription | ||
105 | mRouting.removeHalSubscription(LAYER_WITH_SUBSCRIPTION_2); | ||
106 | |||
107 | // Verify there are no subscribers in the routing manager. | ||
108 | VmsSubscriptionState subscriptionState = mRouting.getSubscriptionState(); | ||
109 | assertEquals(4, subscriptionState.getSequenceNumber()); | ||
110 | assertTrue(subscriptionState.getLayers().isEmpty()); | ||
111 | } | ||
112 | |||
113 | public void testAddingBothTypesOfSubscribers() throws Exception { | ||
114 | // Add a subscription to a layer. | ||
115 | MockVmsSubscriber subscriberForLayer = new MockVmsSubscriber(); | ||
116 | mRouting.addSubscription(subscriberForLayer, LAYER_WITH_SUBSCRIPTION_1); | ||
117 | |||
118 | // Add a subscription without a layer. | ||
119 | MockVmsSubscriber subscriberWithoutLayer = new MockVmsSubscriber(); | ||
120 | mRouting.addSubscription(subscriberWithoutLayer); | ||
121 | |||
122 | // Verify 2 subscribers for the layer. | ||
123 | assertEquals(2, | ||
124 | mRouting.getSubscribersForLayerFromPublisher( | ||
125 | LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1).size()); | ||
126 | |||
127 | // Add the subscriber with layer as also a subscriber without layer | ||
128 | mRouting.addSubscription(subscriberForLayer); | ||
129 | |||
130 | // The number of subscribers for the layer should remain the same as before. | ||
131 | assertEquals(2, | ||
132 | mRouting.getSubscribersForLayerFromPublisher( | ||
133 | LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1).size()); | ||
134 | } | ||
135 | |||
136 | public void testOnlyRelevantSubscribers() throws Exception { | ||
137 | // Add a subscription to a layer. | ||
138 | MockVmsSubscriber subscriberForLayer = new MockVmsSubscriber(); | ||
139 | mRouting.addSubscription(subscriberForLayer, LAYER_WITH_SUBSCRIPTION_1); | ||
140 | |||
141 | // Add a subscription without a layer. | ||
142 | MockVmsSubscriber subscriberWithoutLayer = new MockVmsSubscriber(); | ||
143 | mRouting.addSubscription(subscriberWithoutLayer); | ||
144 | |||
145 | // Verify that only the subscriber without layer is returned. | ||
146 | Set<MockVmsSubscriber> expectedListeneres = new HashSet<MockVmsSubscriber>(); | ||
147 | expectedListeneres.add(subscriberWithoutLayer); | ||
148 | assertEquals(expectedListeneres, | ||
149 | mRouting.getSubscribersForLayerFromPublisher( | ||
150 | LAYER_WITHOUT_SUBSCRIPTION, PUBLISHER_ID_1)); | ||
151 | } | ||
152 | |||
153 | public void testAddingSubscribersAndHalLayersAndSubscribersToPublishers() throws Exception { | ||
154 | // Add a subscription to a layer. | ||
155 | MockVmsSubscriber subscriber = new MockVmsSubscriber(); | ||
156 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1); | ||
157 | |||
158 | // Add a HAL subscription. | ||
159 | mRouting.addHalSubscription(LAYER_WITH_SUBSCRIPTION_2); | ||
160 | |||
161 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1); | ||
162 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_2); | ||
163 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_2, PUBLISHER_ID_2); | ||
164 | |||
165 | // Verify expected subscriptions are in routing manager. | ||
166 | Set<VmsLayer> expectedSubscriptions = new HashSet<>(); | ||
167 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_1); | ||
168 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_2); | ||
169 | |||
170 | Set<VmsAssociatedLayer> expectedSubscriptionsToPublishers = new HashSet<>(); | ||
171 | expectedSubscriptionsToPublishers.add(new VmsAssociatedLayer(LAYER_WITH_SUBSCRIPTION_1, | ||
172 | new HashSet(Arrays.asList(PUBLISHER_ID_1, PUBLISHER_ID_2)))); | ||
173 | expectedSubscriptionsToPublishers.add(new VmsAssociatedLayer(LAYER_WITH_SUBSCRIPTION_2, | ||
174 | new HashSet(Arrays.asList(PUBLISHER_ID_2)))); | ||
175 | |||
176 | VmsSubscriptionState subscriptionState = mRouting.getSubscriptionState(); | ||
177 | assertEquals(5, subscriptionState.getSequenceNumber()); | ||
178 | assertEquals(expectedSubscriptions, | ||
179 | new HashSet<>(subscriptionState.getLayers())); | ||
180 | |||
181 | assertEquals(expectedSubscriptionsToPublishers, | ||
182 | subscriptionState.getAssociatedLayers()); | ||
183 | |||
184 | // Verify there is only a single subscriber. | ||
185 | assertEquals(1, | ||
186 | mRouting.getSubscribersForLayerFromPublisher( | ||
187 | LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1).size()); | ||
188 | } | ||
189 | |||
190 | public void testAddingSubscriberToPublishersAndGetListeneresToDifferentPublisher() | ||
191 | throws Exception { | ||
192 | // Add a subscription to a layer. | ||
193 | MockVmsSubscriber subscriber = new MockVmsSubscriber(); | ||
194 | |||
195 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_2); | ||
196 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1); | ||
197 | |||
198 | Set<IVmsSubscriberClient> subscribers; | ||
199 | // Need to route a layer 1 message from publisher 2 so there are no subscribers. | ||
200 | subscribers = | ||
201 | mRouting.getSubscribersForLayerFromPublisher( | ||
202 | LAYER_WITH_SUBSCRIPTION_1, | ||
203 | PUBLISHER_ID_2); | ||
204 | assertEquals(0, subscribers.size()); | ||
205 | |||
206 | // Need to route a layer 1 message from publisher 1 so there is one subscriber. | ||
207 | subscribers = | ||
208 | mRouting.getSubscribersForLayerFromPublisher( | ||
209 | LAYER_WITH_SUBSCRIPTION_1, | ||
210 | PUBLISHER_ID_1); | ||
211 | assertEquals(1, subscribers.size()); | ||
212 | assertTrue(subscribers.contains(subscriber)); | ||
213 | |||
214 | // Verify all the messages for LAYER_WITH_SUBSCRIPTION_2 have subscribers since the | ||
215 | // subscription was done without specifying a specific publisher. | ||
216 | subscribers = | ||
217 | mRouting.getSubscribersForLayerFromPublisher( | ||
218 | LAYER_WITH_SUBSCRIPTION_2, | ||
219 | PUBLISHER_ID_UNLISTED); | ||
220 | assertEquals(1, subscribers.size()); | ||
221 | assertTrue(subscribers.contains(subscriber)); | ||
222 | } | ||
223 | |||
224 | |||
225 | public void testRemovalOfSubscribersToPublishers() throws Exception { | ||
226 | // Add a subscription to a layer. | ||
227 | MockVmsSubscriber subscriber = new MockVmsSubscriber(); | ||
228 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1); | ||
229 | |||
230 | // Add a HAL subscription. | ||
231 | mRouting.addHalSubscription(LAYER_WITH_SUBSCRIPTION_2); | ||
232 | |||
233 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1); | ||
234 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_2); | ||
235 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_2, PUBLISHER_ID_2); | ||
236 | mRouting.removeSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_2, PUBLISHER_ID_2); | ||
237 | |||
238 | // Verify expected subscriptions are in routing manager. | ||
239 | Set<VmsLayer> expectedSubscriptions = new HashSet<>(); | ||
240 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_1); | ||
241 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_2); | ||
242 | |||
243 | |||
244 | Set<VmsAssociatedLayer> expectedSubscriptionsToPublishers = new HashSet<>(); | ||
245 | expectedSubscriptionsToPublishers.add(new VmsAssociatedLayer(LAYER_WITH_SUBSCRIPTION_1, | ||
246 | new HashSet(Arrays.asList(PUBLISHER_ID_1, PUBLISHER_ID_2)))); | ||
247 | |||
248 | VmsSubscriptionState subscriptionState = mRouting.getSubscriptionState(); | ||
249 | assertEquals(6, subscriptionState.getSequenceNumber()); | ||
250 | assertEquals(expectedSubscriptions, | ||
251 | new HashSet<>(subscriptionState.getLayers())); | ||
252 | |||
253 | assertEquals(expectedSubscriptionsToPublishers, | ||
254 | subscriptionState.getAssociatedLayers()); | ||
255 | |||
256 | // Verify there is only a single subscriber. | ||
257 | assertEquals(1, | ||
258 | mRouting.getSubscribersForLayerFromPublisher( | ||
259 | LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1).size()); | ||
260 | } | ||
261 | |||
262 | public void testRemovalOfSubscribersToPublishersClearListForPublisher() throws Exception { | ||
263 | // Add a subscription to a layer. | ||
264 | MockVmsSubscriber subscriber = new MockVmsSubscriber(); | ||
265 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1); | ||
266 | |||
267 | // Add a HAL subscription. | ||
268 | mRouting.addHalSubscription(LAYER_WITH_SUBSCRIPTION_2); | ||
269 | |||
270 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1); | ||
271 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_2); | ||
272 | mRouting.addSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_2, PUBLISHER_ID_2); | ||
273 | mRouting.removeSubscription(subscriber, LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1); | ||
274 | |||
275 | // Verify expected subscriptions are in routing manager. | ||
276 | Set<VmsLayer> expectedSubscriptions = new HashSet<>(); | ||
277 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_1); | ||
278 | expectedSubscriptions.add(LAYER_WITH_SUBSCRIPTION_2); | ||
279 | |||
280 | Set<VmsAssociatedLayer> expectedSubscriptionsToPublishers = new HashSet<>(); | ||
281 | expectedSubscriptionsToPublishers.add(new VmsAssociatedLayer(LAYER_WITH_SUBSCRIPTION_1, | ||
282 | new HashSet(Arrays.asList(PUBLISHER_ID_2)))); | ||
283 | expectedSubscriptionsToPublishers.add(new VmsAssociatedLayer(LAYER_WITH_SUBSCRIPTION_2, | ||
284 | new HashSet(Arrays.asList(PUBLISHER_ID_2)))); | ||
285 | |||
286 | VmsSubscriptionState subscriptionState = mRouting.getSubscriptionState(); | ||
287 | assertEquals(6, subscriptionState.getSequenceNumber()); | ||
288 | assertEquals(expectedSubscriptions, | ||
289 | new HashSet<>(subscriptionState.getLayers())); | ||
290 | |||
291 | assertEquals(expectedSubscriptionsToPublishers, | ||
292 | subscriptionState.getAssociatedLayers()); | ||
293 | |||
294 | // Verify there is only a single subscriber. | ||
295 | assertEquals(1, | ||
296 | mRouting.getSubscribersForLayerFromPublisher( | ||
297 | LAYER_WITH_SUBSCRIPTION_1, PUBLISHER_ID_1).size()); | ||
298 | } | ||
299 | |||
300 | class MockVmsSubscriber extends IVmsSubscriberClient.Stub { | ||
301 | @Override | ||
302 | public void onVmsMessageReceived(VmsLayer layer, byte[] payload) { | ||
303 | } | ||
304 | |||
305 | @Override | ||
306 | public void onLayersAvailabilityChanged(List<VmsAssociatedLayer> availableLayers) { | ||
307 | } | ||
308 | } | ||
309 | } \ No newline at end of file | ||