diff options
| author | 2022-12-19 18:49:51 +0000 | |
|---|---|---|
| committer | 2022-12-19 18:49:51 +0000 | |
| commit | ef4cbddd832cf6fad8a4e372c47836739ebc57c0 (patch) | |
| tree | 0ff968025f84612e511d7b28bd14d00255f8e658 | |
| parent | 4845b2c493bbd0148993b101b28ae41f08db7876 (diff) | |
| parent | 0780ddeda11e71fd29f5bc7804f2c4b3ba57846a (diff) | |
Merge "Executor Pattern for ImsSmsImplBase"
| -rw-r--r-- | core/api/system-current.txt | 1 | ||||
| -rw-r--r-- | telephony/java/android/telephony/ims/feature/MmTelFeature.java | 95 | ||||
| -rw-r--r-- | telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java | 42 |
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; + } } |