blob: ec1606c2bf5de798b28f92108e0d58d764a2a0a4 [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
Pavel Maltsev0d07c762016-11-03 16:40:15 -070018import android.car.Car;
Keun-young Parke54ac272016-02-16 19:02:18 -080019import 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;
Pavel Maltsev0d07c762016-11-03 16:40:15 -070022import android.os.RemoteException;
keunyoung1ab8e182015-09-24 09:25:22 -070023import android.util.Log;
24
keunyoung1ab8e182015-09-24 09:25:22 -070025import java.io.PrintWriter;
Pavel Maltsev0d07c762016-11-03 16:40:15 -070026import java.util.Arrays;
27import java.util.HashMap;
28import java.util.Map;
keunyoung1ab8e182015-09-24 09:25:22 -070029
30/**
31 * Service to allow testing / mocking vehicle HAL.
32 * This service uses Vehicle HAL APIs directly (one exception) as vehicle HAL mocking anyway
33 * requires accessing that level directly.
34 */
Pavel Maltsev0d07c762016-11-03 16:40:15 -070035class CarTestService extends ICarTest.Stub implements CarServiceBase {
36
37 private static final String TAG = CarTestService.class.getSimpleName();
keunyoung1ab8e182015-09-24 09:25:22 -070038
39 private final Context mContext;
keunyoung1ab8e182015-09-24 09:25:22 -070040 private final ICarImpl mICarImpl;
41
Pavel Maltsev0d07c762016-11-03 16:40:15 -070042 private final Map<IBinder, TokenDeathRecipient> mTokens = new HashMap<>();
43
44 CarTestService(Context context, ICarImpl carImpl) {
keunyoung1ab8e182015-09-24 09:25:22 -070045 mContext = context;
46 mICarImpl = carImpl;
keunyoung1ab8e182015-09-24 09:25:22 -070047 }
48
49 @Override
50 public void init() {
keunyoung4b0212c2015-10-29 17:11:57 -070051 // nothing to do.
52 // This service should not reset anything for init / release to maintain mocking.
keunyoung1ab8e182015-09-24 09:25:22 -070053 }
54
55 @Override
56 public void release() {
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 dump(PrintWriter writer) {
keunyoung4b0212c2015-10-29 17:11:57 -070063 writer.println("*CarTestService*");
Pavel Maltsev0d07c762016-11-03 16:40:15 -070064 writer.println(" mTokens:" + Arrays.toString(mTokens.entrySet().toArray()));
keunyoung1ab8e182015-09-24 09:25:22 -070065 }
66
67 @Override
Pavel Maltsev0d07c762016-11-03 16:40:15 -070068 public void stopCarService(IBinder token) throws RemoteException {
69 Log.d(TAG, "stopCarService, token: " + token);
70 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
keunyoung1ab8e182015-09-24 09:25:22 -070071
Keun-young Park43cfff22016-02-19 12:49:52 -080072 synchronized (this) {
Pavel Maltsev0d07c762016-11-03 16:40:15 -070073 if (mTokens.containsKey(token)) {
74 Log.w(TAG, "Calling stopCarService twice with the same token.");
75 return;
76 }
77
78 TokenDeathRecipient deathRecipient = new TokenDeathRecipient(token);
79 mTokens.put(token, deathRecipient);
80 token.linkToDeath(deathRecipient, 0);
81
82 if (mTokens.size() == 1) {
83 mICarImpl.release();
Keun-young Park43cfff22016-02-19 12:49:52 -080084 }
keunyoung5c7cb262015-10-19 10:47:45 -070085 }
keunyoung1ab8e182015-09-24 09:25:22 -070086 }
87
88 @Override
Pavel Maltsev0d07c762016-11-03 16:40:15 -070089 public void startCarService(IBinder token) throws RemoteException {
90 Log.d(TAG, "startCarService, token: " + token);
91 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
92 releaseToken(token);
keunyoung1ab8e182015-09-24 09:25:22 -070093 }
keunyoung4b0212c2015-10-29 17:11:57 -070094
Pavel Maltsev0d07c762016-11-03 16:40:15 -070095 private synchronized void releaseToken(IBinder token) {
96 Log.d(TAG, "releaseToken, token: " + token);
97 DeathRecipient deathRecipient = mTokens.remove(token);
98 if (deathRecipient != null) {
99 token.unlinkToDeath(deathRecipient, 0);
100 }
101
102 if (mTokens.size() == 0) {
103 mICarImpl.init();
104 }
Keun-young Parka28d7b22016-02-29 16:54:29 -0800105 }
106
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700107 private class TokenDeathRecipient implements DeathRecipient {
108 private final IBinder mToken;
keunyoung4b0212c2015-10-29 17:11:57 -0700109
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700110 TokenDeathRecipient(IBinder token) throws RemoteException {
111 mToken = token;
112 }
Keun-young Parka54e1162016-07-29 14:54:06 -0700113
Keun-young Parka54e1162016-07-29 14:54:06 -0700114 @Override
115 public void binderDied() {
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700116 releaseToken(mToken);
Keun-young Parka54e1162016-07-29 14:54:06 -0700117 }
118 }
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700119}