blob: 9541af18c6d1680b05c94a08efcce8b8f13a9a1b [file] [log] [blame]
keunyoung1ab8e182015-09-24 09:25:22 -07001/*
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 */
16package com.android.car;
17
Keun-young Parke54ac272016-02-16 19:02:18 -080018import android.car.test.CarTestManager;
19import android.car.test.ICarTest;
keunyoung1ab8e182015-09-24 09:25:22 -070020import android.content.Context;
Keun-young Parka54e1162016-07-29 14:54:06 -070021import android.os.IBinder;
keunyoung1ab8e182015-09-24 09:25:22 -070022import android.util.Log;
23
24import com.android.car.hal.VehicleHal;
25import com.android.car.vehiclenetwork.IVehicleNetworkHalMock;
26import com.android.car.vehiclenetwork.VehicleNetwork;
Keun-young Parka28d7b22016-02-29 16:54:29 -080027import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
keunyoung1ab8e182015-09-24 09:25:22 -070028import com.android.car.vehiclenetwork.VehiclePropValueParcelable;
29
30import java.io.PrintWriter;
Keun-young Parka54e1162016-07-29 14:54:06 -070031import java.util.NoSuchElementException;
keunyoung1ab8e182015-09-24 09:25:22 -070032
33/**
34 * Service to allow testing / mocking vehicle HAL.
35 * This service uses Vehicle HAL APIs directly (one exception) as vehicle HAL mocking anyway
36 * requires accessing that level directly.
37 */
38public class CarTestService extends ICarTest.Stub implements CarServiceBase {
keunyoung1ab8e182015-09-24 09:25:22 -070039
40 private final Context mContext;
41 private final VehicleNetwork mVehicleNetwork;
42 private final ICarImpl mICarImpl;
keunyoung4b0212c2015-10-29 17:11:57 -070043 private boolean mInMocking = false;
44 private int mMockingFlags = 0;
Keun-young Park43cfff22016-02-19 12:49:52 -080045 private Exception mException = null;
Keun-young Parka54e1162016-07-29 14:54:06 -070046 private IVehicleNetworkHalMock mMock = null;
47 private final MockDeathRecipient mDeathRecipient = new MockDeathRecipient();
keunyoung1ab8e182015-09-24 09:25:22 -070048
49 public CarTestService(Context context, ICarImpl carImpl) {
50 mContext = context;
51 mICarImpl = carImpl;
52 mVehicleNetwork = VehicleHal.getInstance().getVehicleNetwork();
53 }
54
55 @Override
56 public void init() {
keunyoung4b0212c2015-10-29 17:11:57 -070057 // nothing to do.
58 // This service should not reset anything for init / release to maintain mocking.
keunyoung1ab8e182015-09-24 09:25:22 -070059 }
60
61 @Override
62 public void release() {
keunyoung4b0212c2015-10-29 17:11:57 -070063 // nothing to do
64 // This service should not reset anything for init / release to maintain mocking.
keunyoung1ab8e182015-09-24 09:25:22 -070065 }
66
67 @Override
68 public void dump(PrintWriter writer) {
keunyoung4b0212c2015-10-29 17:11:57 -070069 writer.println("*CarTestService*");
Keun-young Parka54e1162016-07-29 14:54:06 -070070 writer.println(" mInMocking:" + mInMocking);
keunyoung1ab8e182015-09-24 09:25:22 -070071 }
72
73 @Override
keunyoung1ab8e182015-09-24 09:25:22 -070074 public void injectEvent(VehiclePropValueParcelable value) {
75 ICarImpl.assertVehicleHalMockPermission(mContext);
76 mVehicleNetwork.injectEvent(value.value);
77 }
78
79 @Override
Keun-young Park43cfff22016-02-19 12:49:52 -080080 public void startMocking(final IVehicleNetworkHalMock mock, final int flags) {
keunyoung1ab8e182015-09-24 09:25:22 -070081 ICarImpl.assertVehicleHalMockPermission(mContext);
Keun-young Park43cfff22016-02-19 12:49:52 -080082 CarServiceUtils.runOnMainSync(new Runnable() {
83 @Override
84 public void run() {
85 try {
Keun-young Park43cfff22016-02-19 12:49:52 -080086 synchronized (this) {
87 mInMocking = true;
88 mMockingFlags = flags;
89 mException = null;
Keun-young Parka54e1162016-07-29 14:54:06 -070090 if (mMock != null) {
91 Log.w(CarLog.TAG_TEST,
92 "New mocking started while previous one is not stopped");
93 try {
94 mMock.asBinder().unlinkToDeath(mDeathRecipient, 0);
95 } catch (NoSuchElementException e) {
96 //ignore
97 }
98 }
99 mMock = mock;
Keun-young Park43cfff22016-02-19 12:49:52 -0800100 }
Keun-young Parka54e1162016-07-29 14:54:06 -0700101 mock.asBinder().linkToDeath(mDeathRecipient, 0);
Keun-young Park021310d2016-04-25 21:09:39 -0700102 mVehicleNetwork.startMocking(mock);
103 mICarImpl.startMocking();
Keun-young Park43cfff22016-02-19 12:49:52 -0800104 } catch (Exception e) {
105 Log.w(CarLog.TAG_TEST, "startMocking failed", e);
106 synchronized (this) {
107 mException = e;
Keun-young Park021310d2016-04-25 21:09:39 -0700108 mInMocking = false;
109 mMockingFlags = 0;
Keun-young Park43cfff22016-02-19 12:49:52 -0800110 }
111 }
112 Log.i(CarLog.TAG_TEST, "start vehicle HAL mocking, flags:0x" +
113 Integer.toHexString(flags));
keunyoung4b0212c2015-10-29 17:11:57 -0700114 }
Keun-young Park43cfff22016-02-19 12:49:52 -0800115 });
116 synchronized (this) {
117 if (mException != null) {
118 throw new IllegalStateException(mException);
119 }
keunyoung5c7cb262015-10-19 10:47:45 -0700120 }
keunyoung1ab8e182015-09-24 09:25:22 -0700121 }
122
123 @Override
Keun-young Park43cfff22016-02-19 12:49:52 -0800124 public void stopMocking(final IVehicleNetworkHalMock mock) {
keunyoung1ab8e182015-09-24 09:25:22 -0700125 ICarImpl.assertVehicleHalMockPermission(mContext);
Keun-young Park43cfff22016-02-19 12:49:52 -0800126 CarServiceUtils.runOnMainSync(new Runnable() {
127 @Override
128 public void run() {
129 try {
Keun-young Parka54e1162016-07-29 14:54:06 -0700130 synchronized (this) {
131 if (!mInMocking) {
132 throw new IllegalStateException("not in mocking");
133 }
134 if (mMock.asBinder() != mock.asBinder()) {
135 throw new IllegalArgumentException("Try to stop mocking not owned");
136 }
137 try {
138 mMock.asBinder().unlinkToDeath(mDeathRecipient, 0);
139 } catch (NoSuchElementException e) {
140 //ignore
141 }
142 }
Keun-young Park43cfff22016-02-19 12:49:52 -0800143 mVehicleNetwork.stopMocking(mock);
Keun-young Park43cfff22016-02-19 12:49:52 -0800144 mICarImpl.stopMocking();
145 synchronized (this) {
146 mInMocking = false;
147 mMockingFlags = 0;
148 mException = null;
Keun-young Parka54e1162016-07-29 14:54:06 -0700149 mMock = null;
Keun-young Park43cfff22016-02-19 12:49:52 -0800150 }
151 Log.i(CarLog.TAG_TEST, "stop vehicle HAL mocking");
152 } catch (Exception e) {
153 Log.w(CarLog.TAG_TEST, "stopMocking failed", e);
154 }
155 }
156 });
keunyoung1ab8e182015-09-24 09:25:22 -0700157 }
keunyoung4b0212c2015-10-29 17:11:57 -0700158
Keun-young Parka28d7b22016-02-29 16:54:29 -0800159 @Override
160 public boolean isPropertySupported(int property) {
161 VehiclePropConfigs configs = VehicleHal.getInstance().getVehicleNetwork().listProperties(
162 property);
163 return configs != null;
164 }
165
keunyoung4b0212c2015-10-29 17:11:57 -0700166 public synchronized boolean isInMocking() {
167 return mInMocking;
168 }
169
170 public synchronized boolean shouldDoRealShutdownInMocking() {
171 return (mMockingFlags & CarTestManager.FLAG_MOCKING_REAL_SHUTDOWN) != 0;
172 }
Keun-young Parka54e1162016-07-29 14:54:06 -0700173
174 private class MockDeathRecipient implements IBinder.DeathRecipient {
175 @Override
176 public void binderDied() {
177 CarServiceUtils.runOnMainSync(() -> {
178 try {
179 IVehicleNetworkHalMock mock;
180 synchronized (this) {
181 mock = mMock;
182 }
183 stopMocking(mock);
184 } catch (Exception e) {
185 //ignore
186 }
187 });
188 }
189 }
keunyoung1ab8e182015-09-24 09:25:22 -0700190}