1 /* 2 * Copyright (C) 2018 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.vehiclehal.test; 17 18 import static org.junit.Assert.assertNotNull; 19 import static org.junit.Assume.assumeTrue; 20 21 import android.car.Car; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.ServiceConnection; 25 import android.hardware.automotive.vehicle.V2_0.IVehicle; 26 import android.hardware.automotive.vehicle.V2_0.StatusCode; 27 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; 28 import android.os.ConditionVariable; 29 import android.os.FileUtils; 30 import android.os.IBinder; 31 import android.support.test.InstrumentationRegistry; 32 import android.util.Log; 33 34 import com.google.android.collect.Lists; 35 36 import org.json.JSONException; 37 import org.junit.After; 38 import org.junit.Before; 39 40 import java.io.File; 41 import java.io.FileOutputStream; 42 import java.io.IOException; 43 import java.io.InputStream; 44 import java.io.OutputStream; 45 import java.util.List; 46 47 48 public class E2eCarTestBase { 49 private static final String TAG = Utils.concatTag(E2eCarTestBase.class); 50 private static final int DEFAULT_WAIT_TIMEOUT_MS = 1000; 51 52 protected IVehicle mVehicle; 53 protected Car mCar; 54 protected Context mContext; 55 private final CarConnectionListener mConnectionListener = new CarConnectionListener(); 56 57 @Before 58 public void connectToVehicleHal() throws Exception { 59 mVehicle = Utils.getVehicle(); 60 mVehicle.getPropConfigs( 61 Lists.newArrayList(VhalEventGenerator.GENERATE_FAKE_DATA_CONTROLLING_PROPERTY), 62 (status, propConfigs) -> assumeTrue(status == StatusCode.OK)); 63 } 64 65 @Before 66 public void connectToCarService() { 67 mContext = InstrumentationRegistry.getContext(); 68 mCar = Car.createCar(mContext, mConnectionListener); 69 assertNotNull(mCar); 70 mCar.connect(); 71 mConnectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); 72 } 73 74 @After 75 public void disconnect() { 76 if (mVehicle != null) { 77 mVehicle = null; 78 } 79 if (mCar != null) { 80 mCar.disconnect(); 81 mCar = null; 82 } 83 } 84 85 protected List<VehiclePropValue> getExpectedEvents(String fileName) 86 throws IOException, JSONException { 87 try (InputStream in = mContext.getAssets().open(fileName)) { 88 Log.d(TAG, "Reading golden test data" + fileName); 89 return VhalJsonReader.readFromJson(in); 90 } 91 } 92 93 /** 94 * The method copies the test data from assets/ to internal storage and make it publicly 95 * readable, so that default VHAL can access and read the test data. 96 */ 97 protected File makeShareable(String fileName) throws IOException { 98 File filesDir = mContext.getFilesDir(); 99 // Set publicly executable permission to make sure app internal storage: 100 // /data/user/0/<package> is accessible for default VHAL service 101 if (!filesDir.getParentFile().setExecutable(true, false)) { 102 Log.w(TAG, "Failed to set parent directory +x permission" 103 + filesDir.getParentFile().getAbsolutePath()); 104 } 105 File internalFile = new File(filesDir, fileName); 106 107 try ( 108 InputStream in = mContext.getAssets().open(fileName); 109 OutputStream out = new FileOutputStream(internalFile) 110 ) { 111 Log.d(TAG, "Copying golden test data to " + internalFile.getAbsolutePath()); 112 FileUtils.copy(in, out); 113 } 114 // Make sure the copied test file is publicly readable for default VHAL service. This 115 // operation is risky with security holes and should only be used for testing scenarios. 116 if (!internalFile.setReadable(true, false)) { 117 Log.w(TAG, "Failed to set read permission for " + internalFile.getAbsolutePath()); 118 } 119 return internalFile; 120 } 121 122 private static class CarConnectionListener implements ServiceConnection { 123 private final ConditionVariable mConnectionWait = new ConditionVariable(); 124 125 void waitForConnection(long timeoutMs) { 126 mConnectionWait.block(timeoutMs); 127 } 128 129 @Override 130 public void onServiceConnected(ComponentName name, IBinder service) { 131 mConnectionWait.open(); 132 } 133 134 @Override 135 public void onServiceDisconnected(ComponentName name) {} 136 } 137 } 138