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.server.ondevicepersonalization;
18 
19 import static com.android.server.ondevicepersonalization.OnDevicePersonalizationSystemService.PERSONALIZATION_STATUS_KEY;
20 
21 import static org.mockito.Mockito.doNothing;
22 import static org.mockito.Mockito.doThrow;
23 import static org.mockito.Mockito.spy;
24 import static org.mockito.Mockito.verify;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertNull;
28 import static org.junit.Assert.assertThrows;
29 import static org.junit.Assert.assertTrue;
30 
31 import android.adservices.ondevicepersonalization.Constants;
32 import android.content.Context;
33 import android.ondevicepersonalization.IOnDevicePersonalizationSystemServiceCallback;
34 import android.os.Bundle;
35 
36 import androidx.test.core.app.ApplicationProvider;
37 
38 import com.android.modules.utils.build.SdkLevel;
39 import com.android.modules.utils.testing.ExtendedMockitoRule;
40 import com.android.ondevicepersonalization.testing.utils.DeviceSupportHelper;
41 
42 import org.junit.After;
43 import org.junit.Assume;
44 import org.junit.Before;
45 import org.junit.Rule;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.junit.runners.JUnit4;
49 import org.mockito.quality.Strictness;
50 
51 import java.util.concurrent.CountDownLatch;
52 
53 @RunWith(JUnit4.class)
54 public class OdpSystemServiceImplTest {
55     private final Context mContext = ApplicationProvider.getApplicationContext();
56     private static final String TEST_CONFIG_FILE_IDENTIFIER = "TEST_CONFIG";
57     private static final String BAD_TEST_KEY = "non-exist-key";
58     private final BooleanFileDataStore mTestDataStore =
59                     new BooleanFileDataStore(mContext.getFilesDir().getAbsolutePath(),
60                                     TEST_CONFIG_FILE_IDENTIFIER);
61     private boolean mOnResultCalled;
62     private boolean mOnErrorCalled;
63     private Bundle mResult;
64     private int mErrorCode;
65     private CountDownLatch mLatch;
66     private OnDevicePersonalizationSystemService mService;
67     private IOnDevicePersonalizationSystemServiceCallback mCallback;
68 
69     @Rule
70     public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
71             .setStrictness(Strictness.LENIENT)
72             .build();
73 
74     @Before
setUp()75     public void setUp() throws Exception {
76         Assume.assumeTrue(DeviceSupportHelper.isDeviceSupported());
77         Assume.assumeTrue(SdkLevel.isAtLeastU());
78         mService = spy(new OnDevicePersonalizationSystemService(mContext, mTestDataStore));
79         doNothing().when(mService).enforceCallingPermission();
80         mOnResultCalled = false;
81         mOnErrorCalled = false;
82         mResult = null;
83         mErrorCode = 0;
84         mLatch = new CountDownLatch(1);
85         mCallback = new IOnDevicePersonalizationSystemServiceCallback.Stub() {
86             @Override
87             public void onResult(Bundle bundle) {
88                 mOnResultCalled = true;
89                 mResult = bundle;
90                 mLatch.countDown();
91             }
92 
93             @Override
94             public void onError(int errorCode) {
95                 mOnErrorCalled = true;
96                 mErrorCode = errorCode;
97                 mLatch.countDown();
98             }
99         };
100         assertNotNull(mCallback);
101     }
102 
103     @Test
testSystemServerServiceOnRequest()104     public void testSystemServerServiceOnRequest() throws Exception {
105         mService.onRequest(new Bundle(), mCallback);
106         mLatch.await();
107         assertTrue(mOnResultCalled);
108         assertNull(mResult);
109         verify(mService).enforceCallingPermission();
110     }
111 
112     @Test
testSystemServerServiceSetPersonalizationStatus()113     public void testSystemServerServiceSetPersonalizationStatus() throws Exception {
114         mService.setPersonalizationStatus(true, mCallback);
115         mLatch.await();
116         assertTrue(mOnResultCalled);
117         assertNotNull(mResult);
118         boolean inputBool = mResult.getBoolean(PERSONALIZATION_STATUS_KEY);
119         assertTrue(inputBool);
120         verify(mService).enforceCallingPermission();
121     }
122 
123     @Test
testSystemServerServiceReadPersonalizationStatusSuccess()124     public void testSystemServerServiceReadPersonalizationStatusSuccess() throws Exception {
125         mTestDataStore.put(PERSONALIZATION_STATUS_KEY, true);
126         mService.readPersonalizationStatus(mCallback);
127         assertTrue(mOnResultCalled);
128         assertNotNull(mResult);
129         boolean inputBool = mResult.getBoolean(PERSONALIZATION_STATUS_KEY);
130         assertTrue(inputBool);
131         verify(mService).enforceCallingPermission();
132     }
133 
134     @Test
testSystemServerServiceReadPersonalizationStatusNotFound()135     public void testSystemServerServiceReadPersonalizationStatusNotFound() throws Exception {
136         mTestDataStore.put(BAD_TEST_KEY, true);
137         mService.readPersonalizationStatus(mCallback);
138         assertTrue(mOnErrorCalled);
139         assertNull(mResult);
140         assertEquals(mErrorCode, Constants.STATUS_KEY_NOT_FOUND);
141         verify(mService).enforceCallingPermission();
142     }
143 
144     @Test
testSystemServerServiceSetPersonalizationStatusPermissionDenied()145     public void testSystemServerServiceSetPersonalizationStatusPermissionDenied()
146             throws Exception {
147         doThrow(SecurityException.class).when(mService).enforceCallingPermission();
148         assertThrows(
149                 SecurityException.class,
150                 () -> mService.setPersonalizationStatus(true, mCallback));
151     }
152 
153     @After
cleanUp()154     public void cleanUp() {
155         mTestDataStore.tearDownForTesting();
156     }
157 }
158