blob: 21ce6075a3f2ef61b06803352fff664896a2707d [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 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 java.util.List;
public class ONSStats {
private static final String ONS_ATOM_LOG_FILE = "ons_atom_log_info";
private static final String KEY_PROVISIONING_RESULT = "_provisioning_result";
private static final String KEY_DOWNLOAD_RESULT = "_download_result";
private static final String KEY_RETRY_COUNT = "_retry_count";
private static final String KEY_DETAILED_ERROR_CODE = "_detailed_error_code";
private static final String KEY_OPP_CARRIER_ID = "_opportunistic_carrier_id";
private static final String KEY_PRIMARY_CARRIER_ID = "_primary_sim_carrier_id";
private final Context mContext;
private final SubscriptionManager mSubscriptionManager;
/** Constructor to create instance for ONSStats. */
public ONSStats(Context context, SubscriptionManager subscriptionManager) {
mContext = context;
mSubscriptionManager = subscriptionManager;
}
/**
* It logs the ONS atom with the info passed as ONSStatsInfo. If the information is already
* logged, it will be skipped.
*
* @param info information to be logged.
* @return returns true if information is logged, otherwise false.
*/
public boolean logEvent(ONSStatsInfo info) {
// check if the info needs to be ignored.
if (ignoreEvent(info)) {
return false;
}
int statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_UNKNOWN;
if (info.isProvisioningResultUpdated()) {
switch (info.getProvisioningResult()) {
case SUCCESS:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_SUCCESS;
break;
case ERR_CANNOT_SWITCH_TO_DUAL_SIM_MODE:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_SWITCH_TO_MULTISIM_FAILED;
break;
case ERR_CARRIER_DOESNT_SUPPORT_CBRS:
case ERR_AUTO_PROVISIONING_DISABLED:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_AUTO_PROVISIONING_DISABLED;
break;
case ERR_ESIM_NOT_SUPPORTED:
case ERR_MULTISIM_NOT_SUPPORTED:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_DEVICE_NOT_CAPABLE;
break;
case ERR_SINGLE_ACTIVE_OPPORTUNISTIC_SIM:
case ERR_DUAL_ACTIVE_SUBSCRIPTIONS:
case ERR_PSIM_NOT_FOUND:
case ERR_DOWNLOADED_ESIM_NOT_FOUND:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_ESIM_PROVISIONING_FAILED;
break;
case ERR_WAITING_FOR_INTERNET_CONNECTION:
case ERR_WAITING_FOR_WIFI_CONNECTION:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_INTERNET_NOT_AVAILABLE;
break;
case ERR_INVALID_CARRIER_CONFIG:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_UNRESOLVABLE_ERROR;
break;
default:
break;
}
} else {
switch (info.getDownloadResult()) {
case ERR_UNRESOLVABLE:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_UNRESOLVABLE_ERROR;
break;
case ERR_MEMORY_FULL:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_MEMORY_FULL;
break;
case ERR_INSTALL_ESIM_PROFILE_FAILED:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_INSTALL_ESIM_PROFILE_FAILED;
break;
case ERR_RETRY_DOWNLOAD:
statsCode = OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE__ERROR_CODE__RESULT_CONNECTION_ERROR;
break;
default:
break;
}
}
OnsStatsLog.write(
OnsStatsLog.ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE,
getSimCarrierId(info.getPrimarySimSubId()),
info.getOppSimCarrierId(),
info.isWifiConnected(),
statsCode,
info.getRetryCount(),
info.getDetailedErrCode());
updateSharedPreferences(info);
return true;
}
private void updateSharedPreferences(ONSStatsInfo info) {
SharedPreferences sharedPref =
mContext.getSharedPreferences(ONS_ATOM_LOG_FILE, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
if (info.isProvisioningResultUpdated()) {
editor.putInt(KEY_PROVISIONING_RESULT, info.getProvisioningResult().ordinal());
editor.remove(KEY_DOWNLOAD_RESULT);
} else {
editor.putInt(KEY_DOWNLOAD_RESULT, info.getDownloadResult().ordinal());
editor.remove(KEY_PROVISIONING_RESULT);
}
editor.putInt(KEY_PRIMARY_CARRIER_ID, getSimCarrierId(info.getPrimarySimSubId()))
.putInt(KEY_RETRY_COUNT, info.getRetryCount())
.putInt(KEY_OPP_CARRIER_ID, info.getOppSimCarrierId())
.putInt(KEY_DETAILED_ERROR_CODE, info.getDetailedErrCode())
.apply();
}
private boolean ignoreEvent(ONSStatsInfo info) {
Result result = info.getProvisioningResult();
if (info.isProvisioningResultUpdated()) {
info.setDetailedErrCode(result.ordinal());
// Codes are ignored since they are intermediate state of CBRS provisioning check.
if ((result == Result.DOWNLOAD_REQUESTED)
|| result == Result.ERR_NO_SIM_INSERTED
|| result == Result.ERR_DUPLICATE_DOWNLOAD_REQUEST
|| result == Result.ERR_SWITCHING_TO_DUAL_SIM_MODE) {
return true;
}
// add subscription id for carrier if it doesn't support CBRS.
if (result == Result.ERR_CARRIER_DOESNT_SUPPORT_CBRS) {
List<SubscriptionInfo> subInfos =
mSubscriptionManager.getAvailableSubscriptionInfoList();
info.setPrimarySimSubId(
(subInfos != null && !subInfos.isEmpty())
? subInfos.get(0).getSubscriptionId()
: -1);
}
}
SharedPreferences sharedPref =
mContext.getSharedPreferences(ONS_ATOM_LOG_FILE, Context.MODE_PRIVATE);
boolean errorCodeUpdated =
(info.isProvisioningResultUpdated()
? sharedPref.getInt(KEY_PROVISIONING_RESULT, -1) != result.ordinal()
: sharedPref.getInt(KEY_DOWNLOAD_RESULT, -1)
!= info.getDownloadResult().ordinal());
boolean carrierIdUpdated =
sharedPref.getInt(KEY_PRIMARY_CARRIER_ID, -1)
!= getSimCarrierId(info.getPrimarySimSubId());
boolean retryCountUpdated = sharedPref.getInt(KEY_RETRY_COUNT, -1) != info.getRetryCount();
boolean oppCarrierIdChanged =
sharedPref.getInt(KEY_OPP_CARRIER_ID, -1) != info.getOppSimCarrierId();
boolean detailedErrorChanged =
sharedPref.getInt(KEY_DETAILED_ERROR_CODE, -1) != info.getDetailedErrCode();
if (!(errorCodeUpdated
|| carrierIdUpdated
|| retryCountUpdated
|| oppCarrierIdChanged
|| detailedErrorChanged)) {
// Result codes are meant to log on every occurrence. These should not be ignored.
if (result == Result.SUCCESS
|| result == Result.ERR_DOWNLOADED_ESIM_NOT_FOUND
|| info.getDownloadResult()
== DownloadRetryResultCode.ERR_INSTALL_ESIM_PROFILE_FAILED) {
return false;
}
return true;
}
return false;
}
private int getSimCarrierId(int subId) {
if (subId == -1) return -1;
SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(subId);
return (subInfo != null) ? subInfo.getCarrierId() : -1;
}
}