aboutsummaryrefslogtreecommitdiff
path: root/experimental/experimentalcarservice_unit_test/src/com/android/experimentalcar/DriverDistractionExperimentalFeatureServiceTest.java
blob: 59ad9c519adbbd27b33cbe8e0375fd4eefba985f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
 * Copyright (C) 2019 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.experimentalcar;

import static com.google.common.truth.Truth.assertThat;

import android.car.experimental.DriverAwarenessEvent;
import android.car.experimental.DriverAwarenessSupplierConfig;
import android.car.experimental.DriverAwarenessSupplierService;
import android.car.experimental.IDriverAwarenessSupplier;
import android.car.experimental.IDriverAwarenessSupplierCallback;
import android.content.Context;
import android.os.RemoteException;
import android.util.Pair;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.Arrays;

@RunWith(MockitoJUnitRunner.class)
public class DriverDistractionExperimentalFeatureServiceTest {

    private static final long INITIAL_TIME = 1000L;
    private static final long PREFERRED_SUPPLIER_STALENESS = 10L;

    private final IDriverAwarenessSupplier mFallbackSupplier =
            new IDriverAwarenessSupplier.Stub() {
                @Override
                public void onReady() throws RemoteException {
                }

                @Override
                public void setCallback(IDriverAwarenessSupplierCallback callback)
                        throws RemoteException {
                }
            };
    private final DriverAwarenessSupplierConfig mFallbackConfig = new DriverAwarenessSupplierConfig(
            DriverAwarenessSupplierService.NO_STALENESS);

    private final IDriverAwarenessSupplier mPreferredSupplier =
            new IDriverAwarenessSupplier.Stub() {
                @Override
                public void onReady() throws RemoteException {
                }

                @Override
                public void setCallback(IDriverAwarenessSupplierCallback callback)
                        throws RemoteException {
                }
            };
    private final DriverAwarenessSupplierConfig mPreferredSupplierConfig =
            new DriverAwarenessSupplierConfig(PREFERRED_SUPPLIER_STALENESS);

    @Mock
    private Context mContext;

    private DriverDistractionExperimentalFeatureService mService;
    private FakeTimeSource mTimeSource;
    private FakeTimer mTimer;

    @Before
    public void setUp() throws Exception {
        mTimeSource = new FakeTimeSource(INITIAL_TIME);
        mTimer = new FakeTimer();
        mService = new DriverDistractionExperimentalFeatureService(mContext, mTimeSource, mTimer);
    }

    @After
    public void tearDown() throws Exception {
        if (mService != null) {
            mService.release();
        }
    }

    @Test
    public void testHandleDriverAwarenessEvent_updatesCurrentValue_withLatestEvent()
            throws Exception {
        mService.setDriverAwarenessSuppliers(Arrays.asList(
                new Pair<>(mFallbackSupplier, mFallbackConfig)));

        float firstEmittedEvent = 0.7f;
        emitEvent(mFallbackSupplier, INITIAL_TIME + 1, firstEmittedEvent);

        assertThat(getCurrentAwarenessValue()).isEqualTo(firstEmittedEvent);
    }

    @Test
    public void testHandleDriverAwarenessEvent_hasPreferredEvent_ignoresFallbackEvent()
            throws Exception {
        mService.setDriverAwarenessSuppliers(Arrays.asList(
                new Pair<>(mFallbackSupplier, mFallbackConfig),
                new Pair<>(mPreferredSupplier, mPreferredSupplierConfig)));

        // emit an event from the preferred supplier before the fallback supplier
        float preferredValue = 0.6f;
        emitEvent(mPreferredSupplier, INITIAL_TIME + 1, preferredValue);
        float fallbackValue = 0.7f;
        emitEvent(mFallbackSupplier, INITIAL_TIME + 2, fallbackValue);

        // even though the fallback supplier has a more recent timestamp, it is not the current
        // since the event from the preferred supplier is still fresh
        assertThat(getCurrentAwarenessValue()).isEqualTo(preferredValue);
    }

    @Test
    public void testHandleDriverAwarenessEvent_ignoresOldEvents() throws Exception {
        mService.setDriverAwarenessSuppliers(Arrays.asList(
                new Pair<>(mFallbackSupplier, mFallbackConfig)));

        float firstEmittedEvent = 0.7f;
        emitEvent(mFallbackSupplier, INITIAL_TIME + 1, firstEmittedEvent);
        long oldTime = INITIAL_TIME - 100;
        emitEvent(mFallbackSupplier, oldTime, 0.6f);

        // the event with the old timestamp shouldn't overwrite the value with a more recent
        // timestamp
        assertThat(getCurrentAwarenessValue()).isEqualTo(firstEmittedEvent);
    }

    @Test
    public void testPreferredAwarenessEvent_becomesStale_fallsBackToFallbackEvent()
            throws Exception {
        mService.setDriverAwarenessSuppliers(Arrays.asList(
                new Pair<>(mFallbackSupplier, mFallbackConfig),
                new Pair<>(mPreferredSupplier, mPreferredSupplierConfig)));

        // emit an event from the preferred supplier before the fallback supplier
        float preferredValue = 0.6f;
        long preferredEventTime = INITIAL_TIME + 1;
        mTimeSource.setElapsedRealtime(preferredEventTime);
        emitEvent(mPreferredSupplier, preferredEventTime, preferredValue);
        float fallbackValue = 0.7f;
        long fallbackEventTime = INITIAL_TIME + 2;
        mTimeSource.setElapsedRealtime(fallbackEventTime);
        emitEvent(mFallbackSupplier, fallbackEventTime, fallbackValue);

        // the preferred supplier still has a fresh event
        assertThat(getCurrentAwarenessValue()).isEqualTo(preferredValue);

        // go into the future
        mTimeSource.setElapsedRealtime(preferredEventTime + PREFERRED_SUPPLIER_STALENESS + 1);
        mTimer.executePendingTask();

        // the preferred supplier's data has become stale
        assertThat(getCurrentAwarenessValue()).isEqualTo(fallbackValue);
    }

    private float getCurrentAwarenessValue() {
        return mService.getCurrentDriverAwareness().mAwarenessEvent.getAwarenessValue();
    }

    /**
     * Handle an event as if it were emitted from the specified supplier with the specified time and
     * value.
     */
    private void emitEvent(IDriverAwarenessSupplier supplier, long time, float value)
            throws RemoteException {
        long maxStaleness;
        if (supplier == mFallbackSupplier) {
            maxStaleness = DriverAwarenessSupplierService.NO_STALENESS;
        } else {
            maxStaleness = PREFERRED_SUPPLIER_STALENESS;
        }
        mService.handleDriverAwarenessEvent(
                new DriverDistractionExperimentalFeatureService.DriverAwarenessEventWrapper(
                        new DriverAwarenessEvent(time, value),
                        supplier,
                        maxStaleness));
    }
}