blob: 5425f2b522fa5b9a54d77ed479288a5bd6587995 [file] [log] [blame]
/*
* Copyright (C) 2018 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.internal.telephony.emergency;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.telephony.Rlog;
import android.telephony.emergency.EmergencyNumber;
import android.util.LocalLog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.util.IndentingPrintWriter;
import com.android.phone.ecc.nano.ProtobufEccData;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Emergency Number Tracker that handles update of emergency number list from RIL and emergency
* number database. This is multi-sim based and each Phone has a EmergencyNumberTracker.
*/
public class EmergencyNumberTracker extends Handler {
private static final String TAG = EmergencyNumberTracker.class.getSimpleName();
/** @hide */
public static boolean DBG = false;
private final CommandsInterface mCi;
private final Phone mPhone;
private List<EmergencyNumber> mEmergencyNumberListFromDatabase = new ArrayList<>();
private List<EmergencyNumber> mEmergencyNumberListFromRadio = new ArrayList<>();
private List<EmergencyNumber> mEmergencyNumberList = new ArrayList<>();
private final LocalLog mEmergencyNumberListDatabaseLocalLog = new LocalLog(20);
private final LocalLog mEmergencyNumberListRadioLocalLog = new LocalLog(20);
private final LocalLog mEmergencyNumberListLocalLog = new LocalLog(20);
/** Event indicating the update for the emergency number list from the radio. */
private static final int EVENT_UNSOL_EMERGENCY_NUMBER_LIST = 1;
// TODO EVENT_UPDATE_NETWORK_COUNTRY_ISO
public EmergencyNumberTracker(Phone phone, CommandsInterface ci) {
mPhone = phone;
mCi = ci;
// TODO cache Emergency Number List Database per country ISO;
// TODO register for Locale Tracker Country ISO Change
mCi.registerForEmergencyNumberList(this, EVENT_UNSOL_EMERGENCY_NUMBER_LIST, null);
}
/**
* Message handler for updating emergency number list from RIL, updating emergency number list
* from database if the country ISO is changed, and notifying the change of emergency number
* list.
*
* @param msg The message
*/
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_UNSOL_EMERGENCY_NUMBER_LIST:
AsyncResult ar = (AsyncResult) msg.obj;
if (ar.result == null) {
loge("EVENT_UNSOL_EMERGENCY_NUMBER_LIST: Result from RIL is null.");
} else if ((ar.result != null) && (ar.exception == null)) {
updateAndNotifyEmergencyNumberList((List<EmergencyNumber>) ar.result);
} else {
loge("EVENT_UNSOL_EMERGENCY_NUMBER_LIST: Exception from RIL : "
+ ar.exception);
}
break;
}
}
private void updateAndNotifyEmergencyNumberList(
List<EmergencyNumber> emergencyNumberListRadio) {
Collections.sort(emergencyNumberListRadio);
logd("updateAndNotifyEmergencyNumberList(): receiving " + emergencyNumberListRadio);
if (!emergencyNumberListRadio.equals(mEmergencyNumberListFromRadio)) {
try {
mEmergencyNumberListFromRadio = emergencyNumberListRadio;
if (!DBG) {
mEmergencyNumberListRadioLocalLog.log("updateRadioEmergencyNumberList:"
+ emergencyNumberListRadio);
}
List<EmergencyNumber> emergencyNumberListMergedWithDatabase =
constructEmergencyNumberListWithDatabase();
mEmergencyNumberList = emergencyNumberListMergedWithDatabase;
if (!DBG) {
mEmergencyNumberListLocalLog.log("updateEmergencyNumberList:"
+ emergencyNumberListMergedWithDatabase);
}
notifyEmergencyNumberList();
} catch (NullPointerException ex) {
loge("updateAndNotifyEmergencyNumberList() Phone already destroyed: " + ex
+ "EmergencyNumberList not notified");
}
}
}
private void notifyEmergencyNumberList() {
List<EmergencyNumber> emergencyNumberListToNotify = getEmergencyNumberList();
mPhone.notifyEmergencyNumberList(emergencyNumberListToNotify);
logd("notifyEmergencyNumberList():" + emergencyNumberListToNotify);
}
private List<EmergencyNumber> constructEmergencyNumberListWithDatabase() {
List<EmergencyNumber> emergencyNumberListRadioAndDatabase = mEmergencyNumberListFromRadio;
// TODO integrate with emergency number database
// TODO sorting
return emergencyNumberListRadioAndDatabase;
}
public List<EmergencyNumber> getEmergencyNumberList() {
return new ArrayList<>(mEmergencyNumberList);
}
@VisibleForTesting
public List<EmergencyNumber> getRadioEmergencyNumberList() {
return new ArrayList<>(mEmergencyNumberListFromRadio);
}
private static void logd(String str) {
Rlog.d(TAG, str);
}
private static void loge(String str) {
Rlog.e(TAG, str);
}
/**
* Dump Emergency Number List info in the tracking
*
* @param fd FileDescriptor
* @param pw PrintWriter
* @param args args
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.println("mEmergencyNumberListDatabaseLocalLog:");
ipw.increaseIndent();
mEmergencyNumberListDatabaseLocalLog.dump(fd, pw, args);
ipw.decreaseIndent();
ipw.println(" - - - - - - - -");
ipw.println("mEmergencyNumberListRadioLocalLog:");
ipw.increaseIndent();
mEmergencyNumberListRadioLocalLog.dump(fd, pw, args);
ipw.decreaseIndent();
ipw.println(" - - - - - - - -");
ipw.println("mEmergencyNumberListLocalLog:");
ipw.increaseIndent();
mEmergencyNumberListLocalLog.dump(fd, pw, args);
ipw.decreaseIndent();
ipw.flush();
}
}