summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hakjun Choi <hakjunc@google.com> 2022-12-19 18:49:51 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-19 18:49:51 +0000
commitef4cbddd832cf6fad8a4e372c47836739ebc57c0 (patch)
tree0ff968025f84612e511d7b28bd14d00255f8e658
parent4845b2c493bbd0148993b101b28ae41f08db7876 (diff)
parent0780ddeda11e71fd29f5bc7804f2c4b3ba57846a (diff)
Merge "Executor Pattern for ImsSmsImplBase"
-rw-r--r--core/api/system-current.txt1
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java95
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java42
3 files changed, 112 insertions, 26 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 567a570309a3..164654145517 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -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);
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index e21358832fbb..f412116d32b9 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -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;
}
}
};
@@ -1491,6 +1521,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.
* @hide
@@ -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();
}
/**
diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
index daab84eb077c..17cb3b46e0f1 100644
--- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
@@ -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;
+ }
}