blob: 12c49afab978d9ab1aca3e7756146735801d5afa [file] [log] [blame]
/*
* Copyright (C) 2022 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.ons;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import android.content.Context;
import android.content.SharedPreferences;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import com.android.ons.ONSProfileActivator.Result;
import com.android.ons.ONSProfileDownloader.DownloadRetryResultCode;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@RunWith(JUnit4.class)
public class ONSStatsTest {
private static final String ONS_ATOM_LOG_FILE = "ons_atom_log_info";
private static final String KEY_DETAILED_ERROR_CODE = "_detailed_error_code";
@Spy private Context mContext;
@Mock private SubscriptionManager mSubscriptionManager;
private SharedPreferences mSharedPreferences;
@Mock private SubscriptionInfo mSubInfoId1;
@Mock private SubscriptionInfo mSubInfoId2;
private ONSStats mONSStats;
private class FakeSharedPreferences implements SharedPreferences {
HashMap<String, Object> mMap = new HashMap<>();
@Override
public Map<String, ?> getAll() {
return mMap;
}
@Override
public String getString(String key, String defValue) {
return (String) mMap.getOrDefault(key, defValue);
}
@Override
public Set<String> getStringSet(String key, Set<String> defValues) {
if (mMap.containsKey(key)) {
return (Set<String>) mMap.get(key);
}
return defValues;
}
@Override
public int getInt(String key, int defValue) {
return (int) mMap.getOrDefault(key, defValue);
}
@Override
public long getLong(String key, long defValue) {
return 0; // not used
}
@Override
public float getFloat(String key, float defValue) {
return (float) mMap.getOrDefault(key, defValue);
}
@Override
public boolean getBoolean(String key, boolean defValue) {
return (boolean) mMap.getOrDefault(key, defValue);
}
@Override
public boolean contains(String key) {
return mMap.containsKey(key);
}
@Override
public Editor edit() {
TestEditor editor = new TestEditor();
editor.map = mMap;
return editor;
}
@Override
public void registerOnSharedPreferenceChangeListener(
OnSharedPreferenceChangeListener listener) {}
@Override
public void unregisterOnSharedPreferenceChangeListener(
OnSharedPreferenceChangeListener listener) {}
private class TestEditor implements SharedPreferences.Editor {
HashMap<String, Object> map = new HashMap<>();
@Override
public SharedPreferences.Editor putString(String key, String value) {
map.put(key, value);
return this;
}
@Override
public SharedPreferences.Editor putStringSet(String key, Set<String> values) {
map.put(key, values);
return this;
}
@Override
public SharedPreferences.Editor putInt(String key, int value) {
map.put(key, value);
return this;
}
@Override
public SharedPreferences.Editor putLong(String key, long value) {
map.put(key, value);
return this;
}
@Override
public SharedPreferences.Editor putFloat(String key, float value) {
map.put(key, value);
return this;
}
@Override
public SharedPreferences.Editor putBoolean(String key, boolean value) {
map.put(key, value);
return this;
}
@Override
public SharedPreferences.Editor remove(String key) {
map.remove(key);
return this;
}
@Override
public SharedPreferences.Editor clear() {
map.clear();
return this;
}
@Override
public boolean commit() {
mMap = map;
return true;
}
@Override
public void apply() {
mMap = map;
}
}
;
}
;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mSharedPreferences = new FakeSharedPreferences();
doReturn(mSharedPreferences)
.when(mContext)
.getSharedPreferences(eq(ONS_ATOM_LOG_FILE), eq(Context.MODE_PRIVATE));
doReturn(123).when(mSubInfoId1).getCarrierId();
doReturn(456).when(mSubInfoId2).getCarrierId();
doReturn(mSubInfoId1).when(mSubscriptionManager).getActiveSubscriptionInfo(1);
doReturn(mSubInfoId2).when(mSubscriptionManager).getActiveSubscriptionInfo(2);
mONSStats = new ONSStats(mContext, mSubscriptionManager);
}
@After
public void tearDown() {
mSharedPreferences.edit().clear().apply();
}
@Test
public void testLogEvent() {
ONSStatsInfo info =
new ONSStatsInfo()
.setPrimarySimSubId(1)
.setProvisioningResult(Result.ERR_CANNOT_SWITCH_TO_DUAL_SIM_MODE);
assertTrue(mONSStats.logEvent(info));
}
@Test
public void testIgnoredLogEvents() {
// ignored error codes should not log.
ONSStatsInfo info = new ONSStatsInfo().setProvisioningResult(Result.DOWNLOAD_REQUESTED);
assertFalse(mONSStats.logEvent(info));
info = new ONSStatsInfo().setProvisioningResult(Result.ERR_NO_SIM_INSERTED);
assertFalse(mONSStats.logEvent(info));
info = new ONSStatsInfo().setProvisioningResult(Result.ERR_DUPLICATE_DOWNLOAD_REQUEST);
assertFalse(mONSStats.logEvent(info));
info = new ONSStatsInfo().setProvisioningResult(Result.ERR_SWITCHING_TO_DUAL_SIM_MODE);
assertFalse(mONSStats.logEvent(info));
}
@Test
public void testRepeatedLogEvents() {
ONSStatsInfo info;
info =
new ONSStatsInfo()
.setDownloadResult(DownloadRetryResultCode.ERR_MEMORY_FULL)
.setDetailedErrCode(10011);
assertTrue(mONSStats.logEvent(info));
// same result should not log consecutively
assertFalse(mONSStats.logEvent(info));
assertFalse(mONSStats.logEvent(info));
}
@Test
public void testRepeatedAllowedLogEvents() {
ONSStatsInfo info;
info = new ONSStatsInfo().setProvisioningResult(Result.ERR_DOWNLOADED_ESIM_NOT_FOUND);
assertTrue(mONSStats.logEvent(info));
// ERR_DOWNLOADED_ESIM_NOT_FOUND is allowed to log consecutively
assertTrue(mONSStats.logEvent(info));
assertTrue(mONSStats.logEvent(info));
info =
new ONSStatsInfo()
.setDownloadResult(DownloadRetryResultCode.ERR_INSTALL_ESIM_PROFILE_FAILED);
assertTrue(mONSStats.logEvent(info));
// ERR_INSTALL_ESIM_PROFILE_FAILED is allowed to log consecutively
assertTrue(mONSStats.logEvent(info));
assertTrue(mONSStats.logEvent(info));
}
@Test
public void testRepeatedSuccessLogEvents() {
ONSStatsInfo info;
info = new ONSStatsInfo().setProvisioningResult(Result.SUCCESS).setRetryCount(2);
// should log every time if eSIM is newly downloaded.
assertTrue(mONSStats.logEvent(info));
assertTrue(mONSStats.logEvent(info));
info = new ONSStatsInfo().setProvisioningResult(Result.SUCCESS);
// should log even if eSIM is already downloaded and event triggered just to group it.
assertTrue(mONSStats.logEvent(info));
assertTrue(mONSStats.logEvent(info));
}
@Test
public void testRepeatedErrorWithInfoChangeLogEvents() {
ONSStatsInfo info =
new ONSStatsInfo()
.setPrimarySimSubId(1)
.setProvisioningResult(Result.ERR_AUTO_PROVISIONING_DISABLED);
assertTrue(mONSStats.logEvent(info));
// Same error should log if the info is changed.
info.setPrimarySimSubId(2);
assertTrue(mONSStats.logEvent(info));
// no change in info
assertFalse(mONSStats.logEvent(info));
}
@Test
public void testDetailedErrorCodeLogEvents() {
ONSStatsInfo info;
info = new ONSStatsInfo().setProvisioningResult(Result.ERR_WAITING_FOR_INTERNET_CONNECTION);
assertTrue(mONSStats.logEvent(info));
// For provisioning errors; Result enum ordinal is set as detailed error code.
assertEquals(
Result.ERR_WAITING_FOR_INTERNET_CONNECTION.ordinal(),
mSharedPreferences.getInt(KEY_DETAILED_ERROR_CODE, -1));
assertEquals(
Result.ERR_WAITING_FOR_INTERNET_CONNECTION.ordinal(), info.getDetailedErrCode());
// For Download errors; detailed error code is updated from EuiccManager.
info =
new ONSStatsInfo()
.setDownloadResult(DownloadRetryResultCode.ERR_MEMORY_FULL)
.setDetailedErrCode(10223);
assertTrue(mONSStats.logEvent(info));
assertEquals(10223, mSharedPreferences.getInt(KEY_DETAILED_ERROR_CODE, -1));
assertEquals(10223, info.getDetailedErrCode());
}
}