diff options
22 files changed, 503 insertions, 104 deletions
diff --git a/api/current.txt b/api/current.txt index be23b06306d9..c38690c4ba8d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -39497,11 +39497,6 @@ package android.system { field public final int errno; } - public class Int32Ref { - ctor public Int32Ref(int); - field public int value; - } - public class Int64Ref { ctor public Int64Ref(long); field public long value; @@ -39601,7 +39596,6 @@ package android.system { method public static int umask(int); method public static android.system.StructUtsname uname(); method public static void unsetenv(java.lang.String) throws android.system.ErrnoException; - method public static int waitpid(int, android.system.Int32Ref, int) throws android.system.ErrnoException; method public static int write(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException; method public static int write(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException; method public static int writev(java.io.FileDescriptor, java.lang.Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException; diff --git a/api/system-current.txt b/api/system-current.txt index c2becbbc576c..10ce02803f0c 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4789,6 +4789,24 @@ package android.telephony { public final class SmsManager { method public void sendMultipartTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); method public void sendTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent); + field public static final int RESULT_CANCELLED = 23; // 0x17 + field public static final int RESULT_ENCODING_ERROR = 18; // 0x12 + field public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; // 0x6 + field public static final int RESULT_ERROR_NONE = 0; // 0x0 + field public static final int RESULT_INTERNAL_ERROR = 21; // 0x15 + field public static final int RESULT_INVALID_ARGUMENTS = 11; // 0xb + field public static final int RESULT_INVALID_SMSC_ADDRESS = 19; // 0x13 + field public static final int RESULT_INVALID_SMS_FORMAT = 14; // 0xe + field public static final int RESULT_INVALID_STATE = 12; // 0xc + field public static final int RESULT_MODEM_ERROR = 16; // 0x10 + field public static final int RESULT_NETWORK_ERROR = 17; // 0x11 + field public static final int RESULT_NETWORK_REJECT = 10; // 0xa + field public static final int RESULT_NO_MEMORY = 13; // 0xd + field public static final int RESULT_NO_RESOURCES = 22; // 0x16 + field public static final int RESULT_OPERATION_NOT_ALLOWED = 20; // 0x14 + field public static final int RESULT_RADIO_NOT_AVAILABLE = 9; // 0x9 + field public static final int RESULT_REQUEST_NOT_SUPPORTED = 24; // 0x18 + field public static final int RESULT_SYSTEM_ERROR = 15; // 0xf } public class SubscriptionManager { @@ -5049,6 +5067,30 @@ package android.telephony.ims { } +package android.telephony.ims.internal.stub { + + public class SmsImplBase { + ctor public SmsImplBase(); + method public void acknowledgeSms(int, int, int); + method public void acknowledgeSmsReport(int, int, int); + method public java.lang.String getSmsFormat(); + method public void onReady(); + method public final void onSendSmsResult(int, int, int, int) throws java.lang.RuntimeException; + method public final void onSmsReceived(int, java.lang.String, byte[]) throws java.lang.RuntimeException; + method public final void onSmsStatusReportReceived(int, int, java.lang.String, byte[]) throws java.lang.RuntimeException; + method public void sendSms(int, int, java.lang.String, java.lang.String, boolean, byte[]); + field public static final int DELIVER_STATUS_ERROR = 2; // 0x2 + field public static final int DELIVER_STATUS_OK = 1; // 0x1 + field public static final int SEND_STATUS_ERROR = 2; // 0x2 + field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4 + field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3 + field public static final int SEND_STATUS_OK = 1; // 0x1 + field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2 + field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1 + } + +} + package android.telephony.mbms { public final class DownloadRequest implements android.os.Parcelable { diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 35a21a4eaf9f..b255a43cbe30 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -300,11 +300,7 @@ public final class BluetoothA2dp implements BluetoothProfile { } /** - * Initiate connection to a profile of the remote bluetooth device. - * - * <p> Currently, the system supports only 1 connection to the - * A2DP profile. The API will automatically disconnect connected - * devices before connecting. + * Initiate connection to a profile of the remote Bluetooth device. * * <p> This API returns false in scenarios like the profile on the * device is already connected or Bluetooth is not turned on. @@ -699,15 +695,17 @@ public final class BluetoothA2dp implements BluetoothProfile { /** * Gets the current codec status (configuration and capability). * + * @param device the remote Bluetooth device. If null, use the current + * active A2DP Bluetooth device. * @return the current codec status * @hide */ - public BluetoothCodecStatus getCodecStatus() { - if (DBG) Log.d(TAG, "getCodecStatus"); + public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) { + if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")"); try { mServiceLock.readLock().lock(); if (mService != null && isEnabled()) { - return mService.getCodecStatus(); + return mService.getCodecStatus(device); } if (mService == null) { Log.w(TAG, "Proxy not attached to service"); @@ -724,15 +722,18 @@ public final class BluetoothA2dp implements BluetoothProfile { /** * Sets the codec configuration preference. * + * @param device the remote Bluetooth device. If null, use the current + * active A2DP Bluetooth device. * @param codecConfig the codec configuration preference * @hide */ - public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) { - if (DBG) Log.d(TAG, "setCodecConfigPreference"); + public void setCodecConfigPreference(BluetoothDevice device, + BluetoothCodecConfig codecConfig) { + if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")"); try { mServiceLock.readLock().lock(); if (mService != null && isEnabled()) { - mService.setCodecConfigPreference(codecConfig); + mService.setCodecConfigPreference(device, codecConfig); } if (mService == null) Log.w(TAG, "Proxy not attached to service"); return; @@ -747,36 +748,42 @@ public final class BluetoothA2dp implements BluetoothProfile { /** * Enables the optional codecs. * + * @param device the remote Bluetooth device. If null, use the currect + * active A2DP Bluetooth device. * @hide */ - public void enableOptionalCodecs() { - if (DBG) Log.d(TAG, "enableOptionalCodecs"); - enableDisableOptionalCodecs(true); + public void enableOptionalCodecs(BluetoothDevice device) { + if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")"); + enableDisableOptionalCodecs(device, true); } /** * Disables the optional codecs. * + * @param device the remote Bluetooth device. If null, use the currect + * active A2DP Bluetooth device. * @hide */ - public void disableOptionalCodecs() { - if (DBG) Log.d(TAG, "disableOptionalCodecs"); - enableDisableOptionalCodecs(false); + public void disableOptionalCodecs(BluetoothDevice device) { + if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")"); + enableDisableOptionalCodecs(device, false); } /** * Enables or disables the optional codecs. * + * @param device the remote Bluetooth device. If null, use the currect + * active A2DP Bluetooth device. * @param enable if true, enable the optional codecs, other disable them */ - private void enableDisableOptionalCodecs(boolean enable) { + private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) { try { mServiceLock.readLock().lock(); if (mService != null && isEnabled()) { if (enable) { - mService.enableOptionalCodecs(); + mService.enableOptionalCodecs(device); } else { - mService.disableOptionalCodecs(); + mService.disableOptionalCodecs(device); } } if (mService == null) Log.w(TAG, "Proxy not attached to service"); diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index 063186d7f97f..e836230e2273 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -1582,6 +1582,7 @@ public final class MediaDrm implements AutoCloseable { * Key to extract the number of successful {@link #openSession} calls * from the {@link PersistableBundle} returned by a * {@link #getMetrics} call. + * The count is a Long value ({@link android.os.BaseBundle#getLong}). */ public static final String OPEN_SESSION_OK_COUNT = "/drm/mediadrm/open_session/ok/count"; @@ -1590,8 +1591,27 @@ public final class MediaDrm implements AutoCloseable { * Key to extract the number of failed {@link #openSession} calls * from the {@link PersistableBundle} returned by a * {@link #getMetrics} call. + * The count is a Long value ({@link android.os.BaseBundle#getLong}). */ public static final String OPEN_SESSION_ERROR_COUNT = "/drm/mediadrm/open_session/error/count"; + + /** + * Key to extract the number of successful {@link #getKeyRequest} + * calls from the {@link PersistableBundle} returned by a + * {@link #getMetrics} call. + * The count is a Long value ({@link android.os.BaseBundle#getLong}). + */ + public static final String GET_KEY_REQUEST_OK_COUNT + = "/drm/mediadrm/get_key_request/ok/count"; + + /** + * Key to extract the number of failed {@link #getKeyRequest} + * calls from the {@link PersistableBundle} returned by a + * {@link #getMetrics} call. + * The count is a Long value ({@link android.os.BaseBundle#getLong}). + */ + public static final String GET_KEY_REQUEST_ERROR_COUNT + = "/drm/mediadrm/get_key_request/error/count"; } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index 9b69304be308..6b9902425bcb 100755 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -219,8 +219,8 @@ public class A2dpProfile implements LocalBluetoothProfile { return true; } BluetoothCodecConfig codecConfig = null; - if (mServiceWrapper.getCodecStatus() != null) { - codecConfig = mServiceWrapper.getCodecStatus().getCodecConfig(); + if (mServiceWrapper.getCodecStatus(device) != null) { + codecConfig = mServiceWrapper.getCodecStatus(device).getCodecConfig(); } if (codecConfig != null) { return !codecConfig.isMandatoryCodec(); @@ -238,9 +238,9 @@ public class A2dpProfile implements LocalBluetoothProfile { return; } if (enabled) { - mService.enableOptionalCodecs(); + mService.enableOptionalCodecs(device); } else { - mService.disableOptionalCodecs(); + mService.disableOptionalCodecs(device); } } @@ -253,8 +253,8 @@ public class A2dpProfile implements LocalBluetoothProfile { // We want to get the highest priority codec, since that's the one that will be used with // this device, and see if it is high-quality (ie non-mandatory). BluetoothCodecConfig[] selectable = null; - if (mServiceWrapper.getCodecStatus() != null) { - selectable = mServiceWrapper.getCodecStatus().getCodecsSelectableCapabilities(); + if (mServiceWrapper.getCodecStatus(device) != null) { + selectable = mServiceWrapper.getCodecStatus(device).getCodecsSelectableCapabilities(); // To get the highest priority, we sort in reverse. Arrays.sort(selectable, (a, b) -> { diff --git a/packages/SettingsLib/src/com/android/settingslib/wrapper/BluetoothA2dpWrapper.java b/packages/SettingsLib/src/com/android/settingslib/wrapper/BluetoothA2dpWrapper.java index 4c52a9f8d3ce..17e34016a53b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wrapper/BluetoothA2dpWrapper.java +++ b/packages/SettingsLib/src/com/android/settingslib/wrapper/BluetoothA2dpWrapper.java @@ -43,8 +43,8 @@ public class BluetoothA2dpWrapper { /** * Wraps {@code BluetoothA2dp.getCodecStatus} */ - public BluetoothCodecStatus getCodecStatus() { - return mService.getCodecStatus(); + public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) { + return mService.getCodecStatus(device); } /** diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java index ece0d51e2b66..590bc90ca818 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java @@ -123,7 +123,7 @@ public class A2dpProfileTest { when(mBluetoothA2dp.getConnectionState(any())).thenReturn( BluetoothProfile.STATE_CONNECTED); BluetoothCodecStatus status = mock(BluetoothCodecStatus.class); - when(mBluetoothA2dpWrapper.getCodecStatus()).thenReturn(status); + when(mBluetoothA2dpWrapper.getCodecStatus(mDevice)).thenReturn(status); BluetoothCodecConfig config = mock(BluetoothCodecConfig.class); when(status.getCodecConfig()).thenReturn(config); when(config.isMandatoryCodec()).thenReturn(false); @@ -186,7 +186,7 @@ public class A2dpProfileTest { BluetoothCodecStatus status = mock(BluetoothCodecStatus.class); BluetoothCodecConfig config = mock(BluetoothCodecConfig.class); BluetoothCodecConfig[] configs = {config}; - when(mBluetoothA2dpWrapper.getCodecStatus()).thenReturn(status); + when(mBluetoothA2dpWrapper.getCodecStatus(mDevice)).thenReturn(status); when(status.getCodecsSelectableCapabilities()).thenReturn(configs); when(config.isMandatoryCodec()).thenReturn(true); @@ -201,7 +201,7 @@ public class A2dpProfileTest { BluetoothCodecStatus status = mock(BluetoothCodecStatus.class); BluetoothCodecConfig config = mock(BluetoothCodecConfig.class); BluetoothCodecConfig[] configs = {config}; - when(mBluetoothA2dpWrapper.getCodecStatus()).thenReturn(status); + when(mBluetoothA2dpWrapper.getCodecStatus(mDevice)).thenReturn(status); when(status.getCodecsSelectableCapabilities()).thenReturn(configs); when(config.isMandatoryCodec()).thenReturn(false); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 8f41084b2b2c..310e12e7945b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -317,6 +317,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne } public void refreshAllTiles() { + mBrightnessController.checkRestrictionAndSetEnabled(); for (TileRecord r : mRecords) { r.tile.refreshState(); } diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index 3db30fcbbe6b..15e92f48890f 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -31,6 +31,7 @@ import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.os.UserManager; import android.provider.Settings; import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; @@ -39,6 +40,7 @@ import android.widget.ImageView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.Dependency; import java.util.ArrayList; @@ -384,6 +386,18 @@ public class BrightnessController implements ToggleSlider.Listener { } } + public void checkRestrictionAndSetEnabled() { + mBackgroundHandler.post(new Runnable() { + @Override + public void run() { + ((ToggleSliderView)mControl).setEnforcedAdmin( + RestrictedLockUtils.checkIfRestrictionEnforced(mContext, + UserManager.DISALLOW_CONFIG_BRIGHTNESS, + mUserTracker.getCurrentUserId())); + } + }); + } + private void setMode(int mode) { Settings.System.putIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, mode, diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java index 722aba591ea8..8ed4c75e8673 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java +++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSeekBar.java @@ -17,14 +17,21 @@ package com.android.systemui.settings; import android.content.Context; +import android.content.Intent; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.SeekBar; +import com.android.settingslib.RestrictedLockUtils; +import com.android.systemui.Dependency; +import com.android.systemui.plugins.ActivityStarter; + public class ToggleSeekBar extends SeekBar { private String mAccessibilityLabel; + private RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin = null; + public ToggleSeekBar(Context context) { super(context); } @@ -39,6 +46,12 @@ public class ToggleSeekBar extends SeekBar { @Override public boolean onTouchEvent(MotionEvent event) { + if (mEnforcedAdmin != null) { + Intent intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent( + mContext, mEnforcedAdmin); + Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(intent, 0); + return true; + } if (!isEnabled()) { setEnabled(true); } @@ -57,4 +70,8 @@ public class ToggleSeekBar extends SeekBar { info.setText(mAccessibilityLabel); } } + + public void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin) { + mEnforcedAdmin = admin; + } } diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java index 07b9ec27629f..90744a62677d 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java +++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java @@ -29,6 +29,7 @@ import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; +import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.R; import com.android.systemui.statusbar.policy.BrightnessMirrorController; @@ -95,6 +96,12 @@ public class ToggleSliderView extends RelativeLayout implements ToggleSlider { } } + public void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin) { + mToggle.setEnabled(admin == null); + mSlider.setEnabled(admin == null); + mSlider.setEnforcedAdmin(admin); + } + public void setOnChangedListener(Listener l) { mListener = l; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 5f4854aeeb7b..5112d37c830c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1096,9 +1096,19 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mGroupParentWhenDismissed; } - public void performDismiss() { - if (mOnDismissRunnable != null) { - mOnDismissRunnable.run(); + public void performDismiss(boolean fromAccessibility) { + if (mGroupManager.isOnlyChildInGroup(getStatusBarNotification())) { + ExpandableNotificationRow groupSummary = + mGroupManager.getLogicalGroupSummary(getStatusBarNotification()); + if (groupSummary.isClearable()) { + groupSummary.performDismiss(fromAccessibility); + } + } + setDismissed(true, fromAccessibility); + if (isClearable()) { + if (mOnDismissRunnable != null) { + mOnDismissRunnable.run(); + } } } @@ -2328,8 +2338,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } switch (action) { case AccessibilityNodeInfo.ACTION_DISMISS: - NotificationStackScrollLayout.performDismiss(this, mGroupManager, - true /* fromAccessibility */); + performDismiss(true /* fromAccessibility */); return true; case AccessibilityNodeInfo.ACTION_COLLAPSE: case AccessibilityNodeInfo.ACTION_EXPAND: diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java index 97e3d22c6a46..cfc69a8f67a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java @@ -47,7 +47,6 @@ public class RemoteInputController { private final Delegate mDelegate; public RemoteInputController(Delegate delegate) { - addCallback(Dependency.get(StatusBarWindowManager.class)); mDelegate = delegate; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index d13ecaeb11b2..a54b26589628 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -2760,6 +2760,7 @@ public class StatusBar extends SystemUI implements DemoMode, mStackScroller.requestDisallowDismiss(); } }); + mRemoteInputManager.getController().addCallback(mStatusBarWindowManager); mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index af3d64be0fd0..53e470938f3f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -1019,7 +1019,9 @@ public class NotificationStackScrollLayout extends ViewGroup mHeadsUpManager.addSwipedOutNotification(row.getStatusBarNotification().getKey()); } } - performDismiss(v, mGroupManager, false /* fromAccessibility */); + if (v instanceof ExpandableNotificationRow) { + ((ExpandableNotificationRow) v).performDismiss(false /* fromAccessibility */); + } mFalsingManager.onNotificationDismissed(); if (mFalsingManager.shouldEnforceBouncer()) { @@ -1028,26 +1030,6 @@ public class NotificationStackScrollLayout extends ViewGroup } } - public static void performDismiss(View v, NotificationGroupManager groupManager, - boolean fromAccessibility) { - if (!(v instanceof ExpandableNotificationRow)) { - return; - } - ExpandableNotificationRow row = (ExpandableNotificationRow) v; - if (groupManager.isOnlyChildInGroup(row.getStatusBarNotification())) { - ExpandableNotificationRow groupSummary = - groupManager.getLogicalGroupSummary(row.getStatusBarNotification()); - if (groupSummary.isClearable()) { - performDismiss(groupSummary, groupManager, fromAccessibility); - } - } - row.setDismissed(true, fromAccessibility); - if (row.isClearable()) { - row.performDismiss(); - } - if (DEBUG) Log.v(TAG, "onChildDismissed: " + v); - } - @Override public void onChildSnappedBack(View animView, float targetLeft) { mAmbientState.onDragFinished(animView); diff --git a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java index 53a799497fd8..5c83d99b646a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java +++ b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java @@ -18,9 +18,11 @@ import static org.mockito.Mockito.mock; import android.content.Context; import android.util.ArrayMap; +import android.util.ArraySet; public class TestableDependency extends Dependency { private final ArrayMap<Object, Object> mObjs = new ArrayMap<>(); + private final ArraySet<Object> mInstantiatedObjects = new ArraySet<>(); public TestableDependency(Context context) { mContext = context; @@ -47,6 +49,11 @@ public class TestableDependency extends Dependency { @Override protected <T> T createDependency(Object key) { if (mObjs.containsKey(key)) return (T) mObjs.get(key); + mInstantiatedObjects.add(key); return super.createDependency(key); } + + public <T> boolean hasInstantiatedDependency(Class<T> key) { + return mObjs.containsKey(key) || mInstantiatedObjects.contains(key); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java new file mode 100644 index 000000000000..5f763a45f3eb --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2017 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.systemui.statusbar; + +import static org.junit.Assert.assertFalse; +import static org.mockito.Mockito.when; + +import android.os.Handler; +import android.os.Looper; +import android.support.test.filters.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import com.android.systemui.Dependency; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.phone.NotificationGroupManager; +import com.android.systemui.statusbar.phone.StatusBarWindowManager; +import com.android.systemui.statusbar.policy.HeadsUpManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Verifies that particular sets of dependencies don't have dependencies on others. For example, + * code managing notifications shouldn't directly depend on StatusBar, since there are platforms + * which want to manage notifications, but don't use StatusBar. + */ +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class NonPhoneDependencyTest extends SysuiTestCase { + @Mock private NotificationPresenter mPresenter; + @Mock private NotificationListContainer mListContainer; + @Mock private NotificationEntryManager.Callback mEntryManagerCallback; + @Mock private HeadsUpManager mHeadsUpManager; + @Mock private RemoteInputController.Delegate mDelegate; + @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener; + @Mock private NotificationGutsManager.OnSettingsClickListener mOnClickListener; + @Mock private NotificationRemoteInputManager.Callback mRemoteInputManagerCallback; + + private Handler mHandler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mHandler = new Handler(Looper.getMainLooper()); + when(mPresenter.getHandler()).thenReturn(mHandler); + } + + @Test + public void testNotificationManagementCodeHasNoDependencyOnStatusBarWindowManager() { + NotificationEntryManager entryManager = Dependency.get(NotificationEntryManager.class); + NotificationGutsManager gutsManager = Dependency.get(NotificationGutsManager.class); + NotificationListener notificationListener = Dependency.get(NotificationListener.class); + NotificationLogger notificationLogger = Dependency.get(NotificationLogger.class); + NotificationMediaManager mediaManager = Dependency.get(NotificationMediaManager.class); + NotificationRemoteInputManager remoteInputManager = + Dependency.get(NotificationRemoteInputManager.class); + NotificationLockscreenUserManager lockscreenUserManager = + Dependency.get(NotificationLockscreenUserManager.class); + NotificationViewHierarchyManager viewHierarchyManager = + Dependency.get(NotificationViewHierarchyManager.class); + + when(mPresenter.getNotificationLockscreenUserManager()).thenReturn(lockscreenUserManager); + when(mPresenter.getGroupManager()).thenReturn( + Dependency.get(NotificationGroupManager.class)); + + entryManager.setUpWithPresenter(mPresenter, mListContainer, mEntryManagerCallback, + mHeadsUpManager); + gutsManager.setUpWithPresenter(mPresenter, entryManager, mListContainer, + mCheckSaveListener, mOnClickListener); + notificationListener.setUpWithPresenter(mPresenter, entryManager); + notificationLogger.setUpWithEntryManager(entryManager, mListContainer); + mediaManager.setUpWithPresenter(mPresenter, entryManager); + remoteInputManager.setUpWithPresenter(mPresenter, entryManager, mRemoteInputManagerCallback, + mDelegate); + lockscreenUserManager.setUpWithPresenter(mPresenter, entryManager); + viewHierarchyManager.setUpWithPresenter(mPresenter, entryManager, mListContainer); + + assertFalse(mDependency.hasInstantiatedDependency(StatusBarWindowManager.class)); + } +} diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java index b6c3c66924f0..0d567d1e971d 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java @@ -40,6 +40,7 @@ import android.security.keystore.recovery.WrappedApplicationKey; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.HexDump; import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb; import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage; import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage; @@ -455,22 +456,66 @@ public class RecoverableKeyStoreManager { private byte[] decryptRecoveryKey( RecoverySessionStorage.Entry sessionEntry, byte[] encryptedClaimResponse) throws RemoteException, ServiceSpecificException { + // TODO: Remove the extensive loggings in this function + byte[] locallyEncryptedKey; try { - byte[] locallyEncryptedKey = KeySyncUtils.decryptRecoveryClaimResponse( + locallyEncryptedKey = KeySyncUtils.decryptRecoveryClaimResponse( sessionEntry.getKeyClaimant(), sessionEntry.getVaultParams(), encryptedClaimResponse); - return KeySyncUtils.decryptRecoveryKey(sessionEntry.getLskfHash(), locallyEncryptedKey); - } catch (InvalidKeyException | AEADBadTagException e) { + } catch (InvalidKeyException e) { + Log.e(TAG, "Got InvalidKeyException during decrypting recovery claim response", e); + Log.e(TAG, constructLoggingMessage("sessionEntry.getKeyClaimant()", + sessionEntry.getKeyClaimant())); + Log.e(TAG, constructLoggingMessage("sessionEntry.getVaultParams()", + sessionEntry.getVaultParams())); + Log.e(TAG, constructLoggingMessage("encryptedClaimResponse", encryptedClaimResponse)); throw new ServiceSpecificException(ERROR_DECRYPTION_FAILED, "Failed to decrypt recovery key " + e.getMessage()); + } catch (AEADBadTagException e) { + Log.e(TAG, "Got AEADBadTagException during decrypting recovery claim response", e); + Log.e(TAG, constructLoggingMessage("sessionEntry.getKeyClaimant()", + sessionEntry.getKeyClaimant())); + Log.e(TAG, constructLoggingMessage("sessionEntry.getVaultParams()", + sessionEntry.getVaultParams())); + Log.e(TAG, constructLoggingMessage("encryptedClaimResponse", encryptedClaimResponse)); + throw new ServiceSpecificException(ERROR_DECRYPTION_FAILED, + "Failed to decrypt recovery key " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + // Should never happen: all the algorithms used are required by AOSP implementations + throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage()); + } + try { + return KeySyncUtils.decryptRecoveryKey(sessionEntry.getLskfHash(), locallyEncryptedKey); + } catch (InvalidKeyException e) { + Log.e(TAG, "Got InvalidKeyException during decrypting recovery key", e); + Log.e(TAG, constructLoggingMessage("sessionEntry.getLskfHash()", + sessionEntry.getLskfHash())); + Log.e(TAG, constructLoggingMessage("locallyEncryptedKey", locallyEncryptedKey)); + throw new ServiceSpecificException(ERROR_DECRYPTION_FAILED, + "Failed to decrypt recovery key " + e.getMessage()); + } catch (AEADBadTagException e) { + Log.e(TAG, "Got AEADBadTagException during decrypting recovery key", e); + Log.e(TAG, constructLoggingMessage("sessionEntry.getLskfHash()", + sessionEntry.getLskfHash())); + Log.e(TAG, constructLoggingMessage("locallyEncryptedKey", locallyEncryptedKey)); + throw new ServiceSpecificException(ERROR_DECRYPTION_FAILED, + "Failed to decrypt recovery key " + e.getMessage()); } catch (NoSuchAlgorithmException e) { // Should never happen: all the algorithms used are required by AOSP implementations throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage()); } } + private String constructLoggingMessage(String key, byte[] value) { + if (value == null) { + return key + " is null"; + } else { + return key + ": " + HexDump.toHexString(value); + } + } + /** * Uses {@code recoveryKey} to decrypt {@code applicationKeys}. * diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 5d88cf07bb91..0874b86494e6 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -1134,7 +1134,11 @@ public final class SmsManager { // SMS send failure result codes - /** No error. {@hide}*/ + /** + * No error. + * @hide + */ + @SystemApi static public final int RESULT_ERROR_NONE = 0; /** Generic failure cause */ static public final int RESULT_ERROR_GENERIC_FAILURE = 1; @@ -1146,12 +1150,113 @@ public final class SmsManager { static public final int RESULT_ERROR_NO_SERVICE = 4; /** Failed because we reached the sending queue limit. */ static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5; - /** Failed because FDN is enabled. {@hide} */ + /** + * Failed because FDN is enabled. + * @hide + */ + @SystemApi static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; /** Failed because user denied the sending of this short code. */ static public final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7; /** Failed because the user has denied this app ever send premium short codes. */ static public final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8; + /** + * Failed because the radio was not available + * @hide + */ + @SystemApi + static public final int RESULT_RADIO_NOT_AVAILABLE = 9; + /** + * Failed because of network rejection + * @hide + */ + @SystemApi + static public final int RESULT_NETWORK_REJECT = 10; + /** + * Failed because of invalid arguments + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_ARGUMENTS = 11; + /** + * Failed because of an invalid state + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_STATE = 12; + /** + * Failed because there is no memory + * @hide + */ + @SystemApi + static public final int RESULT_NO_MEMORY = 13; + /** + * Failed because the sms format is not valid + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_SMS_FORMAT = 14; + /** + * Failed because of a system error + * @hide + */ + @SystemApi + static public final int RESULT_SYSTEM_ERROR = 15; + /** + * Failed because of a modem error + * @hide + */ + @SystemApi + static public final int RESULT_MODEM_ERROR = 16; + /** + * Failed because of a network error + * @hide + */ + @SystemApi + static public final int RESULT_NETWORK_ERROR = 17; + /** + * Failed because of an encoding error + * @hide + */ + @SystemApi + static public final int RESULT_ENCODING_ERROR = 18; + /** + * Failed because of an invalid smsc address + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_SMSC_ADDRESS = 19; + /** + * Failed because the operation is not allowed + * @hide + */ + @SystemApi + static public final int RESULT_OPERATION_NOT_ALLOWED = 20; + /** + * Failed because of an internal error + * @hide + */ + @SystemApi + static public final int RESULT_INTERNAL_ERROR = 21; + /** + * Failed because there are no resources + * @hide + */ + @SystemApi + static public final int RESULT_NO_RESOURCES = 22; + /** + * Failed because the operation was cancelled + * @hide + */ + @SystemApi + static public final int RESULT_CANCELLED = 23; + /** + * Failed because the request is not supported + * @hide + */ + @SystemApi + static public final int RESULT_REQUEST_NOT_SUPPORTED = 24; + static private final String PHONE_PACKAGE_NAME = "com.android.phone"; diff --git a/telephony/java/android/telephony/ims/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/feature/MMTelFeature.java index 519710728403..93c316f3dcb9 100644 --- a/telephony/java/android/telephony/ims/feature/MMTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MMTelFeature.java @@ -209,6 +209,13 @@ public class MMTelFeature extends ImsFeature { return MMTelFeature.this.getSmsFormat(); } } + + @Override + public void onSmsReady() { + synchronized (mLock) { + MMTelFeature.this.onSmsReady(); + } + } }; /** @@ -384,25 +391,29 @@ public class MMTelFeature extends ImsFeature { return null; } - public void setSmsListener(IImsSmsListener listener) { + private void setSmsListener(IImsSmsListener listener) { getSmsImplementation().registerSmsListener(listener); } - public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry, + private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry, byte[] pdu) { getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu); } - public void acknowledgeSms(int token, int messageRef, + private void acknowledgeSms(int token, int messageRef, @SmsImplBase.DeliverStatusResult int result) { getSmsImplementation().acknowledgeSms(token, messageRef, result); } - public void acknowledgeSmsReport(int token, int messageRef, + private void acknowledgeSmsReport(int token, int messageRef, @SmsImplBase.StatusReportResult int result) { getSmsImplementation().acknowledgeSmsReport(token, messageRef, result); } + private void onSmsReady() { + getSmsImplementation().onReady(); + } + /** * Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default * non-functional implementation is returned. diff --git a/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java b/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java index 113dad4696ef..89acc80a9d3b 100644 --- a/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java +++ b/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java @@ -17,10 +17,10 @@ package android.telephony.ims.internal.stub; import android.annotation.IntDef; +import android.annotation.SystemApi; import android.os.RemoteException; import android.telephony.SmsManager; import android.telephony.SmsMessage; -import android.telephony.ims.internal.feature.MmTelFeature; import android.util.Log; import com.android.ims.internal.IImsSmsListener; @@ -33,11 +33,14 @@ import java.lang.annotation.RetentionPolicy; * * Any service wishing to provide SMS over IMS should extend this class and implement all methods * that the service supports. + * * @hide */ +@SystemApi public class SmsImplBase { private static final String LOG_TAG = "SmsImplBase"; + /** @hide */ @IntDef({ SEND_STATUS_OK, SEND_STATUS_ERROR, @@ -58,8 +61,8 @@ public class SmsImplBase { public static final int SEND_STATUS_ERROR = 2; /** - * IMS provider failed to send the message and platform should retry again after setting TP-RD bit - * to high. + * IMS provider failed to send the message and platform should retry again after setting TP-RD + * bit to high. */ public static final int SEND_STATUS_ERROR_RETRY = 3; @@ -69,6 +72,7 @@ public class SmsImplBase { */ public static final int SEND_STATUS_ERROR_FALLBACK = 4; + /** @hide */ @IntDef({ DELIVER_STATUS_OK, DELIVER_STATUS_ERROR @@ -85,6 +89,7 @@ public class SmsImplBase { */ public static final int DELIVER_STATUS_ERROR = 2; + /** @hide */ @IntDef({ STATUS_REPORT_STATUS_OK, STATUS_REPORT_STATUS_ERROR @@ -140,21 +145,23 @@ public class SmsImplBase { try { onSendSmsResult(token, messageRef, SEND_STATUS_ERROR, SmsManager.RESULT_ERROR_GENERIC_FAILURE); - } catch (RemoteException e) { + } catch (RuntimeException e) { Log.e(LOG_TAG, "Can not send sms: " + e.getMessage()); } } /** - * This method will be triggered by the platform after {@link #onSmsReceived(int, String, byte[])} - * has been called to deliver the result to the IMS provider. + * This method will be triggered by the platform after + * {@link #onSmsReceived(int, String, byte[])} has been called to deliver the result to the IMS + * provider. * * @param token token provided in {@link #onSmsReceived(int, String, byte[])} - * @param result result of delivering the message. Valid values are defined in - * {@link DeliverStatusResult} + * @param result result of delivering the message. Valid values are: + * {@link #DELIVER_STATUS_OK}, + * {@link #DELIVER_STATUS_OK} * @param messageRef the message reference */ - public void acknowledgeSms(int token, int messageRef, @DeliverStatusResult int result) { + public void acknowledgeSms(int token, @DeliverStatusResult int messageRef, int result) { Log.e(LOG_TAG, "acknowledgeSms() not implemented."); } @@ -164,8 +171,9 @@ public class SmsImplBase { * result to the IMS provider. * * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} - * @param result result of delivering the message. Valid values are defined in - * {@link StatusReportResult} + * @param result result of delivering the message. Valid values are: + * {@link #STATUS_REPORT_STATUS_OK}, + * {@link #STATUS_REPORT_STATUS_ERROR} * @param messageRef the message reference */ public void acknowledgeSmsReport(int token, int messageRef, @StatusReportResult int result) { @@ -177,20 +185,17 @@ public class SmsImplBase { * platform will deliver the message to the messages database and notify the IMS provider of the * result by calling {@link #acknowledgeSms(int, int, int)}. * - * This method must not be called before {@link MmTelFeature#onFeatureReady()} is called. - * * @param token unique token generated by IMS providers that the platform will use to trigger * callbacks for this message. * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and * {@link SmsMessage#FORMAT_3GPP2}. * @param pdu PDUs representing the contents of the message. - * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()} + * @throws RuntimeException if called before {@link #onReady()} is triggered. */ - public final void onSmsReceived(int token, String format, byte[] pdu) - throws IllegalStateException { + public final void onSmsReceived(int token, String format, byte[] pdu) throws RuntimeException { synchronized (mLock) { if (mListener == null) { - throw new IllegalStateException("Feature not ready."); + throw new RuntimeException("Feature not ready."); } try { mListener.onSmsReceived(token, format, pdu); @@ -205,11 +210,13 @@ public class SmsImplBase { * This method should be triggered by the IMS providers to pass the result of the sent message * to the platform. * - * This method must not be called before {@link MmTelFeature#onFeatureReady()} is called. - * * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040 - * @param status result of sending the SMS. Valid values are defined in {@link SendStatusResult} + * @param status result of sending the SMS. Valid values are: + * {@link #SEND_STATUS_OK}, + * {@link #SEND_STATUS_ERROR}, + * {@link #SEND_STATUS_ERROR_RETRY}, + * {@link #SEND_STATUS_ERROR_FALLBACK}, * @param reason reason in case status is failure. Valid values are: * {@link SmsManager#RESULT_ERROR_NONE}, * {@link SmsManager#RESULT_ERROR_GENERIC_FAILURE}, @@ -217,19 +224,41 @@ public class SmsImplBase { * {@link SmsManager#RESULT_ERROR_NULL_PDU}, * {@link SmsManager#RESULT_ERROR_NO_SERVICE}, * {@link SmsManager#RESULT_ERROR_LIMIT_EXCEEDED}, + * {@link SmsManager#RESULT_ERROR_FDN_CHECK_FAILURE}, * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NOT_ALLOWED}, - * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED} - * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()} - * @throws RemoteException if the connection to the framework is not available. If this happens - * attempting to send the SMS should be aborted. + * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED}, + * {@link SmsManager#RESULT_RADIO_NOT_AVAILABLE}, + * {@link SmsManager#RESULT_NETWORK_REJECT}, + * {@link SmsManager#RESULT_INVALID_ARGUMENTS}, + * {@link SmsManager#RESULT_INVALID_STATE}, + * {@link SmsManager#RESULT_NO_MEMORY}, + * {@link SmsManager#RESULT_INVALID_SMS_FORMAT}, + * {@link SmsManager#RESULT_SYSTEM_ERROR}, + * {@link SmsManager#RESULT_MODEM_ERROR}, + * {@link SmsManager#RESULT_NETWORK_ERROR}, + * {@link SmsManager#RESULT_ENCODING_ERROR}, + * {@link SmsManager#RESULT_INVALID_SMSC_ADDRESS}, + * {@link SmsManager#RESULT_OPERATION_NOT_ALLOWED}, + * {@link SmsManager#RESULT_INTERNAL_ERROR}, + * {@link SmsManager#RESULT_NO_RESOURCES}, + * {@link SmsManager#RESULT_CANCELLED}, + * {@link SmsManager#RESULT_REQUEST_NOT_SUPPORTED} + * + * @throws RuntimeException if called before {@link #onReady()} is triggered or if the + * connection to the framework is not available. If this happens attempting to send the SMS + * should be aborted. */ - public final void onSendSmsResult(int token, int messageRef, @SendStatusResult int status, - int reason) throws IllegalStateException, RemoteException { + public final void onSendSmsResult(int token, int messageRef, @SendStatusResult int status, + int reason) throws RuntimeException { synchronized (mLock) { if (mListener == null) { - throw new IllegalStateException("Feature not ready."); + throw new RuntimeException("Feature not ready."); + } + try { + mListener.onSendSmsResult(token, messageRef, status, reason); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); } - mListener.onSendSmsResult(token, messageRef, status, reason); } } @@ -241,13 +270,13 @@ public class SmsImplBase { * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and * {@link SmsMessage#FORMAT_3GPP2}. * @param pdu PDUs representing the content of the status report. - * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()} + * @throws RuntimeException if called before {@link #onReady()} is triggered */ public final void onSmsStatusReportReceived(int token, int messageRef, String format, - byte[] pdu) { + byte[] pdu) throws RuntimeException{ synchronized (mLock) { if (mListener == null) { - throw new IllegalStateException("Feature not ready."); + throw new RuntimeException("Feature not ready."); } try { mListener.onSmsStatusReportReceived(token, messageRef, format, pdu); @@ -268,4 +297,13 @@ public class SmsImplBase { public String getSmsFormat() { return SmsMessage.FORMAT_3GPP; } + + /** + * Called when SmsImpl has been initialized and communication with the framework is set up. + * Any attempt by this class to access the framework before this method is called will return + * with an {@link RuntimeException}. + */ + public void onReady() { + // Base Implementation - Should be overridden + } } diff --git a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl index cce39f4daf2a..10c7f3e8a2d7 100644 --- a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl +++ b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl @@ -61,4 +61,5 @@ interface IImsMMTelFeature { oneway void acknowledgeSms(int token, int messageRef, int result); oneway void acknowledgeSmsReport(int token, int messageRef, int result); String getSmsFormat(); + oneway void onSmsReady(); } |