• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 
17 package com.android.car.carlauncher;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.app.Activity;
22 import android.app.Instrumentation;
23 import android.car.app.RemoteCarTaskView;
24 import android.car.test.mocks.AbstractExtendedMockitoTestCase;
25 import android.content.Context;
26 import android.content.Intent;
27 
28 import androidx.core.app.ActivityCompat;
29 import androidx.test.ext.junit.rules.ActivityScenarioRule;
30 import androidx.test.ext.junit.runners.AndroidJUnit4;
31 import androidx.test.platform.app.InstrumentationRegistry;
32 
33 import org.junit.After;
34 import org.junit.Before;
35 import org.junit.Rule;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.mockito.Mock;
39 
40 import java.util.concurrent.CountDownLatch;
41 import java.util.concurrent.TimeUnit;
42 
43 @RunWith(AndroidJUnit4.class)
44 public final class CarLauncherViewModelTest extends AbstractExtendedMockitoTestCase {
45     private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
46     private final Context mContext = mInstrumentation.getContext();
47 
48     @Rule
49     public final ActivityScenarioRule<TestActivity> mActivityRule =
50             new ActivityScenarioRule<>(TestActivity.class);
51 
52     @Mock
53     private Intent mIntent;
54 
55     private RemoteCarTaskView mRemoteCarTaskView;
56     private TestActivity mActivity;
57 
58 
59     @Before
setUp()60     public void setUp() {
61         mActivityRule.getScenario().onActivity(activity -> mActivity = activity);
62     }
63 
64     @After
tearDown()65     public void tearDown() throws InterruptedException {
66         mActivityRule.getScenario().close();
67         mActivity.finishCompletely();
68         mRemoteCarTaskView = null;
69     }
70 
71     @Test
testOnConfigChange_sameRemoteCarTaskView()72     public void testOnConfigChange_sameRemoteCarTaskView() {
73         // Arrange
74         createCarLauncherViewModel();
75         RemoteCarTaskView oldRemoteCarTaskView = mRemoteCarTaskView;
76 
77         // Act
78         triggerActivityRecreation();
79 
80         // Assert
81         assertThat(oldRemoteCarTaskView).isSameInstanceAs(mRemoteCarTaskView);
82     }
83 
84     @Test
testViewModelOnCleared_clearsRemoteCarTaskView()85     public void testViewModelOnCleared_clearsRemoteCarTaskView() {
86         // Arrange
87         CarLauncherViewModel carLauncherViewModel = createCarLauncherViewModel();
88 
89         // Act
90         runOnMain(carLauncherViewModel::onCleared);
91         mInstrumentation.waitForIdleSync();
92 
93         // Assert
94         assertThat(mRemoteCarTaskView).isNull();
95     }
96 
createCarLauncherViewModel()97     private CarLauncherViewModel createCarLauncherViewModel() {
98         CarLauncherViewModel carLauncherViewModel = new CarLauncherViewModel(mActivity, mIntent);
99         runOnMain(() -> carLauncherViewModel.getRemoteCarTaskView().observeForever(
100                 remoteCarTaskView -> mRemoteCarTaskView = remoteCarTaskView));
101         mInstrumentation.waitForIdleSync();
102         return carLauncherViewModel;
103     }
104 
triggerActivityRecreation()105     private void triggerActivityRecreation() {
106         // Causes activity recreation with a new instance resulting in the same flow as
107         // activity being recreated due to a configuration change.
108         runOnMain(() -> ActivityCompat.recreate(mActivity));
109         mInstrumentation.waitForIdleSync();
110     }
111 
runOnMain(Runnable runnable)112     private void runOnMain(Runnable runnable) {
113         mContext.getMainExecutor().execute(runnable);
114     }
115 
116 
117     public static class TestActivity extends Activity {
118         private static final int FINISH_TIMEOUT_MS = 1000;
119         private final CountDownLatch mDestroyed = new CountDownLatch(1);
120 
121         @Override
onDestroy()122         protected void onDestroy() {
123             super.onDestroy();
124             mDestroyed.countDown();
125         }
126 
finishCompletely()127         void finishCompletely() throws InterruptedException {
128             finish();
129             mDestroyed.await(FINISH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
130         }
131     }
132 }
133