[Smart forwarding] Enable/Disable Smart Forwarding flow
Bug: 170178144 Test: By manual 1. Test turn on/turn off flow 2. Test enter phone number flow Change-Id: Icee8c85e71f72f467b2dc11b9b55c674f22d8179
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.settings.sim.smartForwarding;
|
||||||
|
|
||||||
|
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.TAG;
|
||||||
|
|
||||||
|
import android.telephony.CallForwardingInfo;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class DisableSmartForwardingTask implements Runnable {
|
||||||
|
private final TelephonyManager tm;
|
||||||
|
private final boolean[] callWaitingStatus;
|
||||||
|
private final CallForwardingInfo[] callForwardingInfo;
|
||||||
|
|
||||||
|
public DisableSmartForwardingTask(TelephonyManager tm,
|
||||||
|
boolean[] callWaitingStatus, CallForwardingInfo[] callForwardingInfo) {
|
||||||
|
this.tm = tm;
|
||||||
|
this.callWaitingStatus = callWaitingStatus;
|
||||||
|
this.callForwardingInfo = callForwardingInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (int i = 0; i < tm.getActiveModemCount(); i++) {
|
||||||
|
if (callWaitingStatus != null) {
|
||||||
|
Log.d(TAG, "Restore call waiting to " + callWaitingStatus[i]);
|
||||||
|
tm.setCallWaitingEnabled(callWaitingStatus[i], null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callForwardingInfo != null
|
||||||
|
&& callForwardingInfo[i] != null
|
||||||
|
&& callForwardingInfo[i].getTimeoutSeconds() > 0) {
|
||||||
|
Log.d(TAG, "Restore call waiting to " + callForwardingInfo);
|
||||||
|
tm.setCallForwarding(callForwardingInfo[i], null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,456 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.settings.sim.smartForwarding;
|
||||||
|
|
||||||
|
import static android.telephony.CallForwardingInfo.REASON_NOT_REACHABLE;
|
||||||
|
|
||||||
|
import static com.android.settings.sim.smartForwarding.SmartForwardingUtils.TAG;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.telephony.CallForwardingInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class EnableSmartForwardingTask
|
||||||
|
implements Callable<EnableSmartForwardingTask.FeatureResult> {
|
||||||
|
|
||||||
|
private static final int TIMEOUT = 20;
|
||||||
|
|
||||||
|
private final SubscriptionManager sm;
|
||||||
|
private final TelephonyManager tm;
|
||||||
|
private final String[] mCallForwardingNumber;
|
||||||
|
|
||||||
|
FeatureResult mResult = new FeatureResult(false, null);
|
||||||
|
SettableFuture<FeatureResult> client = SettableFuture.create();
|
||||||
|
|
||||||
|
public EnableSmartForwardingTask(Context context, String[] callForwardingNumber) {
|
||||||
|
tm = context.getSystemService(TelephonyManager.class);
|
||||||
|
sm = context.getSystemService(SubscriptionManager.class);
|
||||||
|
mCallForwardingNumber = callForwardingNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureResult call() throws TimeoutException, InterruptedException, ExecutionException {
|
||||||
|
FlowController controller = new FlowController();
|
||||||
|
if (controller.init(mCallForwardingNumber)) {
|
||||||
|
controller.startProcess();
|
||||||
|
} else {
|
||||||
|
client.set(mResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.get(TIMEOUT, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FlowController {
|
||||||
|
private SlotUTData[] mSlotUTData;
|
||||||
|
private final ArrayList<Command> mSteps = new ArrayList<>();
|
||||||
|
|
||||||
|
public boolean init(String[] phoneNum) {
|
||||||
|
if (!initObject(phoneNum)) return false;
|
||||||
|
initSteps();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean initObject(String[] phoneNum) {
|
||||||
|
Executor executor = Executors.newSingleThreadExecutor();
|
||||||
|
if (tm == null || sm == null) {
|
||||||
|
Log.e(TAG, "TelephonyManager or SubscriptionManager is null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phoneNum.length != tm.getActiveModemCount()) {
|
||||||
|
Log.e(TAG, "The length of PhoneNum array should same as phone count.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSlotUTData = new SlotUTData[tm.getActiveModemCount()];
|
||||||
|
for (int i = 0; i < mSlotUTData.length; i++) {
|
||||||
|
int[] subIdList = sm.getSubscriptionIds(i);
|
||||||
|
if (subIdList.length < 1) {
|
||||||
|
Log.e(TAG, "getSubscriptionIds() return empty sub id list.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int subId = subIdList[0];
|
||||||
|
|
||||||
|
if (!sm.isActiveSubId(subId)) {
|
||||||
|
mResult.setReason(FeatureResult.FailedReason.SIM_NOT_ACTIVE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryCallWaitingCommand queryCallWaitingCommand =
|
||||||
|
new QueryCallWaitingCommand(tm, executor, subId);
|
||||||
|
QueryCallForwardingCommand queryCallForwardingCommand =
|
||||||
|
new QueryCallForwardingCommand(tm, executor, subId);
|
||||||
|
UpdateCallWaitingCommand updateCallWaitingCommand =
|
||||||
|
new UpdateCallWaitingCommand(tm, executor, queryCallWaitingCommand, subId);
|
||||||
|
UpdateCallForwardingCommand updateCallForwardingCommand =
|
||||||
|
new UpdateCallForwardingCommand(tm, executor, queryCallForwardingCommand,
|
||||||
|
subId, phoneNum[i]);
|
||||||
|
|
||||||
|
mSlotUTData[i] = new SlotUTData(subId, phoneNum[i],
|
||||||
|
queryCallWaitingCommand,
|
||||||
|
queryCallForwardingCommand,
|
||||||
|
updateCallWaitingCommand,
|
||||||
|
updateCallForwardingCommand);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSteps() {
|
||||||
|
// 1. Query call waiting for each slots
|
||||||
|
for (SlotUTData slotUTData : mSlotUTData) {
|
||||||
|
mSteps.add(slotUTData.getQueryCallWaitingCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Query call forwarding for each slots
|
||||||
|
for (SlotUTData slotUTData : mSlotUTData) {
|
||||||
|
mSteps.add(slotUTData.getQueryCallForwardingCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Enable call waiting for each slots
|
||||||
|
for (SlotUTData slotUTData : mSlotUTData) {
|
||||||
|
mSteps.add(slotUTData.getUpdateCallWaitingCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Set call forwarding for each slots
|
||||||
|
for (SlotUTData slotUTData : mSlotUTData) {
|
||||||
|
mSteps.add(slotUTData.getUpdateCallForwardingCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startProcess() {
|
||||||
|
int index = 0;
|
||||||
|
boolean result = true;
|
||||||
|
|
||||||
|
// go through all steps
|
||||||
|
while (index < mSteps.size() && result) {
|
||||||
|
Command currentStep = mSteps.get(index);
|
||||||
|
Log.d(TAG, "processing : " + currentStep);
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = currentStep.process();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(TAG, "Failed on : " + currentStep, e);
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
index++;
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Failed on : " + currentStep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
// No more steps need to perform, return successful to UI.
|
||||||
|
mResult.result = true;
|
||||||
|
mResult.slotUTData = mSlotUTData;
|
||||||
|
Log.d(TAG, "Smart forwarding successful");
|
||||||
|
client.set(mResult);
|
||||||
|
} else {
|
||||||
|
restoreAllSteps(index);
|
||||||
|
client.set(mResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreAllSteps(int index) {
|
||||||
|
List<Command> restoreCommands = mSteps.subList(0, index);
|
||||||
|
Collections.reverse(restoreCommands);
|
||||||
|
for (Command currentStep : restoreCommands) {
|
||||||
|
Log.d(TAG, "restoreStep: " + currentStep);
|
||||||
|
// Only restore update steps
|
||||||
|
if (currentStep instanceof UpdateCommand) {
|
||||||
|
((UpdateCommand) currentStep).onRestore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class SlotUTData {
|
||||||
|
int subId;
|
||||||
|
String mCallForwardingNumber;
|
||||||
|
|
||||||
|
QueryCallWaitingCommand mQueryCallWaiting;
|
||||||
|
QueryCallForwardingCommand mQueryCallForwarding;
|
||||||
|
UpdateCallWaitingCommand mUpdateCallWaiting;
|
||||||
|
UpdateCallForwardingCommand mUpdateCallForwarding;
|
||||||
|
|
||||||
|
public SlotUTData(int subId,
|
||||||
|
String callForwardingNumber,
|
||||||
|
QueryCallWaitingCommand queryCallWaiting,
|
||||||
|
QueryCallForwardingCommand queryCallForwarding,
|
||||||
|
UpdateCallWaitingCommand updateCallWaiting,
|
||||||
|
UpdateCallForwardingCommand updateCallForwarding) {
|
||||||
|
this.subId = subId;
|
||||||
|
this.mCallForwardingNumber = callForwardingNumber;
|
||||||
|
this.mQueryCallWaiting = queryCallWaiting;
|
||||||
|
this.mQueryCallForwarding = queryCallForwarding;
|
||||||
|
this.mUpdateCallWaiting = updateCallWaiting;
|
||||||
|
this.mUpdateCallForwarding = updateCallForwarding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryCallWaitingCommand getQueryCallWaitingCommand() {
|
||||||
|
return mQueryCallWaiting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryCallForwardingCommand getQueryCallForwardingCommand() {
|
||||||
|
return mQueryCallForwarding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UpdateCallWaitingCommand getUpdateCallWaitingCommand() {
|
||||||
|
return mUpdateCallWaiting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UpdateCallForwardingCommand getUpdateCallForwardingCommand() {
|
||||||
|
return mUpdateCallForwarding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Command {
|
||||||
|
boolean process() throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract static class QueryCommand<T> implements Command {
|
||||||
|
int subId;
|
||||||
|
TelephonyManager tm;
|
||||||
|
Executor executor;
|
||||||
|
|
||||||
|
public QueryCommand(TelephonyManager tm, Executor executor, int subId) {
|
||||||
|
this.subId = subId;
|
||||||
|
this.tm = tm;
|
||||||
|
this.executor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName() + "[SubId " + subId + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract T getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract static class UpdateCommand<T> implements Command {
|
||||||
|
int subId;
|
||||||
|
TelephonyManager tm;
|
||||||
|
Executor executor;
|
||||||
|
|
||||||
|
public UpdateCommand(TelephonyManager tm, Executor executor, int subId) {
|
||||||
|
this.subId = subId;
|
||||||
|
this.tm = tm;
|
||||||
|
this.executor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName() + "[SubId " + subId + "] ";
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void onRestore();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class QueryCallWaitingCommand extends QueryCommand<Integer> {
|
||||||
|
int result;
|
||||||
|
SettableFuture<Boolean> resultFuture = SettableFuture.create();
|
||||||
|
|
||||||
|
public QueryCallWaitingCommand(TelephonyManager tm, Executor executor, int subId) {
|
||||||
|
super(tm, executor, subId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process() throws Exception {
|
||||||
|
tm.createForSubscriptionId(subId)
|
||||||
|
.getCallWaitingStatus(executor, this::queryStatusCallBack);
|
||||||
|
return resultFuture.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Integer getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queryStatusCallBack(int result) {
|
||||||
|
this.result = result;
|
||||||
|
|
||||||
|
if (result == TelephonyManager.CALL_WAITING_STATUS_ENABLED
|
||||||
|
|| result == TelephonyManager.CALL_WAITING_STATUS_DISABLED) {
|
||||||
|
Log.d(TAG, "Call Waiting result: " + result);
|
||||||
|
resultFuture.set(true);
|
||||||
|
} else {
|
||||||
|
resultFuture.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class QueryCallForwardingCommand extends QueryCommand<CallForwardingInfo> {
|
||||||
|
CallForwardingInfo result;
|
||||||
|
SettableFuture<Boolean> resultFuture = SettableFuture.create();
|
||||||
|
|
||||||
|
public QueryCallForwardingCommand(TelephonyManager tm, Executor executor, int subId) {
|
||||||
|
super(tm, executor, subId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process() throws Exception{
|
||||||
|
tm.createForSubscriptionId(subId)
|
||||||
|
.getCallForwarding(REASON_NOT_REACHABLE, executor,
|
||||||
|
new TelephonyManager.CallForwardingInfoCallback() {
|
||||||
|
@Override
|
||||||
|
public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
|
||||||
|
Log.d(TAG, "Call Forwarding result: " + info);
|
||||||
|
result = info;
|
||||||
|
resultFuture.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(int error) {
|
||||||
|
Log.d(TAG, "Query Call Forwarding failed.");
|
||||||
|
resultFuture.set(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return resultFuture.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
CallForwardingInfo getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UpdateCallWaitingCommand extends UpdateCommand<Integer> {
|
||||||
|
SettableFuture<Boolean> resultFuture = SettableFuture.create();
|
||||||
|
QueryCallWaitingCommand queryResult;
|
||||||
|
|
||||||
|
public UpdateCallWaitingCommand(TelephonyManager tm, Executor executor,
|
||||||
|
QueryCallWaitingCommand queryCallWaitingCommand, int subId) {
|
||||||
|
super(tm, executor, subId);
|
||||||
|
this.queryResult = queryCallWaitingCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process() throws Exception {
|
||||||
|
tm.createForSubscriptionId(subId)
|
||||||
|
.setCallWaitingEnabled(true, executor, this::updateStatusCallBack);
|
||||||
|
return resultFuture.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateStatusCallBack(int result) {
|
||||||
|
Log.d(TAG, "UpdateCallWaitingCommand updateStatusCallBack result: " + result);
|
||||||
|
if (result == TelephonyManager.CALL_WAITING_STATUS_ENABLED
|
||||||
|
|| result == TelephonyManager.CALL_WAITING_STATUS_DISABLED) {
|
||||||
|
resultFuture.set(true);
|
||||||
|
} else {
|
||||||
|
resultFuture.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void onRestore() {
|
||||||
|
Log.d(TAG, "onRestore: " + this);
|
||||||
|
if (queryResult.getResult() != TelephonyManager.CALL_WAITING_STATUS_ENABLED) {
|
||||||
|
tm.createForSubscriptionId(subId)
|
||||||
|
.setCallWaitingEnabled(false, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UpdateCallForwardingCommand extends UpdateCommand<Integer> {
|
||||||
|
String phoneNum;
|
||||||
|
SettableFuture<Boolean> resultFuture = SettableFuture.create();
|
||||||
|
QueryCallForwardingCommand queryResult;
|
||||||
|
|
||||||
|
public UpdateCallForwardingCommand(TelephonyManager tm, Executor executor,
|
||||||
|
QueryCallForwardingCommand queryCallForwardingCommand,
|
||||||
|
int subId, String phoneNum) {
|
||||||
|
super(tm, executor, subId);
|
||||||
|
this.phoneNum = phoneNum;
|
||||||
|
this.queryResult = queryCallForwardingCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process() throws Exception {
|
||||||
|
CallForwardingInfo info = new CallForwardingInfo(
|
||||||
|
true, REASON_NOT_REACHABLE, phoneNum, 3);
|
||||||
|
tm.createForSubscriptionId(subId)
|
||||||
|
.setCallForwarding(info, executor, this::updateStatusCallBack);
|
||||||
|
return resultFuture.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateStatusCallBack(int result) {
|
||||||
|
Log.d(TAG, "UpdateCallForwardingCommand updateStatusCallBack : " + result);
|
||||||
|
if (result == TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS) {
|
||||||
|
resultFuture.set(true);
|
||||||
|
} else {
|
||||||
|
resultFuture.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void onRestore() {
|
||||||
|
Log.d(TAG, "onRestore: " + this);
|
||||||
|
|
||||||
|
tm.createForSubscriptionId(subId)
|
||||||
|
.setCallForwarding(queryResult.getResult(), null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FeatureResult {
|
||||||
|
enum FailedReason {
|
||||||
|
NETWORK_ERROR,
|
||||||
|
SIM_NOT_ACTIVE
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean result;
|
||||||
|
private FailedReason reason;
|
||||||
|
private SlotUTData[] slotUTData;
|
||||||
|
|
||||||
|
public FeatureResult(boolean result, SlotUTData[] slotUTData) {
|
||||||
|
this.result = result;
|
||||||
|
this.slotUTData = slotUTData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlotUTData[] getSlotUTData() {
|
||||||
|
return slotUTData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReason(FailedReason reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FailedReason getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.settings.sim.smartForwarding;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.telephony.CallForwardingInfo;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
public class SmartForwardingUtils {
|
||||||
|
public static final String TAG = "SmartForwarding";
|
||||||
|
public static final String SMART_FORWARDING_PREF = "smart_forwarding_pref_";
|
||||||
|
|
||||||
|
public static final String CALL_WAITING_KEY = "call_waiting_key";
|
||||||
|
public static final String CALL_FORWARDING_ENABLED_KEY = "call_forwarding_enabled_key";
|
||||||
|
public static final String CALL_FORWARDING_REASON_KEY = "call_forwarding_reason_key";
|
||||||
|
public static final String CALL_FORWARDING_NUMBER_KEY = "call_forwarding_number_key";
|
||||||
|
public static final String CALL_FORWARDING_TIME_KEY = "call_forwarding_timekey";
|
||||||
|
|
||||||
|
public static boolean getBackupCallWaitingStatus(Context context, int subId) {
|
||||||
|
SharedPreferences preferences = context.getSharedPreferences(
|
||||||
|
SMART_FORWARDING_PREF + subId, Context.MODE_PRIVATE);
|
||||||
|
return preferences.getBoolean(CALL_WAITING_KEY, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CallForwardingInfo getBackupCallForwardingStatus(Context context, int subId) {
|
||||||
|
SharedPreferences preferences = context.getSharedPreferences(
|
||||||
|
SMART_FORWARDING_PREF + subId, Context.MODE_PRIVATE);
|
||||||
|
if (preferences.contains(CALL_FORWARDING_ENABLED_KEY)) {
|
||||||
|
boolean enabled = preferences.getBoolean(CALL_FORWARDING_ENABLED_KEY, false);
|
||||||
|
int reason = preferences.getInt(CALL_FORWARDING_REASON_KEY,
|
||||||
|
CallForwardingInfo.REASON_UNCONDITIONAL);
|
||||||
|
String number = preferences.getString(CALL_FORWARDING_NUMBER_KEY, "");
|
||||||
|
int time = preferences.getInt(CALL_FORWARDING_TIME_KEY, 1);
|
||||||
|
|
||||||
|
return new CallForwardingInfo(enabled, reason, number, time);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveCallWaitingStatus(Context context, int subId, boolean value) {
|
||||||
|
SharedPreferences.Editor preferences = context.getSharedPreferences(
|
||||||
|
SMART_FORWARDING_PREF + subId, Context.MODE_PRIVATE).edit();
|
||||||
|
preferences.putBoolean(CALL_WAITING_KEY, value).commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveCallForwardingStatus(Context context, int subId,
|
||||||
|
CallForwardingInfo callForwardingInfo) {
|
||||||
|
SharedPreferences.Editor preferences = context.getSharedPreferences(
|
||||||
|
SMART_FORWARDING_PREF + subId, Context.MODE_PRIVATE).edit();
|
||||||
|
|
||||||
|
preferences.putBoolean(CALL_FORWARDING_ENABLED_KEY, callForwardingInfo.isEnabled())
|
||||||
|
.commit();
|
||||||
|
preferences.putInt(CALL_FORWARDING_REASON_KEY, callForwardingInfo.getReason()).commit();
|
||||||
|
preferences.putString(CALL_FORWARDING_NUMBER_KEY, callForwardingInfo.getNumber()).commit();
|
||||||
|
preferences.putInt(CALL_FORWARDING_TIME_KEY, callForwardingInfo.getTimeoutSeconds())
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearBackupData(Context context, int subId) {
|
||||||
|
SharedPreferences.Editor preferences = context.getSharedPreferences(
|
||||||
|
SMART_FORWARDING_PREF + subId, Context.MODE_PRIVATE).edit();
|
||||||
|
preferences.clear().commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean[] getAllSlotCallWaitingStatus(Context context, SubscriptionManager sm,
|
||||||
|
TelephonyManager tm) {
|
||||||
|
int phoneCount = tm.getActiveModemCount();
|
||||||
|
boolean[] allStatus = new boolean[phoneCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < phoneCount; i++) {
|
||||||
|
int subId = sm.getSubscriptionIds(i)[0];
|
||||||
|
boolean callWaitingStatus = getBackupCallWaitingStatus(context, subId);
|
||||||
|
allStatus[i] = callWaitingStatus;
|
||||||
|
}
|
||||||
|
return allStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CallForwardingInfo[] getAllSlotCallForwardingStatus(
|
||||||
|
Context context, SubscriptionManager sm, TelephonyManager tm) {
|
||||||
|
int phoneCount = tm.getActiveModemCount();
|
||||||
|
CallForwardingInfo[] allStatus = new CallForwardingInfo[phoneCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < phoneCount; i++) {
|
||||||
|
int subId = sm.getSubscriptionIds(i)[0];
|
||||||
|
CallForwardingInfo callWaitingStatus = getBackupCallForwardingStatus(context, subId);
|
||||||
|
allStatus[i] = callWaitingStatus;
|
||||||
|
}
|
||||||
|
return allStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearAllBackupData(Context context, SubscriptionManager sm,
|
||||||
|
TelephonyManager tm) {
|
||||||
|
int phoneCount = tm.getActiveModemCount();
|
||||||
|
for (int i = 0; i < phoneCount; i++) {
|
||||||
|
int subId = sm.getSubscriptionIds(i)[0];
|
||||||
|
clearBackupData(context, subId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void backupPrevStatus(Context context,
|
||||||
|
EnableSmartForwardingTask.SlotUTData[] slotUTData) {
|
||||||
|
for (int i = 0; i < slotUTData.length; i++) {
|
||||||
|
int callWaiting = slotUTData[i].mQueryCallWaiting.result;
|
||||||
|
saveCallWaitingStatus(
|
||||||
|
context,
|
||||||
|
slotUTData[i].subId,
|
||||||
|
callWaiting == TelephonyManager.CALL_WAITING_STATUS_ENABLED);
|
||||||
|
|
||||||
|
saveCallForwardingStatus(
|
||||||
|
context,
|
||||||
|
slotUTData[i].subId,
|
||||||
|
slotUTData[i].mQueryCallForwarding.result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPhoneNumber(Context context, int slotId) {
|
||||||
|
SubscriptionManager subscriptionManager = context.getSystemService(
|
||||||
|
SubscriptionManager.class);
|
||||||
|
int[] subIdList = subscriptionManager.getSubscriptionIds(slotId);
|
||||||
|
if (subIdList != null) {
|
||||||
|
SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(subIdList[0]);
|
||||||
|
return (subInfo != null) ? subInfo.getNumber() : "";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user