Loading core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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); telephony/java/android/telephony/ims/feature/MmTelFeature.java +69 −26 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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( Loading @@ -396,16 +426,16 @@ public class MmTelFeature extends ImsFeature { } } @Override public void setTerminalBasedCallWaitingStatus(boolean enabled) throws RemoteException { synchronized (mLock) { private <T> T executeMethodAsyncForResultNoException(Supplier<T> r, String errorLogName, Executor executor) { CompletableFuture<T> future = CompletableFuture.supplyAsync( () -> TelephonyUtils.runWithCleanCallingIdentity(r), executor); try { MmTelFeature.this.setTerminalBasedCallWaitingStatus(enabled); } catch (ServiceSpecificException se) { throw new ServiceSpecificException(se.errorCode, se.getMessage()); } catch (Exception e) { throw new RemoteException(e.getMessage()); } return future.get(); } catch (ExecutionException | InterruptedException e) { Log.w(LOG_TAG, "MmTelFeature Binder - " + errorLogName + " exception: " + e.getMessage()); return null; } } }; Loading Loading @@ -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. Loading Loading @@ -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(); } /** Loading @@ -1683,7 +1726,7 @@ public class MmTelFeature extends ImsFeature { } private String getSmsFormat() { return getSmsImplementation().getSmsFormat(); return getImsSmsImpl().getSmsFormat(); } /** Loading telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java +42 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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. Loading Loading @@ -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; } } Loading
core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -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);
telephony/java/android/telephony/ims/feature/MmTelFeature.java +69 −26 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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( Loading @@ -396,16 +426,16 @@ public class MmTelFeature extends ImsFeature { } } @Override public void setTerminalBasedCallWaitingStatus(boolean enabled) throws RemoteException { synchronized (mLock) { private <T> T executeMethodAsyncForResultNoException(Supplier<T> r, String errorLogName, Executor executor) { CompletableFuture<T> future = CompletableFuture.supplyAsync( () -> TelephonyUtils.runWithCleanCallingIdentity(r), executor); try { MmTelFeature.this.setTerminalBasedCallWaitingStatus(enabled); } catch (ServiceSpecificException se) { throw new ServiceSpecificException(se.errorCode, se.getMessage()); } catch (Exception e) { throw new RemoteException(e.getMessage()); } return future.get(); } catch (ExecutionException | InterruptedException e) { Log.w(LOG_TAG, "MmTelFeature Binder - " + errorLogName + " exception: " + e.getMessage()); return null; } } }; Loading Loading @@ -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. Loading Loading @@ -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(); } /** Loading @@ -1683,7 +1726,7 @@ public class MmTelFeature extends ImsFeature { } private String getSmsFormat() { return getSmsImplementation().getSmsFormat(); return getImsSmsImpl().getSmsFormat(); } /** Loading
telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java +42 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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. Loading Loading @@ -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; } }