diff options
author | Keun-young Park <keunyoung@google.com> | 2016-03-04 18:18:19 -0800 |
---|---|---|
committer | Keun-young Park <keunyoung@google.com> | 2016-03-07 17:33:02 -0800 |
commit | 4afc6ee52690326316e2ed1b7bc354f466849426 (patch) | |
tree | 29b69905759f623b393dfa54c51400945c2d5e67 /tests/android_support_car_api_test | |
parent | 5c6c390bac4374bc502ea8f4ffd0cb7d59506ec3 (diff) | |
download | Car-4afc6ee52690326316e2ed1b7bc354f466849426.tar.gz |
car api review: remove sensor types not relevant for embedded
- For embedded, sensor data like GPS, accelerometer, compass
should be coming from SensorManager api.
- For support lib, embedded wrapper should proxy to SensorManager
for these removed sensors
- also add support for low fuel warning.
- duplicated carapi_test into android_car_apitest and
android_support_car_apitest.
bug: 27411121
Change-Id: Idf261b0793ed5debd1d0f4ac84372ea2b7614a63
Diffstat (limited to 'tests/android_support_car_api_test')
14 files changed, 1687 insertions, 0 deletions
diff --git a/tests/android_support_car_api_test/Android.mk b/tests/android_support_car_api_test/Android.mk new file mode 100644 index 0000000000..f74fb44a48 --- /dev/null +++ b/tests/android_support_car_api_test/Android.mk @@ -0,0 +1,39 @@ +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := AndroudSupportCarApiTest + +# for system|priviledged permission. +LOCAL_CERTIFICATE := platform + +LOCAL_MODULE_TAGS := tests + +# When built explicitly put it in the data partition +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) + +LOCAL_PROGUARD_ENABLED := disabled + +LOCAL_STATIC_JAVA_LIBRARIES += android.support.car + +LOCAL_JAVA_LIBRARIES := android.car android.test.runner + +include $(BUILD_PACKAGE) diff --git a/tests/android_support_car_api_test/AndroidManifest.xml b/tests/android_support_car_api_test/AndroidManifest.xml new file mode 100644 index 0000000000..bdfb3d987e --- /dev/null +++ b/tests/android_support_car_api_test/AndroidManifest.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + package="com.android.support.car.apitest" + android:sharedUserId="android.uid.system" > + + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.support.car.apitest" + android:label="Tests for Car APIs"/> + + <application android:label="CarApiTest"> + <uses-library android:name="android.test.runner" /> + <activity android:name=".TestCarProxyActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarActivityTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarActivityTest.java new file mode 100644 index 0000000000..3cd54cc767 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarActivityTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.support.car.Car; +import android.test.ActivityInstrumentationTestCase2; + +public class CarActivityTest extends ActivityInstrumentationTestCase2<TestCarProxyActivity> { + private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000; + + private TestCarProxyActivity mActivity; + + public CarActivityTest() { + super(TestCarProxyActivity.class); + } + + public CarActivityTest(Class<TestCarProxyActivity> activityClass) { + super(activityClass); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + TestCarActivity.testCleanup(); + } + + public void testCycle() throws Throwable { + TestCarActivity.sCreateTestAction = new TestAction<TestCarActivity>() { + @Override + public void run(TestCarActivity param) { + // TODO: Add tests + } + }; + TestCarActivity.sStartTestAction = new TestAction<TestCarActivity>() { + @Override + public void run(TestCarActivity param) { + // TODO: Add tests + } + }; + TestCarActivity.sResumeTestAction = new TestAction<TestCarActivity>() { + @Override + public void run(TestCarActivity param) { + // TODO: Add tests + } + }; + TestCarActivity.sPauseTestAction = new TestAction<TestCarActivity>() { + @Override + public void run(TestCarActivity param) { + // TODO: Add tests + } + }; + TestCarActivity.sStopTestAction = new TestAction<TestCarActivity>() { + @Override + public void run(TestCarActivity param) { + // TODO: Add tests + } + }; + TestCarActivity.sDestroyTestAction = new TestAction<TestCarActivity>() { + @Override + public void run(TestCarActivity param) { + // TODO: Add tests + } + }; + mActivity = getActivity(); + TestCarActivity.sCreateTestAction.assertTestRun(DEFAULT_WAIT_TIMEOUT_MS); + TestCarActivity.sStartTestAction.assertTestRun(DEFAULT_WAIT_TIMEOUT_MS); + TestCarActivity.sResumeTestAction.assertTestRun(DEFAULT_WAIT_TIMEOUT_MS); + mActivity.finish(); + TestCarActivity.sPauseTestAction.assertTestRun(DEFAULT_WAIT_TIMEOUT_MS); + TestCarActivity.sStopTestAction.assertTestRun(DEFAULT_WAIT_TIMEOUT_MS); + TestCarActivity.sDestroyTestAction.assertTestRun(DEFAULT_WAIT_TIMEOUT_MS); + } + +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarApiTestBase.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarApiTestBase.java new file mode 100644 index 0000000000..e7d7a04be4 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarApiTestBase.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.content.ComponentName; +import android.os.IBinder; +import android.os.Looper; +import android.support.car.Car; +import android.support.car.ServiceConnectionListener; +import android.test.AndroidTestCase; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +public class CarApiTestBase extends AndroidTestCase { + protected static final long DEFAULT_WAIT_TIMEOUT_MS = 1000; + + private Car mCar; + + private final DefaultServiceConnectionListener mConnectionListener = + new DefaultServiceConnectionListener(); + + protected void assertMainThread() { + assertTrue(Looper.getMainLooper().isCurrentThread()); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mCar = Car.createCar(getContext(), mConnectionListener); + mCar.connect(); + mConnectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + mCar.disconnect(); + } + + protected synchronized Car getCar() { + return mCar; + } + + protected class DefaultServiceConnectionListener implements ServiceConnectionListener { + private final Semaphore mConnectionWait = new Semaphore(0); + + public void waitForConnection(long timeoutMs) throws InterruptedException { + mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); + } + + @Override + public void onServiceSuspended(int cause) { + assertMainThread(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + assertMainThread(); + } + + @Override + public void onServiceConnectionFailed(int cause) { + assertMainThread(); + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + assertMainThread(); + mConnectionWait.release(); + } + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarAppContextManagerTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarAppContextManagerTest.java new file mode 100644 index 0000000000..11d673796b --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarAppContextManagerTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.support.car.apitest; + +import android.support.car.Car; +import android.support.car.CarAppContextManager; +import android.util.Log; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +public class CarAppContextManagerTest extends CarApiTestBase { + private static final String TAG = CarAppContextManager.class.getSimpleName(); + private CarAppContextManager mManager; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mManager = (CarAppContextManager) getCar().getCarManager(Car.APP_CONTEXT_SERVICE); + assertNotNull(mManager); + } + + public void testUnregisteredAccess() throws Exception { + try { + mManager.setActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + fail(); + } catch (IllegalStateException e) { + // expected + } + } + + public void testRegisterNull() throws Exception { + try { + mManager.registerContextListener(null, 0); + fail(); + } catch (IllegalArgumentException e) { + // expected + } + } + + public void testRegisterUnregister() throws Exception { + ContextChangeListerner listener = new ContextChangeListerner(); + ContextChangeListerner listener2 = new ContextChangeListerner(); + mManager.registerContextListener(listener, 0); + mManager.registerContextListener(listener2, 0); + mManager.unregisterContextListener(); + // this one is no-op + mManager.unregisterContextListener(); + } + + public void testContextChange() throws Exception { + DefaultServiceConnectionListener connectionListener = + new DefaultServiceConnectionListener(); + Car car2 = Car.createCar(getContext(), connectionListener, null); + car2.connect(); + connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); + CarAppContextManager manager2 = (CarAppContextManager) + car2.getCarManager(Car.APP_CONTEXT_SERVICE); + assertNotNull(manager2); + + assertEquals(0, mManager.getActiveAppContexts()); + ContextChangeListerner owner = new ContextChangeListerner(); + ContextChangeListerner owner2 = new ContextChangeListerner(); + mManager.registerContextListener(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION | + CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); + manager2.registerContextListener(owner2, CarAppContextManager.APP_CONTEXT_NAVIGATION | + CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); + + mManager.setActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + int expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION; + assertEquals(expectedContexts, mManager.getActiveAppContexts()); + assertEquals(expectedContexts, manager2.getActiveAppContexts()); + assertTrue(mManager.isOwningContext(expectedContexts)); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION | + CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertTrue(owner2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, + expectedContexts)); + // owner should not get notification for its own change + assertFalse(owner.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + + mManager.setActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); + expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION | + CarAppContextManager.APP_CONTEXT_VOICE_COMMAND; + assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION | + CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertEquals(expectedContexts, mManager.getActiveAppContexts()); + assertEquals(expectedContexts, manager2.getActiveAppContexts()); + assertTrue(owner2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, + expectedContexts)); + // owner should not get notification for its own change + assertFalse(owner.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + + // this should be no-op + mManager.setActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + assertEquals(expectedContexts, mManager.getActiveAppContexts()); + assertEquals(expectedContexts, manager2.getActiveAppContexts()); + assertFalse(owner2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + assertFalse(owner.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + + manager2.setActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertEquals(expectedContexts, mManager.getActiveAppContexts()); + assertEquals(expectedContexts, manager2.getActiveAppContexts()); + assertTrue(owner.waitForOwnershipLossAndAssert(DEFAULT_WAIT_TIMEOUT_MS, + CarAppContextManager.APP_CONTEXT_NAVIGATION)); + + // no-op as it is not owning it + mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertEquals(expectedContexts, mManager.getActiveAppContexts()); + assertEquals(expectedContexts, manager2.getActiveAppContexts()); + + mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION; + assertEquals(expectedContexts, mManager.getActiveAppContexts()); + assertEquals(expectedContexts, manager2.getActiveAppContexts()); + assertTrue(owner2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, + CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(owner.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + + manager2.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); + assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); + expectedContexts = 0; + assertEquals(expectedContexts, mManager.getActiveAppContexts()); + assertEquals(expectedContexts, manager2.getActiveAppContexts()); + assertTrue(owner.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + mManager.unregisterContextListener(); + manager2.unregisterContextListener(); + } + + public void testFilter() throws Exception { + DefaultServiceConnectionListener connectionListener = + new DefaultServiceConnectionListener(); + Car car2 = Car.createCar(getContext(), connectionListener); + car2.connect(); + connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); + CarAppContextManager manager2 = (CarAppContextManager) + car2.getCarManager(Car.APP_CONTEXT_SERVICE); + assertNotNull(manager2); + + assertEquals(0, mManager.getActiveAppContexts()); + ContextChangeListerner owner = new ContextChangeListerner(); + ContextChangeListerner listener = new ContextChangeListerner(); + mManager.registerContextListener(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION | + CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); + manager2.registerContextListener(listener, CarAppContextManager.APP_CONTEXT_NAVIGATION); + mManager.setActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + assertTrue(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, + CarAppContextManager.APP_CONTEXT_NAVIGATION)); + mManager.setActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); + assertFalse(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); + assertFalse(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); + assertTrue(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); + } + + private class ContextChangeListerner implements CarAppContextManager.AppContextChangeListener { + private int mLastChangeEvent; + private final Semaphore mChangeWait = new Semaphore(0); + private int mLastLossEvent; + private final Semaphore mLossEventWait = new Semaphore(0); + + public boolean waitForContextChangeAndAssert(long timeoutMs, int expectedContexts) + throws Exception { + if (!mChangeWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { + return false; + } + assertEquals(expectedContexts, mLastChangeEvent); + return true; + } + + public boolean waitForOwnershipLossAndAssert(long timeoutMs, int expectedContexts) + throws Exception { + if (!mLossEventWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { + return false; + } + assertEquals(expectedContexts, mLastLossEvent); + return true; + } + + @Override + public void onAppContextChange(int activeContexts) { + Log.i(TAG, "onAppContextChange " + Integer.toHexString(activeContexts)); + assertMainThread(); + mLastChangeEvent = activeContexts; + mChangeWait.release(); + } + + @Override + public void onAppContextOwnershipLoss(int context) { + Log.i(TAG, "onAppContextOwnershipLoss " + Integer.toHexString(context)); + assertMainThread(); + mLastLossEvent = context; + mLossEventWait.release(); + } + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarConnectionListenerTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarConnectionListenerTest.java new file mode 100644 index 0000000000..3349763e21 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarConnectionListenerTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.support.car.Car; +import android.support.car.CarConnectionListener; +import android.util.Log; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +public class CarConnectionListenerTest extends CarApiTestBase { + private static final String TAG = CarConnectionListenerTest.class.getSimpleName(); + + public void testRegisterUnregister() throws Exception { + CarConnectionListerImpl listener = new CarConnectionListerImpl(); + getCar().registerCarConnectionListener(listener); + assertTrue(listener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS)); + getCar().unregisterCarConnectionListener(listener); + } + + public void testMultiple() throws Exception { + CarConnectionListerImpl listener1 = new CarConnectionListerImpl(); + getCar().registerCarConnectionListener(listener1); + assertTrue(listener1.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS)); + CarConnectionListerImpl listener2 = new CarConnectionListerImpl(); + getCar().registerCarConnectionListener(listener2); + assertTrue(listener2.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS)); + assertFalse(listener1.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS)); + getCar().unregisterCarConnectionListener(listener2); + getCar().unregisterCarConnectionListener(listener1); + } + + private class CarConnectionListerImpl implements CarConnectionListener { + int mConnectionType; + boolean mIsConnected = false; + private Semaphore mWaitSemaphore = new Semaphore(0); + + @Override + public void onConnected(int connectionType) { + Log.i(TAG, "onConnected " + connectionType); + mConnectionType = connectionType; + mIsConnected = true; + mWaitSemaphore.release(); + } + + @Override + public void onDisconnected() { + Log.i(TAG, "onDisconnected"); + mIsConnected = false; + mWaitSemaphore.release(); + } + + public boolean waitForConnection(long timeoutMs) throws Exception { + if (!mWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { + return false; + } + assertTrue(mIsConnected); + assertEquals(Car.CONNECTION_TYPE_EMBEDDED, mConnectionType); + return true; + } + + public boolean waitForDisconnect(long timeoutMs) throws Exception { + if (!mWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { + return false; + } + assertFalse(mIsConnected); + return true; + } + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarNavigationManagerTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarNavigationManagerTest.java new file mode 100644 index 0000000000..0ab40b0823 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarNavigationManagerTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.support.car.apitest; + +import static android.support.car.CarAppContextManager.APP_CONTEXT_NAVIGATION; + +import android.os.Looper; +import android.support.car.Car; +import android.support.car.CarAppContextManager; +import android.support.car.CarAppContextManager.AppContextChangeListener; +import android.support.car.navigation.CarNavigationInstrumentCluster; +import android.support.car.CarNotConnectedException; +import android.support.car.navigation.CarNavigationManager; +import android.support.car.navigation.CarNavigationManager.CarNavigationListener; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * Unit tests for {@link android.support.car.navigation.CarNavigationStatusManager} + */ +public class CarNavigationManagerTest extends CarApiTestBase { + + private CarNavigationManager mCarNavigationManager; + private CarAppContextManager mCarAppContextManager; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mCarNavigationManager = + (CarNavigationManager) getCar().getCarManager(Car.CAR_NAVIGATION_SERVICE); + assertNotNull(mCarNavigationManager); + mCarAppContextManager = + (CarAppContextManager) getCar().getCarManager(Car.APP_CONTEXT_SERVICE); + assertNotNull(mCarAppContextManager); + } + + public void testStart() throws Exception { + final CountDownLatch onStartLatch = new CountDownLatch(1); + + mCarNavigationManager.registerListener(new CarNavigationListener() { + @Override + public void onInstrumentClusterStart(CarNavigationInstrumentCluster instrumentCluster) { + // TODO: we should use VehicleHalMock once we implement HAL support in + // CarNavigationStatusService. + assertFalse(instrumentCluster.supportsCustomImages()); + assertEquals(1000, instrumentCluster.getMinIntervalMs()); + onStartLatch.countDown(); + } + + @Override + public void onInstrumentClusterStop() { + // TODO + } + }); + + assertTrue(onStartLatch.await(DEFAULT_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + + try { + mCarNavigationManager.sendNavigationStatus(1); + fail(); + } catch (IllegalStateException expected) { + // Expected. Client should acquire context ownership for APP_CONTEXT_NAVIGATION. + } + + mCarAppContextManager.registerContextListener(new AppContextChangeListener() { + @Override + public void onAppContextChange(int activeContexts) { + // Nothing to do here. + } + + @Override + public void onAppContextOwnershipLoss(int context) { + // Nothing to do here. + } + }, APP_CONTEXT_NAVIGATION); + mCarAppContextManager.setActiveContexts(APP_CONTEXT_NAVIGATION); + assertTrue(mCarAppContextManager.isOwningContext(APP_CONTEXT_NAVIGATION)); + + // TODO: we should use mocked HAL to be able to verify this, right now just make sure that + // it is not crashing and logcat has appropriate traces. + mCarNavigationManager.sendNavigationStatus(1); + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarPackageManagerTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarPackageManagerTest.java new file mode 100644 index 0000000000..c9bbad0512 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarPackageManagerTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.content.ComponentName; +import android.os.IBinder; +import android.os.Looper; +import android.support.car.Car; +import android.support.car.ServiceConnectionListener; +import android.support.car.content.pm.CarPackageManager; +import android.test.AndroidTestCase; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +public class CarPackageManagerTest extends AndroidTestCase { + private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000; + + private final Semaphore mConnectionWait = new Semaphore(0); + + private Car mCar; + private CarPackageManager mCarPackageManager; + + private final ServiceConnectionListener mConnectionListener = new ServiceConnectionListener() { + + @Override + public void onServiceSuspended(int cause) { + assertMainThread(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + assertMainThread(); + } + + @Override + public void onServiceConnectionFailed(int cause) { + assertMainThread(); + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + assertMainThread(); + mConnectionWait.release(); + } + }; + + private void assertMainThread() { + assertTrue(Looper.getMainLooper().isCurrentThread()); + } + private void waitForConnection(long timeoutMs) throws InterruptedException { + mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mCar = Car.createCar(getContext(), mConnectionListener); + mCar.connect(); + waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); + mCarPackageManager = (CarPackageManager) mCar.getCarManager(Car.PACKAGE_SERVICE); + assertNotNull(mCarPackageManager); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + mCar.disconnect(); + } + + public void testCreate() throws Exception { + //nothing to do for now + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarSensorManagerTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarSensorManagerTest.java new file mode 100644 index 0000000000..e30afe0cd5 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarSensorManagerTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.content.ComponentName; +import android.os.IBinder; +import android.os.Looper; +import android.support.car.Car; +import android.support.car.ServiceConnectionListener; +import android.support.car.hardware.CarSensorEvent; +import android.support.car.hardware.CarSensorManager; +import android.test.AndroidTestCase; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + + +public class CarSensorManagerTest extends AndroidTestCase { + private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000; + + private final Semaphore mConnectionWait = new Semaphore(0); + + private Car mCar; + private CarSensorManager mCarSensorManager; + + private final ServiceConnectionListener mConnectionListener = new ServiceConnectionListener() { + + @Override + public void onServiceSuspended(int cause) { + assertMainThread(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + assertMainThread(); + } + + @Override + public void onServiceConnectionFailed(int cause) { + assertMainThread(); + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + assertMainThread(); + mConnectionWait.release(); + } + }; + + private void assertMainThread() { + assertTrue(Looper.getMainLooper().isCurrentThread()); + } + private void waitForConnection(long timeoutMs) throws InterruptedException { + mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mCar = Car.createCar(getContext(), mConnectionListener); + mCar.connect(); + waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); + mCarSensorManager = + (CarSensorManager) mCar.getCarManager(Car.SENSOR_SERVICE); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + mCar.disconnect(); + } + + public void testDrivingPolicy() throws Exception { + int[] supportedSensors = mCarSensorManager.getSupportedSensors(); + assertNotNull(supportedSensors); + boolean found = false; + for (int sensor: supportedSensors) { + if (sensor == CarSensorManager.SENSOR_TYPE_DRIVING_STATUS) { + found = true; + break; + } + } + assertTrue(found); + assertTrue(mCarSensorManager.isSensorSupported( + CarSensorManager.SENSOR_TYPE_DRIVING_STATUS)); + assertTrue(CarSensorManager.isSensorSupported(supportedSensors, + CarSensorManager.SENSOR_TYPE_DRIVING_STATUS)); + CarSensorEvent lastEvent = mCarSensorManager.getLatestSensorEvent( + CarSensorManager.SENSOR_TYPE_DRIVING_STATUS); + assertNotNull(lastEvent); + } + + public void testSensorType() throws Exception { + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_CAR_SPEED, + CarSensorManager.SENSOR_TYPE_CAR_SPEED); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_DRIVING_STATUS, + CarSensorManager.SENSOR_TYPE_DRIVING_STATUS); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_ENVIRONMENT, + CarSensorManager.SENSOR_TYPE_ENVIRONMENT); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_FUEL_LEVEL, + CarSensorManager.SENSOR_TYPE_FUEL_LEVEL); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_GEAR, + CarSensorManager.SENSOR_TYPE_GEAR); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_NIGHT, + CarSensorManager.SENSOR_TYPE_NIGHT); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_ODOMETER, + CarSensorManager.SENSOR_TYPE_ODOMETER); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_PARKING_BRAKE, + CarSensorManager.SENSOR_TYPE_PARKING_BRAKE); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_RPM, + CarSensorManager.SENSOR_TYPE_RPM); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_VENDOR_EXTENSION_START, + CarSensorManager.SENSOR_TYPE_VENDOR_EXTENSION_START); + assertEquals(android.car.hardware.CarSensorManager.SENSOR_TYPE_VENDOR_EXTENSION_END, + CarSensorManager.SENSOR_TYPE_VENDOR_EXTENSION_END); + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarTest.java new file mode 100644 index 0000000000..14e6f19ee3 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/CarTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.content.ComponentName; +import android.os.IBinder; +import android.os.Looper; +import android.support.car.Car; +import android.support.car.hardware.CarSensorManager; +import android.support.car.ServiceConnectionListener; +import android.test.AndroidTestCase; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + + +public class CarTest extends AndroidTestCase { + private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000; + + private final Semaphore mConnectionWait = new Semaphore(0); + + private final ServiceConnectionListener mConnectionListener = new ServiceConnectionListener() { + + @Override + public void onServiceSuspended(int cause) { + assertMainThread(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + assertMainThread(); + } + + @Override + public void onServiceConnectionFailed(int cause) { + assertMainThread(); + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + assertMainThread(); + mConnectionWait.release(); + } + }; + + private void assertMainThread() { + assertTrue(Looper.getMainLooper().isCurrentThread()); + } + + private void waitForConnection(long timeoutMs) throws InterruptedException { + mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS); + } + + public void testCarConnection() throws Exception { + Car car = Car.createCar(getContext(), mConnectionListener); + assertFalse(car.isConnected()); + assertFalse(car.isConnecting()); + car.connect(); + //TODO fix race here + assertTrue(car.isConnecting()); + waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); + assertTrue(car.isConnected()); + assertFalse(car.isConnecting()); + CarSensorManager carSensorManager = + (CarSensorManager) car.getCarManager(Car.SENSOR_SERVICE); + assertNotNull(carSensorManager); + CarSensorManager carSensorManager2 = + (CarSensorManager) car.getCarManager(Car.SENSOR_SERVICE); + assertEquals(carSensorManager, carSensorManager2); + Object noSuchService = car.getCarManager("No such service"); + assertNull(noSuchService); + // double disconnect should be safe. + car.disconnect(); + car.disconnect(); + assertFalse(car.isConnected()); + assertFalse(car.isConnecting()); + } + + public void testDoubleConnect() throws Exception { + Car car = Car.createCar(getContext(), mConnectionListener); + assertFalse(car.isConnected()); + assertFalse(car.isConnecting()); + car.connect(); + try { + car.connect(); + fail("dobule connect should throw"); + } catch (IllegalStateException e) { + // expected + } + car.disconnect(); + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/ExtendableParcelableTest.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/ExtendableParcelableTest.java new file mode 100644 index 0000000000..d6a3264f5f --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/ExtendableParcelableTest.java @@ -0,0 +1,482 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.support.car.apitest; + +import android.os.Parcel; +import android.support.car.annotation.VersionDef; +import android.support.car.os.ExtendableParcelable; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.util.Arrays; + +public class ExtendableParcelableTest extends AndroidTestCase { + + private static final String TAG = ExtendableParcelableTest.class.getSimpleName(); + + public static class V1Parcelable extends ExtendableParcelable { + @VersionDef(version = 1) + public final byte[] byteData0; + @VersionDef(version = 1) + public final int intData0; + @VersionDef(version = 1) + public final String stringData0; + @VersionDef(version = 1) + public final int intData1; + + private static final int VERSION = 1; + + public V1Parcelable(byte[] byteData0, int intData0, String stringData0, int intData1) { + super(VERSION); + this.byteData0 = byteData0; + this.intData0 = intData0; + this.stringData0 = stringData0; + this.intData1 = intData1; + } + + public V1Parcelable(Parcel in) { + super(in, VERSION); + int lastPosition = readHeader(in); + byteData0 = in.createByteArray(); + intData0 = in.readInt(); + stringData0 = in.readString(); + intData1 = in.readInt(); + completeReading(in, lastPosition); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + int pos = writeHeader(dest); + dest.writeByteArray(byteData0); + dest.writeInt(intData0); + dest.writeString(stringData0); + dest.writeInt(intData1); + completeWriting(dest, pos); + } + + @Override + public boolean equals(Object o) { + if (o instanceof V1Parcelable) { + V1Parcelable other = (V1Parcelable) o; + return Arrays.equals(byteData0, other.byteData0) && intData0 == other.intData0 && + (stringData0 == null ? other.stringData0 == null : + stringData0.equals(other.stringData0)) && + intData1 == other.intData1; + } + return false; + } + + @Override + public String toString() { + return "V1Parcelable byteData0:" + Arrays.toString(byteData0) + ",intData0:" + intData0 + + ",stringData0:" + stringData0 + ",intData1:" + intData1; + } + } + + public static class V2Parcelable extends ExtendableParcelable { + @VersionDef(version = 1) + public final byte[] byteData0; + @VersionDef(version = 1) + public final int intData0; + @VersionDef(version = 1) + public final String stringData0; + @VersionDef(version = 1) + public final int intData1; + @VersionDef(version = 2) + public final byte[] byteData1; + @VersionDef(version = 2) + public final int intData2; + + private static final int VERSION = 2; + + public V2Parcelable(byte[] byteData0, int intData0, String stringData0, int intData1, + byte[] byteData1, int intData2) { + super(VERSION); + this.byteData0 = byteData0; + this.intData0 = intData0; + this.stringData0 = stringData0; + this.intData1 = intData1; + this.byteData1 = byteData1; + this.intData2 = intData2; + } + + public V2Parcelable(Parcel in) { + super(in, VERSION); + int lastPosition = readHeader(in); + byteData0 = in.createByteArray(); + intData0 = in.readInt(); + stringData0 = in.readString(); + intData1 = in.readInt(); + if (version >= 2) { // do not use VERSION here as VERSION will become 3 in next revision + byteData1 = in.createByteArray(); + intData2 = in.readInt(); + } else { + byteData1 = null; + intData2 = 0; + } + completeReading(in, lastPosition); + } + + /** provide has method if null check is not possible. */ + public boolean hasIntData1() { + return version >= 2; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + int pos = writeHeader(dest); + dest.writeByteArray(byteData0); + dest.writeInt(intData0); + dest.writeString(stringData0); + dest.writeInt(intData1); + dest.writeByteArray(byteData1); + dest.writeInt(intData2); + completeWriting(dest, pos); + } + + @Override + public boolean equals(Object o) { + if (o instanceof V2Parcelable) { + V2Parcelable other = (V2Parcelable) o; + return Arrays.equals(byteData0, other.byteData0) && intData0 == other.intData0 && + (stringData0 == null ? other.stringData0 == null : + stringData0.equals(other.stringData0)) && + intData1 == other.intData1 && Arrays.equals(byteData1, other.byteData1) + && intData2 == other.intData2; + } + return false; + } + + @Override + public String toString() { + return "V2Parcelable byteData0:" + Arrays.toString(byteData0) + ",intData0:" + intData0 + + ",stringData0:" + stringData0 + ",intData1:" + intData1 + + ",byteData1:" + Arrays.toString(byteData1) + ",intData2:" + intData2; + } + } + + public static class V3Parcelable extends ExtendableParcelable { + @VersionDef(version = 1) + public final byte[] byteData0; + @VersionDef(version = 1) + public final int intData0; + @VersionDef(version = 1) + public final String stringData0; + @VersionDef(version = 1) + public final int intData1; + @VersionDef(version = 2) + public final byte[] byteData1; + @VersionDef(version = 2) + public final int intData2; + @VersionDef(version = 3) + public final String stringData1; + @VersionDef(version = 3) + public final int intData3; + + private static final int VERSION = 3; + + public V3Parcelable(byte[] byteData0, int intData0, String stringData0, int intData1, + byte[] byteData1, int intData2, String stringData1, int intData3) { + super(VERSION); + this.byteData0 = byteData0; + this.intData0 = intData0; + this.stringData0 = stringData0; + this.intData1 = intData1; + this.byteData1 = byteData1; + this.intData2 = intData2; + this.stringData1 = stringData1; + this.intData3 = intData3; + } + + public V3Parcelable(Parcel in) { + super(in, VERSION); + int lastPosition = readHeader(in); + byteData0 = in.createByteArray(); + intData0 = in.readInt(); + stringData0 = in.readString(); + intData1 = in.readInt(); + if (version >= 2) { + byteData1 = in.createByteArray(); + intData2 = in.readInt(); + } else { + byteData1 = null; + intData2 = 0; + } + if (version >= 3) { + stringData1 = in.readString(); + intData3 = in.readInt(); + } else { + stringData1 = null; + intData3 = 0; + } + completeReading(in, lastPosition); + } + + /** provide has method if null check is not possible. */ + public boolean hasIntData1() { + return version >= 2; + } + + /** provide has method if null check is not possible. */ + public boolean hasIntData2() { + return version >= 3; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + int pos = writeHeader(dest); + dest.writeByteArray(byteData0); + dest.writeInt(intData0); + dest.writeString(stringData0); + dest.writeInt(intData1); + dest.writeByteArray(byteData1); + dest.writeInt(intData2); + dest.writeString(stringData1); + dest.writeInt(intData3); + completeWriting(dest, pos); + } + + @Override + public boolean equals(Object o) { + if (o instanceof V3Parcelable) { + V3Parcelable other = (V3Parcelable) o; + return Arrays.equals(byteData0, other.byteData0) && intData0 == other.intData0 && + (stringData0 == null ? other.stringData0 == null : + stringData0.equals(other.stringData0)) && + intData1 == other.intData1 && Arrays.equals(byteData1, other.byteData1) + && intData2 == other.intData2 && + (stringData1 == null ? other.stringData1 == null : + stringData1.equals(other.stringData1)) && + intData3 == other.intData3; + } + return false; + } + + @Override + public String toString() { + return "V3Parcelable byteData0:" + Arrays.toString(byteData0) + ",intData0:" + intData0 + + ",stringData0:" + stringData0 + ",intData1:" + intData1 + + ",byteData1:" + Arrays.toString(byteData1) + ",intData2:" + intData2 + + ",stringData1:" + stringData1 + ",intData3:" + intData3; + } + } + + public void testV1ToV3() throws Exception { + Parcel p = Parcel.obtain(); + int startPos = p.dataPosition(); + byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 }; + int intData0 = 1234; + String stringData0 = null; + int intData1 = 5678; + V1Parcelable v1 = new V1Parcelable(byteData0, intData0, stringData0, intData1); + // expected after reading parcel + V3Parcelable v3Expected = new V3Parcelable(byteData0, intData0, stringData0, intData1, + null, 0, null, 0); + v1.writeToParcel(p, 0); + final int additionalData = 0x8fffffff; + p.writeInt(additionalData); + + p.setDataPosition(startPos); + V3Parcelable v3 = new V3Parcelable(p); + Log.i(TAG, "v1:" + v1); + Log.i(TAG, "v3 expected:" + v3Expected); + Log.i(TAG, "v3 read:" + v3); + assertTrue(v3Expected.equals(v3)); + assertEquals(1, v3.version); + assertFalse(v3.hasIntData1()); + assertFalse(v3.hasIntData2()); + assertEquals(additionalData, p.readInt()); + } + + public void testV2ToV3() throws Exception { + Parcel p = Parcel.obtain(); + int startPos = p.dataPosition(); + byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 }; + int intData0 = 1234; + String stringData0 = null; + int intData1 = 5678; + byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 }; + int intData2 = 9012; + V2Parcelable v2 = new V2Parcelable(byteData0, intData0, stringData0, intData1, byteData1, + intData2); + // expected after reading parcel + V3Parcelable v3Expected = new V3Parcelable(byteData0, intData0, stringData0, intData1, + byteData1, intData2, null, 0); + v2.writeToParcel(p, 0); + final int additionalData = 0x8fffffff; + p.writeInt(additionalData); + + p.setDataPosition(startPos); + V3Parcelable v3 = new V3Parcelable(p); + Log.i(TAG, "v2:" + v2); + Log.i(TAG, "v3 expected:" + v3Expected); + Log.i(TAG, "v3 read:" + v3); + assertTrue(v3Expected.equals(v3)); + assertEquals(2, v3.version); + assertTrue(v3.hasIntData1()); + assertFalse(v3.hasIntData2()); + assertEquals(additionalData, p.readInt()); + } + + public void testV3ToV1() throws Exception { + Parcel p = Parcel.obtain(); + int startPos = p.dataPosition(); + byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 }; + int intData0 = 1234; + String stringData0 = null; + int intData1 = 5678; + byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 }; + int intData2 = 9012; + // v3 + String stringData1 = "Hello"; + int intData3 = -1; + V3Parcelable v3 = new V3Parcelable(byteData0, intData0, stringData0, intData1, byteData1, + intData2, stringData1, intData3); + // expected after reading parcel + V1Parcelable v1Expected = new V1Parcelable(byteData0, intData0, stringData0, intData1); + v3.writeToParcel(p, 0); + final int additionalData = 0x8fffffff; + p.writeInt(additionalData); + + p.setDataPosition(startPos); + V1Parcelable v1 = new V1Parcelable(p); + Log.i(TAG, "v3:" + v3); + Log.i(TAG, "v1 expected:" + v1Expected); + Log.i(TAG, "v1 read:" + v1); + assertTrue(v1Expected.equals(v1)); + assertEquals(1, v1.version); + assertEquals(additionalData, p.readInt()); + } + + public void testV2ToV2() throws Exception { + Parcel p = Parcel.obtain(); + int startPos = p.dataPosition(); + byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 }; + int intData0 = 1234; + String stringData0 = null; + int intData1 = 5678; + byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 }; + int intData2 = 9012; + V2Parcelable v2 = new V2Parcelable(byteData0, intData0, stringData0, intData1, byteData1, + intData2); + v2.writeToParcel(p, 0); + final int additionalData = 0x8fffffff; + p.writeInt(additionalData); + + p.setDataPosition(startPos); + V2Parcelable v2Read = new V2Parcelable(p); + Log.i(TAG, "v2:" + v2); + Log.i(TAG, "v2 read:" + v2Read); + assertTrue(v2.equals(v2Read)); + assertEquals(2, v2.version); + assertTrue(v2.hasIntData1()); + assertEquals(additionalData, p.readInt()); + } + + public void testV3ToV1Array() throws Exception { + Parcel p = Parcel.obtain(); + int startPos = p.dataPosition(); + byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 }; + int intData0 = 1234; + String stringData0 = null; + int intData1 = 5678; + byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 }; + int intData2 = 9012; + // v3 + String stringData1 = "Hello"; + int intData3 = -1; + V3Parcelable v3_0 = new V3Parcelable(byteData0, intData0, stringData0, intData1, byteData1, + intData2, stringData1, intData3); + V1Parcelable v1Expected0 = new V1Parcelable(byteData0, intData0, stringData0, intData1); + byteData0 = null; + intData0 = 1; + stringData0 = "world"; + V3Parcelable v3_1 = new V3Parcelable(byteData0, intData0, stringData0, intData1, byteData1, + intData2, stringData1, intData3); + V1Parcelable v1Expected1 = new V1Parcelable(byteData0, intData0, stringData0, intData1); + // test write of arrays without initial length portion + v3_0.writeToParcel(p, 0); + v3_1.writeToParcel(p, 0); + final int additionalData = 0x8fffffff; + p.writeInt(additionalData); + + p.setDataPosition(startPos); + V1Parcelable v1_0 = new V1Parcelable(p); + V1Parcelable v1_1 = new V1Parcelable(p); + Log.i(TAG, "v3_1:" + v3_1); + Log.i(TAG, "v1 expected 1:" + v1Expected1); + Log.i(TAG, "v1_1 read:" + v1_1); + assertTrue(v1Expected0.equals(v1_0)); + assertTrue(v1Expected1.equals(v1_1)); + assertEquals(1, v1_0.version); + assertEquals(1, v1_1.version); + assertEquals(additionalData, p.readInt()); + } + + public void testV1ToV3Array() throws Exception { + Parcel p = Parcel.obtain(); + int startPos = p.dataPosition(); + byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 }; + int intData0 = 1234; + String stringData0 = null; + int intData1 = 5678; + V1Parcelable v1_0 = new V1Parcelable(byteData0, intData0, stringData0, intData1); + // expected after reading parcel + V3Parcelable v3Expected0 = new V3Parcelable(byteData0, intData0, stringData0, intData1, + null, 0, null, 0); + byteData0 = null; + intData0 = 4567; + stringData0 = "Hi"; + V1Parcelable v1_1 = new V1Parcelable(byteData0, intData0, stringData0, intData1); + // expected after reading parcel + V3Parcelable v3Expected1 = new V3Parcelable(byteData0, intData0, stringData0, intData1, + null, 0, null, 0); + v1_0.writeToParcel(p, 0); + v1_1.writeToParcel(p, 0); + final int additionalData = 0x8fffffff; + p.writeInt(additionalData); + + p.setDataPosition(startPos); + V3Parcelable v3_0 = new V3Parcelable(p); + V3Parcelable v3_1 = new V3Parcelable(p); + Log.i(TAG, "v1:" + v1_1); + Log.i(TAG, "v3 expected:" + v3Expected1); + Log.i(TAG, "v3 read:" + v3_1); + assertTrue(v3Expected0.equals(v3_0)); + assertFalse(v3_0.hasIntData1()); + assertFalse(v3_0.hasIntData2()); + assertFalse(v3_1.hasIntData1()); + assertFalse(v3_1.hasIntData2()); + assertEquals(1, v3_0.version); + assertEquals(1, v3_1.version); + assertEquals(additionalData, p.readInt()); + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestAction.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestAction.java new file mode 100644 index 0000000000..472b82579d --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestAction.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.util.Log; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import junit.framework.Assert; + +/** + * A generic test action, whose run method will be called with a parameter. + */ +public abstract class TestAction<T> { + /** for passing additional test specific parameters */ + public volatile Object arg0; + public volatile Object arg1; + private static final String TAG = "CAR.TEST"; + private Throwable mLastThrowable; + private Semaphore mWaitSemaphore = new Semaphore(0); + + abstract public void run(T param); + + public void doRun(T param) { + Log.i(TAG, "TestAction doRun " + this + " param:" + param); + try { + run(param); + } catch (Throwable t) { + Log.i(TAG, "TestAction doRun get exception", t); + mLastThrowable = t; + } + mWaitSemaphore.release(); + } + + public void assertTestRun(long timeoutMs) throws Throwable { + if (!mWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { + Assert.fail("timeout"); + } + if (mLastThrowable != null) { + throw mLastThrowable; + } + } + + public void assertNotRun(long waitMs) throws Throwable { + if (!mWaitSemaphore.tryAcquire(waitMs, TimeUnit.MILLISECONDS)) { + return; + } + if (mLastThrowable != null) { + Log.e(TAG, "Action was run, but failed"); + throw mLastThrowable; + } + Assert.fail("Action was run"); + } + + public boolean waitForTest(long timeoutMs) throws Throwable { + if (mWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { + if (mLastThrowable != null) { + throw mLastThrowable; + } + return true; + } + return false; + } + + public void resetRunState() { + mWaitSemaphore.drainPermits(); + } + + public static <U> TestAction<U> buildEmptyAction() { + return new TestAction<U>() { + @Override + public void run(U param) { + } + }; + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestCarActivity.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestCarActivity.java new file mode 100644 index 0000000000..4df67502ed --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestCarActivity.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.content.Context; +import android.os.Bundle; +import android.support.car.Car; +import android.support.car.CarNotConnectedException; +import android.support.car.CarNotSupportedException; +import android.support.car.app.CarActivity; +import android.util.Log; + +public class TestCarActivity extends CarActivity { + private static final String TAG = TestCarActivity.class.getSimpleName(); + + public static volatile TestAction<TestCarActivity> sCreateTestAction; + public static volatile TestAction<TestCarActivity> sStartTestAction; + public static volatile TestAction<TestCarActivity> sResumeTestAction; + public static volatile TestAction<TestCarActivity> sPauseTestAction; + public static volatile TestAction<TestCarActivity> sStopTestAction; + public static volatile TestAction<TestCarActivity> sDestroyTestAction; + + public TestCarActivity(CarActivity.Proxy proxy, Context context, Car car) { + super(proxy, context, car); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.d(TAG, "onCreate"); + super.onCreate(savedInstanceState); + Log.d(TAG, "TestAction " + sCreateTestAction); + doRunTest(sCreateTestAction); + } + + + @Override + protected void onStart() { + Log.d(TAG, "onStart"); + super.onStart(); + doRunTest(sStartTestAction); + } + + @Override + protected void onResume() { + Log.d(TAG, "onResume"); + super.onResume(); + doRunTest(sResumeTestAction); + + } + + @Override + protected void onPause() { + Log.d(TAG, "onPause"); + super.onPause(); + doRunTest(sPauseTestAction); + } + + + @Override + protected void onStop() { + Log.d(TAG, "onStop"); + super.onStop(); + doRunTest(sStopTestAction); + } + + @Override + protected void onDestroy() { + Log.d(TAG, "onDestroy"); + super.onDestroy(); + doRunTest(sDestroyTestAction); + } + + private void doRunTest(TestAction<TestCarActivity> test) { + Log.d(TAG, "doRunTest " + test); + if (test != null) { + test.doRun(this); + } + } + + public static void testCleanup() { + sCreateTestAction = null; + sStartTestAction = null; + sResumeTestAction = null; + sPauseTestAction = null; + sStopTestAction = null; + sDestroyTestAction = null; + } +} diff --git a/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestCarProxyActivity.java b/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestCarProxyActivity.java new file mode 100644 index 0000000000..94abeb1ab4 --- /dev/null +++ b/tests/android_support_car_api_test/src/com/android/support/car/apitest/TestCarProxyActivity.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.support.car.apitest; + +import android.support.car.app.CarProxyActivity; + +public class TestCarProxyActivity extends CarProxyActivity { + + public TestCarProxyActivity() { + super(TestCarActivity.class); + } +} |