Merge "Executor Pattern for ImsSmsImplBase"

This commit is contained in:
Hakjun Choi
2022-12-19 18:49:51 +00:00
committed by Android (Google) Code Review
3 changed files with 112 additions and 26 deletions

View File

@@ -16031,6 +16031,7 @@ package android.telephony.ims.stub {
public class ImsSmsImplBase {
ctor public ImsSmsImplBase();
ctor public ImsSmsImplBase(@NonNull java.util.concurrent.Executor);
method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int);
method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int, @NonNull byte[]);
method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int);

View File

@@ -84,10 +84,12 @@ public class MmTelFeature extends ImsFeature {
private static final String LOG_TAG = "MmTelFeature";
private Executor mExecutor;
private ImsSmsImplBase mSmsImpl;
private HashMap<ImsTrafficSessionCallback, ImsTrafficSessionCallbackWrapper> mTrafficCallbacks =
new HashMap<>();
/**
* Creates a new MmTelFeature using the Executor set in {@link ImsService#getExecutor}
* @hide
*/
@SystemApi
@@ -269,50 +271,54 @@ public class MmTelFeature extends ImsFeature {
@Override
public void setSmsListener(IImsSmsListener l) {
executeMethodAsyncNoException(() -> MmTelFeature.this.setSmsListener(l),
"setSmsListener");
"setSmsListener", getImsSmsImpl().getExecutor());
}
@Override
public void sendSms(int token, int messageRef, String format, String smsc, boolean retry,
byte[] pdu) {
executeMethodAsyncNoException(() -> MmTelFeature.this
.sendSms(token, messageRef, format, smsc, retry, pdu), "sendSms");
.sendSms(token, messageRef, format, smsc, retry, pdu), "sendSms",
getImsSmsImpl().getExecutor());
}
@Override
public void onMemoryAvailable(int token) {
executeMethodAsyncNoException(() -> MmTelFeature.this
.onMemoryAvailable(token), "onMemoryAvailable");
.onMemoryAvailable(token), "onMemoryAvailable", getImsSmsImpl().getExecutor());
}
@Override
public void acknowledgeSms(int token, int messageRef, int result) {
executeMethodAsyncNoException(() -> MmTelFeature.this
.acknowledgeSms(token, messageRef, result), "acknowledgeSms");
.acknowledgeSms(token, messageRef, result), "acknowledgeSms",
getImsSmsImpl().getExecutor());
}
@Override
public void acknowledgeSmsWithPdu(int token, int messageRef, int result, byte[] pdu) {
executeMethodAsyncNoException(() -> MmTelFeature.this
.acknowledgeSms(token, messageRef, result, pdu), "acknowledgeSms");
.acknowledgeSms(token, messageRef, result, pdu), "acknowledgeSms",
getImsSmsImpl().getExecutor());
}
@Override
public void acknowledgeSmsReport(int token, int messageRef, int result) {
executeMethodAsyncNoException(() -> MmTelFeature.this
.acknowledgeSmsReport(token, messageRef, result), "acknowledgeSmsReport");
.acknowledgeSmsReport(token, messageRef, result), "acknowledgeSmsReport",
getImsSmsImpl().getExecutor());
}
@Override
public String getSmsFormat() {
return executeMethodAsyncForResultNoException(() -> MmTelFeature.this
.getSmsFormat(), "getSmsFormat");
.getSmsFormat(), "getSmsFormat", getImsSmsImpl().getExecutor());
}
@Override
public void onSmsReady() {
executeMethodAsyncNoException(() -> MmTelFeature.this.onSmsReady(),
"onSmsReady");
"onSmsReady", getImsSmsImpl().getExecutor());
}
@Override
@@ -347,6 +353,19 @@ public class MmTelFeature extends ImsFeature {
() -> MmTelFeature.this.notifySrvccCanceled(), "notifySrvccCanceled");
}
@Override
public void setTerminalBasedCallWaitingStatus(boolean enabled) throws RemoteException {
synchronized (mLock) {
try {
MmTelFeature.this.setTerminalBasedCallWaitingStatus(enabled);
} catch (ServiceSpecificException se) {
throw new ServiceSpecificException(se.errorCode, se.getMessage());
} catch (Exception e) {
throw new RemoteException(e.getMessage());
}
}
}
// Call the methods with a clean calling identity on the executor and wait indefinitely for
// the future to return.
private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException {
@@ -370,6 +389,17 @@ public class MmTelFeature extends ImsFeature {
}
}
private void executeMethodAsyncNoException(Runnable r, String errorLogName,
Executor executor) {
try {
CompletableFuture.runAsync(
() -> TelephonyUtils.runWithCleanCallingIdentity(r), executor).join();
} catch (CancellationException | CompletionException e) {
Log.w(LOG_TAG, "MmTelFeature Binder - " + errorLogName + " exception: "
+ e.getMessage());
}
}
private <T> T executeMethodAsyncForResult(Supplier<T> r,
String errorLogName) throws RemoteException {
CompletableFuture<T> future = CompletableFuture.supplyAsync(
@@ -396,16 +426,16 @@ public class MmTelFeature extends ImsFeature {
}
}
@Override
public void setTerminalBasedCallWaitingStatus(boolean enabled) throws RemoteException {
synchronized (mLock) {
try {
MmTelFeature.this.setTerminalBasedCallWaitingStatus(enabled);
} catch (ServiceSpecificException se) {
throw new ServiceSpecificException(se.errorCode, se.getMessage());
} catch (Exception e) {
throw new RemoteException(e.getMessage());
}
private <T> T executeMethodAsyncForResultNoException(Supplier<T> r,
String errorLogName, Executor executor) {
CompletableFuture<T> future = CompletableFuture.supplyAsync(
() -> TelephonyUtils.runWithCleanCallingIdentity(r), executor);
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
Log.w(LOG_TAG, "MmTelFeature Binder - " + errorLogName + " exception: "
+ e.getMessage());
return null;
}
}
};
@@ -1490,6 +1520,19 @@ public class MmTelFeature extends ImsFeature {
}
}
/**
* @hide
*/
public @NonNull ImsSmsImplBase getImsSmsImpl() {
synchronized (mLock) {
if (mSmsImpl == null) {
mSmsImpl = getSmsImplementation();
mSmsImpl.setDefaultExecutor(mExecutor);
}
return mSmsImpl;
}
}
/**
* @return The {@link ImsUtImplBase} Ut interface implementation for the supplementary service
* configuration.
@@ -1638,35 +1681,35 @@ public class MmTelFeature extends ImsFeature {
}
private void setSmsListener(IImsSmsListener listener) {
getSmsImplementation().registerSmsListener(listener);
getImsSmsImpl().registerSmsListener(listener);
}
private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
byte[] pdu) {
getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu);
getImsSmsImpl().sendSms(token, messageRef, format, smsc, isRetry, pdu);
}
private void onMemoryAvailable(int token) {
getSmsImplementation().onMemoryAvailable(token);
getImsSmsImpl().onMemoryAvailable(token);
}
private void acknowledgeSms(int token, int messageRef,
@ImsSmsImplBase.DeliverStatusResult int result) {
getSmsImplementation().acknowledgeSms(token, messageRef, result);
getImsSmsImpl().acknowledgeSms(token, messageRef, result);
}
private void acknowledgeSms(int token, int messageRef,
@ImsSmsImplBase.DeliverStatusResult int result, byte[] pdu) {
getSmsImplementation().acknowledgeSms(token, messageRef, result, pdu);
getImsSmsImpl().acknowledgeSms(token, messageRef, result, pdu);
}
private void acknowledgeSmsReport(int token, int messageRef,
@ImsSmsImplBase.StatusReportResult int result) {
getSmsImplementation().acknowledgeSmsReport(token, messageRef, result);
getImsSmsImpl().acknowledgeSmsReport(token, messageRef, result);
}
private void onSmsReady() {
getSmsImplementation().onReady();
getImsSmsImpl().onReady();
}
/**
@@ -1683,7 +1726,7 @@ public class MmTelFeature extends ImsFeature {
}
private String getSmsFormat() {
return getSmsImplementation().getSmsFormat();
return getImsSmsImpl().getSmsFormat();
}
/**

View File

@@ -28,6 +28,7 @@ import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
/**
* Base implementation for SMS over IMS.
@@ -129,6 +130,22 @@ public class ImsSmsImplBase {
// Lock for feature synchronization
private final Object mLock = new Object();
private IImsSmsListener mListener;
private Executor mExecutor;
/**
* Create a new ImsSmsImplBase using the Executor set in MmTelFeature
*/
public ImsSmsImplBase() {
}
/**
* Create a new ImsSmsImplBase with specified executor.
* <p>
* @param executor Default executor for ImsSmsImplBase
*/
public ImsSmsImplBase(@NonNull Executor executor) {
mExecutor = executor;
}
/**
* Registers a listener responsible for handling tasks like delivering messages.
@@ -482,4 +499,29 @@ public class ImsSmsImplBase {
public void onReady() {
// Base Implementation - Should be overridden
}
/**
* Set default Executor for ImsSmsImplBase.
*
* @param executor The default executor for the framework to use when executing the methods
* overridden by the implementation of ImsSms.
* @hide
*/
public final void setDefaultExecutor(@NonNull Executor executor) {
if (mExecutor == null) {
mExecutor = executor;
}
}
/**
* Get Executor from ImsSmsImplBase.
* If there is no settings for the executor, all ImsSmsImplBase method calls will use
* Runnable::run as default
*
* @return an Executor used to execute methods in ImsSms called remotely by the framework.
* @hide
*/
public @NonNull Executor getExecutor() {
return mExecutor != null ? mExecutor : Runnable::run;
}
}