blob: 6e417c655ab6bc36b943ebd0e7682cfccc135bda [file]
/*
* 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.cellbroadcastservice;
import static android.content.Context.MODE_PRIVATE;
import static android.telephony.SmsCbMessage.MESSAGE_FORMAT_3GPP;
import static com.android.cellbroadcastservice.CellBroadcastMetrics.FILTER_CDMA;
import static com.android.cellbroadcastservice.CellBroadcastMetrics.FILTER_GSM;
import android.content.Context;
import android.content.SharedPreferences;
import android.telephony.SmsCbMessage;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* CellBroadcastServiceMetrics
* Logging featureUpdated, when alert message is received or channel range is updated
*/
public class CellBroadcastServiceMetrics {
private static final String TAG = "CellBroadcastServiceMetrics";
private static final boolean VDBG = false;
// Key to access the shared preference of cell broadcast service feature for metric.
private static final String CBS_METRIC_PREF = "CellBroadcastServiceMetricSharedPref";
private static CellBroadcastServiceMetrics sCbsMetrics;
private FeatureMetrics mFeatureMetrics;
private FeatureMetrics mFeatureMetricsSharedPreferences;
/**
* Get instance of CellBroadcastServiceMetrics.
*/
public static CellBroadcastServiceMetrics getInstance() {
if (sCbsMetrics == null) {
sCbsMetrics = new CellBroadcastServiceMetrics();
}
return sCbsMetrics;
}
/**
* CellBroadcastReceiverMetrics.FeatureMetrics
* Logging featureUpdated as needed when alert message is received
*/
public static class FeatureMetrics implements Cloneable {
public static final String ADDITIONAL_CBR_PACKAGES = "additional_cbr_packages";
public static final String AREA_INFO_PACKAGES = "area_info_packages";
public static final String RESET_AREA_INFO = "reset_area_info";
public static final String DEFVAL_AREAPKGS = "com.android.settings";
private boolean mIsOverrideCbrPkgs;
private boolean mIsOverrideAreaInfoPkgs;
private boolean mResetAreaInfo;
private Context mContext;
public FeatureMetrics(Context context) {
mContext = context;
SharedPreferences sp = mContext.getSharedPreferences(CBS_METRIC_PREF, MODE_PRIVATE);
mIsOverrideCbrPkgs = sp.getBoolean(ADDITIONAL_CBR_PACKAGES, false);
mIsOverrideAreaInfoPkgs = sp.getBoolean(AREA_INFO_PACKAGES, false);
mResetAreaInfo = sp.getBoolean(RESET_AREA_INFO, false);
}
@Override
public int hashCode() {
return Objects.hash(mIsOverrideCbrPkgs, mIsOverrideAreaInfoPkgs, mResetAreaInfo);
}
@Override
public boolean equals(Object object) {
if (object instanceof FeatureMetrics) {
FeatureMetrics features = (FeatureMetrics) object;
return (this.mIsOverrideCbrPkgs == features.mIsOverrideCbrPkgs
&& this.mIsOverrideAreaInfoPkgs == features.mIsOverrideAreaInfoPkgs
&& this.mResetAreaInfo == features.mResetAreaInfo);
}
return false;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* Get current status whether cell broadcast receiver packages are overridden
*/
@VisibleForTesting
public boolean isOverrideCbrPkgs() {
return mIsOverrideCbrPkgs;
}
/**
* Get current status whether area information packages are overridden
*/
@VisibleForTesting
public boolean isOverrideAreaInfoPkgs() {
return mIsOverrideAreaInfoPkgs;
}
/**
* Get current status whether reset area information while in out of service
*/
@VisibleForTesting
public boolean isResetAreaInfo() {
return mResetAreaInfo;
}
/**
* Set whether additional cbr packages are overridden
*
* @param override : whether additional cbr packages are overridden
*/
@VisibleForTesting
public void onChangedAdditionalCbrPackage(boolean override) {
mIsOverrideCbrPkgs = override;
}
/**
* Set whether area info packages are overridden
*
* @param current : list of area info overriding packages
*/
@VisibleForTesting
public void onChangedAreaInfoPackage(List<String> current) {
mIsOverrideAreaInfoPkgs = !Arrays.asList(new String[]{DEFVAL_AREAPKGS}).equals(current);
}
/**
* Set whether area info reset on our of service
*
* @param current : whether reset area info is supported
*/
@VisibleForTesting
public void onChangedResetAreaInfo(boolean current) {
mResetAreaInfo = current;
}
/**
* Calling check-in method for CB_SERVICE_FEATURE
*/
@VisibleForTesting
public void logFeatureChanged() {
CellBroadcastModuleStatsLog.write(
CellBroadcastModuleStatsLog.CB_SERVICE_FEATURE_CHANGED,
mIsOverrideCbrPkgs,
mIsOverrideAreaInfoPkgs,
mResetAreaInfo);
if (VDBG) Log.d(TAG, this.toString());
}
/**
* Update preferences for service feature metrics
*/
@VisibleForTesting
public void updateSharedPreferences() {
SharedPreferences sp = mContext.getSharedPreferences(CBS_METRIC_PREF, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(ADDITIONAL_CBR_PACKAGES, mIsOverrideCbrPkgs);
editor.putBoolean(AREA_INFO_PACKAGES, mIsOverrideAreaInfoPkgs);
editor.putBoolean(RESET_AREA_INFO, mResetAreaInfo);
editor.apply();
}
@Override
public String toString() {
return "CellBroadcast_Service_Feature : "
+ "mIsOverrideCbrPkgs = " + mIsOverrideCbrPkgs + " | "
+ "mIsOverrideAreaInfoPkgs = " + mIsOverrideAreaInfoPkgs + " | "
+ "mResetAreaInfo = " + mResetAreaInfo;
}
}
/**
* get cached feature metrics for shared preferences
*/
@VisibleForTesting
public FeatureMetrics getFeatureMetricsSharedPreferences() {
return mFeatureMetricsSharedPreferences;
}
/**
* set cached feature metrics for current status
*/
@VisibleForTesting
public void setFeatureMetrics(FeatureMetrics featureMetrics) {
mFeatureMetrics = featureMetrics;
}
/**
* Set featureMetricsSharedPreferences
*
* @param featureMetricsSharedPreferences : Cbs features information
*/
@VisibleForTesting
public void setFeatureMetricsSharedPreferences(FeatureMetrics featureMetricsSharedPreferences) {
mFeatureMetricsSharedPreferences = featureMetricsSharedPreferences;
}
/**
* Get featureMetrics if null then create
*/
@VisibleForTesting
public FeatureMetrics getFeatureMetrics(Context context) {
if (mFeatureMetrics == null) {
mFeatureMetrics = new FeatureMetrics(context);
mFeatureMetricsSharedPreferences = new FeatureMetrics(context);
}
return mFeatureMetrics;
}
/**
* When feature changed and net alert message received then check-in logging
*
* @param context : Context
*/
@VisibleForTesting
public void logFeatureChangedAsNeeded(Context context) {
if (!getFeatureMetrics(context).equals(mFeatureMetricsSharedPreferences)) {
mFeatureMetrics.logFeatureChanged();
mFeatureMetrics.updateSharedPreferences();
try {
mFeatureMetricsSharedPreferences = (FeatureMetrics) mFeatureMetrics.clone();
} catch (CloneNotSupportedException e) {
Log.e(TAG, "exception during making clone for service feature metrics: " + e);
}
}
}
/**
* Create a new logMessageReported
*
* @param type : radio type
* @param source : layer of reported message
* @param serialNo : set 0 as deprecated
* @param msgId : service_category of message
*/
public void logMessageReported(Context context, int type, int source, int serialNo, int msgId) {
if (VDBG) {
Log.d(TAG, "logMessageReported : " + type + " " + source + " " + 0 + " " + msgId);
}
CellBroadcastModuleStatsLog.write(CellBroadcastModuleStatsLog.CB_MESSAGE_REPORTED, type,
source, 0, msgId);
}
/**
* Create a new logMessageError
*
* @param type : error type
* @param exceptionMessage : error message
*/
public void logMessageError(int type, String exceptionMessage) {
if (VDBG) {
Log.d(TAG, "logMessageError : " + type + " " + exceptionMessage);
}
CellBroadcastModuleStatsLog.write(CellBroadcastModuleStatsLog.CB_MESSAGE_ERROR,
type, exceptionMessage);
}
/**
* Create a new logMessageFiltered
*
* @param filterType : reason type of filtered
* @param msg : sms cell broadcast message information
*/
public void logMessageFiltered(int filterType, SmsCbMessage msg) {
int ratType = msg.getMessageFormat() == MESSAGE_FORMAT_3GPP ? FILTER_GSM : FILTER_CDMA;
if (VDBG) {
Log.d(TAG, "logMessageFiltered : " + ratType + " " + filterType + " " + 0 + " "
+ msg.getServiceCategory());
}
CellBroadcastModuleStatsLog.write(CellBroadcastModuleStatsLog.CB_MESSAGE_FILTERED,
ratType, filterType, 0, msg.getServiceCategory());
}
/**
* Create a new logModuleError
*
* @param source : where this log happened
* @param errorType : type of error
*/
public void logModuleError(int source, int errorType) {
if (VDBG) {
Log.d(TAG, "logModuleError : " + source + " " + errorType);
}
CellBroadcastModuleStatsLog.write(CellBroadcastModuleStatsLog.CB_MODULE_ERROR_REPORTED,
source, errorType);
}
}