diff options
54 files changed, 1888 insertions, 272 deletions
diff --git a/Android.bp b/Android.bp index 678b5da8a0b4..e2b432cdd8cd 100644 --- a/Android.bp +++ b/Android.bp @@ -506,11 +506,14 @@ java_defaults { "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl", "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl", "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl", + "telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl", "telephony/java/android/telephony/mbms/IDownloadStatusListener.aidl", "telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl", "telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl", + "telephony/java/android/telephony/mbms/IGroupCallCallback.aidl", "telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl", "telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl", + "telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl", "telephony/java/android/telephony/INetworkService.aidl", "telephony/java/android/telephony/INetworkServiceCallback.aidl", "telephony/java/com/android/ims/internal/IImsCallSession.aidl", @@ -795,7 +798,7 @@ gensrcs { java_library { name: "ext", installable: true, - no_framework_libs: true, + sdk_version: "core_current", static_libs: [ "libphonenumber-platform", "nist-sip", diff --git a/api/current.txt b/api/current.txt index b902ddcb37ce..17c446c26d94 100755 --- a/api/current.txt +++ b/api/current.txt @@ -41989,6 +41989,7 @@ package android.telephony { field public static final deprecated java.lang.String KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL = "restart_radio_on_pdp_fail_regular_deactivation_bool"; field public static final java.lang.String KEY_RTT_SUPPORTED_BOOL = "rtt_supported_bool"; field public static final java.lang.String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool"; + field public static final java.lang.String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool"; field public static final java.lang.String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool"; field public static final java.lang.String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool"; field public static final java.lang.String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool"; @@ -42250,6 +42251,13 @@ package android.telephony { field public static final int STATUS_UNKNOWN = 0; // 0x0 } + public class MbmsGroupCallSession implements java.lang.AutoCloseable { + method public void close(); + method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsGroupCallSessionCallback); + method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsGroupCallSessionCallback); + method public android.telephony.mbms.GroupCall startGroupCall(java.util.concurrent.Executor, long, int[], int[], android.telephony.mbms.GroupCallCallback); + } + public class MbmsStreamingSession implements java.lang.AutoCloseable { method public void close(); method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsStreamingSessionCallback); @@ -42629,6 +42637,7 @@ package android.telephony { method public static int getDefaultVoiceSubscriptionId(); method public static int[] getSubscriptionIds(int); method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int); + method public boolean isActiveSubscriptionId(int); method public boolean isNetworkRoaming(int); method public static boolean isValidSubscriptionId(int); method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); @@ -43195,6 +43204,29 @@ package android.telephony.mbms { field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileServiceInfo> CREATOR; } + public class GroupCall implements java.lang.AutoCloseable { + method public void close(); + method public long getTmgi(); + method public void updateGroupCall(int[], int[]); + field public static final int REASON_BY_USER_REQUEST = 1; // 0x1 + field public static final int REASON_FREQUENCY_CONFLICT = 3; // 0x3 + field public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6; // 0x6 + field public static final int REASON_NONE = 0; // 0x0 + field public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; // 0x5 + field public static final int REASON_OUT_OF_MEMORY = 4; // 0x4 + field public static final int STATE_STALLED = 3; // 0x3 + field public static final int STATE_STARTED = 2; // 0x2 + field public static final int STATE_STOPPED = 1; // 0x1 + } + + public class GroupCallCallback { + ctor public GroupCallCallback(); + method public void onBroadcastSignalStrengthUpdated(int); + method public void onError(int, java.lang.String); + method public void onGroupCallStateChanged(int, int); + field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff + } + public class MbmsDownloadReceiver extends android.content.BroadcastReceiver { ctor public MbmsDownloadReceiver(); method public void onReceive(android.content.Context, android.content.Intent); @@ -43243,6 +43275,14 @@ package android.telephony.mbms { field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e } + public class MbmsGroupCallSessionCallback { + ctor public MbmsGroupCallSessionCallback(); + method public void onAvailableSaisUpdated(java.util.List<java.lang.Integer>, java.util.List<java.util.List<java.lang.Integer>>); + method public void onError(int, java.lang.String); + method public void onMiddlewareReady(); + method public void onServiceInterfaceAvailable(java.lang.String, int); + } + public class MbmsStreamingSessionCallback { ctor public MbmsStreamingSessionCallback(); method public void onError(int, java.lang.String); diff --git a/api/system-current.txt b/api/system-current.txt index d4ad8fd45243..231a32785b00 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5075,6 +5075,10 @@ package android.telephony { field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload"; } + public class MbmsGroupCallSession implements java.lang.AutoCloseable { + field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall"; + } + public class MbmsStreamingSession implements java.lang.AutoCloseable { field public static final java.lang.String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; } @@ -5238,6 +5242,7 @@ package android.telephony { method public boolean disableDataConnectivity(); method public boolean enableDataConnectivity(); method public void enableVideoCalling(boolean); + method public java.lang.String getAidForAppType(int); method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int); @@ -5252,6 +5257,8 @@ package android.telephony { method public deprecated boolean getDataEnabled(); method public deprecated boolean getDataEnabled(int); method public boolean getEmergencyCallbackMode(); + method public java.lang.String getIsimDomain(); + method public int getPreferredNetworkType(int); method public int getSimApplicationState(); method public int getSimCardState(); method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms(); @@ -5261,10 +5268,7 @@ package android.telephony { method public boolean handlePinMmi(java.lang.String); method public boolean handlePinMmiForSubscriber(int, java.lang.String); method public boolean isDataConnectivityPossible(); - method public deprecated boolean isIdle(); - method public deprecated boolean isOffhook(); method public deprecated boolean isRadioOn(); - method public deprecated boolean isRinging(); method public boolean isVideoCallingEnabled(); method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle); method public boolean needsOtaServiceProvisioning(); @@ -5278,7 +5282,6 @@ package android.telephony { method public void setSimPowerStateForSlot(int, int); method public deprecated void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean); method public void setVoiceActivationState(int); - method public deprecated void silenceRinger(); method public boolean supplyPin(java.lang.String); method public int[] supplyPinReportResult(java.lang.String); method public boolean supplyPuk(java.lang.String, java.lang.String); @@ -5296,6 +5299,29 @@ package android.telephony { field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE"; field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL"; field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; + field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4 + field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5 + field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6 + field public static final int NETWORK_MODE_GLOBAL = 7; // 0x7 + field public static final int NETWORK_MODE_GSM_ONLY = 1; // 0x1 + field public static final int NETWORK_MODE_GSM_UMTS = 3; // 0x3 + field public static final int NETWORK_MODE_LTE_CDMA_EVDO = 8; // 0x8 + field public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; // 0xa + field public static final int NETWORK_MODE_LTE_GSM_WCDMA = 9; // 0x9 + field public static final int NETWORK_MODE_LTE_ONLY = 11; // 0xb + field public static final int NETWORK_MODE_LTE_TDSCDMA = 15; // 0xf + field public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; // 0x16 + field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; // 0x11 + field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; // 0x14 + field public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; // 0x13 + field public static final int NETWORK_MODE_LTE_WCDMA = 12; // 0xc + field public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; // 0x15 + field public static final int NETWORK_MODE_TDSCDMA_GSM = 16; // 0x10 + field public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; // 0x12 + field public static final int NETWORK_MODE_TDSCDMA_ONLY = 13; // 0xd + field public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14; // 0xe + field public static final int NETWORK_MODE_WCDMA_ONLY = 2; // 0x2 + field public static final int NETWORK_MODE_WCDMA_PREF = 0; // 0x0 field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2 field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1 field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3 @@ -6375,6 +6401,17 @@ package android.telephony.mbms.vendor { method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException; } + public class MbmsGroupCallServiceBase extends android.app.Service { + ctor public MbmsGroupCallServiceBase(); + method public void dispose(int) throws android.os.RemoteException; + method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException; + method public void onAppCallbackDied(int, int); + method public android.os.IBinder onBind(android.content.Intent); + method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback); + method public void stopGroupCall(int, long); + method public void updateGroupCall(int, long, int[], int[]); + } + public class MbmsStreamingServiceBase extends android.os.Binder { ctor public MbmsStreamingServiceBase(); method public void dispose(int) throws android.os.RemoteException; diff --git a/api/system-removed.txt b/api/system-removed.txt index 69ad3ea00018..72b60e2e4db2 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -148,6 +148,10 @@ package android.telephony { public class TelephonyManager { method public deprecated void answerRingingCall(); method public deprecated boolean endCall(); + method public deprecated boolean isIdle(); + method public deprecated boolean isOffhook(); + method public deprecated boolean isRinging(); + method public deprecated void silenceRinger(); } } diff --git a/api/test-current.txt b/api/test-current.txt index 634293ab89e8..a7bb467e6141 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -966,6 +966,10 @@ package android.telephony { field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override"; } + public class MbmsGroupCallSession implements java.lang.AutoCloseable { + field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA = "mbms-group-call-service-override"; + } + public class MbmsStreamingSession implements java.lang.AutoCloseable { field public static final java.lang.String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override"; } @@ -1035,6 +1039,17 @@ package android.telephony.mbms.vendor { method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException; } + public class MbmsGroupCallServiceBase extends android.app.Service { + ctor public MbmsGroupCallServiceBase(); + method public void dispose(int) throws android.os.RemoteException; + method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException; + method public void onAppCallbackDied(int, int); + method public android.os.IBinder onBind(android.content.Intent); + method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback); + method public void stopGroupCall(int, long); + method public void updateGroupCall(int, long, int[], int[]); + } + public class MbmsStreamingServiceBase extends android.os.Binder { ctor public MbmsStreamingServiceBase(); method public void dispose(int) throws android.os.RemoteException; diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 9c94f96596bd..fbf5b5288928 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -2147,27 +2147,20 @@ Lcom/android/internal/telephony/ISub;->getDefaultDataSubId()I Lcom/android/internal/telephony/ISub;->getDefaultSubId()I Lcom/android/internal/telephony/ISub;->setDefaultDataSubId(I)V Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCall()Z -Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCallForSubscriber(I)Z Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String; Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->isRadioOn(Ljava/lang/String;)Z Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->mRemote:Landroid/os/IBinder; Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony; Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String; -Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_answerRingingCall:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I -Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I -Lcom/android/internal/telephony/ITelephony;->answerRingingCall()V Lcom/android/internal/telephony/ITelephony;->call(Ljava/lang/String;Ljava/lang/String;)V Lcom/android/internal/telephony/ITelephony;->dial(Ljava/lang/String;)V Lcom/android/internal/telephony/ITelephony;->disableDataConnectivity()Z Lcom/android/internal/telephony/ITelephony;->disableLocationUpdates()V Lcom/android/internal/telephony/ITelephony;->enableDataConnectivity()Z Lcom/android/internal/telephony/ITelephony;->enableLocationUpdates()V -Lcom/android/internal/telephony/ITelephony;->endCall()Z -Lcom/android/internal/telephony/ITelephony;->endCallForSubscriber(I)Z Lcom/android/internal/telephony/ITelephony;->getActivePhoneType()I Lcom/android/internal/telephony/ITelephony;->getCallState()I Lcom/android/internal/telephony/ITelephony;->getDataActivity()I @@ -2179,12 +2172,8 @@ Lcom/android/internal/telephony/ITelephony;->handlePinMmiForSubscriber(ILjava/la Lcom/android/internal/telephony/ITelephony;->hasIccCard()Z Lcom/android/internal/telephony/ITelephony;->iccCloseLogicalChannel(II)Z Lcom/android/internal/telephony/ITelephony;->iccTransmitApduLogicalChannel(IIIIIIILjava/lang/String;)Ljava/lang/String; -Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z -Lcom/android/internal/telephony/ITelephony;->isIdleForSubscriber(ILjava/lang/String;)Z Lcom/android/internal/telephony/ITelephony;->isRadioOnForSubscriber(ILjava/lang/String;)Z -Lcom/android/internal/telephony/ITelephony;->isRinging(Ljava/lang/String;)Z Lcom/android/internal/telephony/ITelephony;->setRadio(Z)Z -Lcom/android/internal/telephony/ITelephony;->silenceRinger()V Lcom/android/internal/telephony/ITelephony;->supplyPin(Ljava/lang/String;)Z Lcom/android/internal/telephony/ITelephony;->toggleRadioOnOff()V Lcom/android/internal/telephony/ITelephony;->updateServiceLocation()V diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java index 183be5f38bd1..559a59b68b4e 100644 --- a/core/java/android/bluetooth/BluetoothMapClient.java +++ b/core/java/android/bluetooth/BluetoothMapClient.java @@ -73,6 +73,8 @@ public final class BluetoothMapClient implements BluetoothProfile { /** Connection canceled before completion. */ public static final int RESULT_CANCELED = 2; + private static final int UPLOADING_FEATURE_BITMASK = 0x08; + private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback = new IBluetoothStateChangeCallback.Stub() { public void onBluetoothStateChange(boolean up) { @@ -395,6 +397,23 @@ public final class BluetoothMapClient implements BluetoothProfile { return false; } + /** + * Returns the "Uploading" feature bit value from the SDP record's + * MapSupportedFeatures field (see Bluetooth MAP 1.4 spec, page 114). + * @param device The Bluetooth device to get this value for. + * @return Returns true if the Uploading bit value in SDP record's + * MapSupportedFeatures field is set. False is returned otherwise. + */ + public boolean isUploadingSupported(BluetoothDevice device) { + try { + return (mService != null && isEnabled() && isValidDevice(device)) + && ((mService.getSupportedFeatures(device) & UPLOADING_FEATURE_BITMASK) > 0); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + return false; + } + private final ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { if (DBG) Log.d(TAG, "Proxy object connected"); diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java index b591163e8728..f90eab13bbcf 100644 --- a/core/java/com/android/internal/content/FileSystemProvider.java +++ b/core/java/com/android/internal/content/FileSystemProvider.java @@ -236,6 +236,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { displayName = FileUtils.buildValidFatFilename(displayName); final File before = getFileForDocId(docId); + final File beforeVisibleFile = getFileForDocId(docId, true); final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName); if (!before.renameTo(after)) { throw new IllegalStateException("Failed to rename to " + after); @@ -245,7 +246,6 @@ public abstract class FileSystemProvider extends DocumentsProvider { onDocIdChanged(docId); onDocIdChanged(afterDocId); - final File beforeVisibleFile = getFileForDocId(docId, true); final File afterVisibleFile = getFileForDocId(afterDocId, true); moveInMediaStore(beforeVisibleFile, afterVisibleFile); diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 632e4396fab0..477b17e9c34b 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3463,4 +3463,12 @@ <!-- Whether or not swipe up gesture's opt-in setting is available on this device --> <bool name="config_swipe_up_gesture_setting_available">false</bool> + <!-- Pre-scale volume at volume step 1 for Absolute Volume --> + <fraction name="config_prescaleAbsoluteVolume_index1">50%</fraction> + + <!-- Pre-scale volume at volume step 2 for Absolute Volume --> + <fraction name="config_prescaleAbsoluteVolume_index2">70%</fraction> + + <!-- Pre-scale volume at volume step 3 for Absolute Volume --> + <fraction name="config_prescaleAbsoluteVolume_index3">85%</fraction> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index de5dc43d6843..e9a54f1d7739 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3393,4 +3393,9 @@ <java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" /> <java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" /> + + <!-- For Bluetooth AbsoluteVolume --> + <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" /> + <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index2" /> + <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index3" /> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index 541877cc28ca..3c5816096f8c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -105,7 +105,7 @@ public class A2dpProfile implements LocalBluetoothProfile { BluetoothProfile.A2DP); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java index 0e0f63cb084c..656f23ffb70c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java @@ -99,7 +99,7 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { BluetoothProfile.A2DP_SINK); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index e96c44db695b..8fa95977c5ce 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -250,7 +250,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> int preferredProfiles = 0; for (LocalBluetoothProfile profile : mProfiles) { - if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) { + if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) { if (profile.isPreferred(mDevice)) { ++preferredProfiles; connectInt(profile); @@ -736,7 +736,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> List<LocalBluetoothProfile> connectableProfiles = new ArrayList<LocalBluetoothProfile>(); for (LocalBluetoothProfile profile : mProfiles) { - if (profile.isConnectable()) { + if (profile.accessProfileEnabled()) { connectableProfiles.add(profile); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java index 7f838600c5ee..3bb8450207ab 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java @@ -106,7 +106,7 @@ public class HeadsetProfile implements LocalBluetoothProfile { BluetoothProfile.HEADSET); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index 1d2fda94deaa..06d60e6e9d47 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -103,7 +103,7 @@ public class HearingAidProfile implements LocalBluetoothProfile { BluetoothProfile.HEARING_AID); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return false; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java index 0857b019ee64..4ae9b328edaa 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java @@ -107,7 +107,7 @@ final class HfpClientProfile implements LocalBluetoothProfile { } @Override - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java index af78c6faae24..1c04e83f771e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java @@ -97,7 +97,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } @Override - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java index dc17e44cb08d..1e064818cc72 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java @@ -95,7 +95,7 @@ public class HidProfile implements LocalBluetoothProfile { BluetoothProfile.HID_HOST); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java index 0447f378fca1..4b0ca7434f9a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java @@ -26,9 +26,9 @@ import android.bluetooth.BluetoothDevice; public interface LocalBluetoothProfile { /** - * Returns true if the user can initiate a connection, false otherwise. + * Return {@code true} if the user can initiate a connection for this profile in UI. */ - boolean isConnectable(); + boolean accessProfileEnabled(); /** * Returns true if the user can enable auto connection for this profile. diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java index e9fcc119d5d8..57712e3cbb28 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java @@ -108,7 +108,7 @@ public final class MapClientProfile implements LocalBluetoothProfile { BluetoothProfile.MAP_CLIENT); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java index 511c4ce678e2..e59a036731d9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java @@ -107,7 +107,7 @@ public class MapProfile implements LocalBluetoothProfile { BluetoothProfile.MAP); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java index dfd16224ef8f..e1e5dbe29a1a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java @@ -32,7 +32,7 @@ final class OppProfile implements LocalBluetoothProfile { // Order of this profile in device profiles list private static final int ORDINAL = 2; - public boolean isConnectable() { + public boolean accessProfileEnabled() { return false; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java index b18b19b1e244..0d566c77eac2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java @@ -80,7 +80,7 @@ public class PanProfile implements LocalBluetoothProfile { BluetoothProfile.PAN); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java index fc54775cc9a2..c83ff359b138 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java @@ -110,7 +110,7 @@ public final class PbapClientProfile implements LocalBluetoothProfile { BluetoothProfile.PBAP_CLIENT); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java index e9d8cb5a4b2b..adef0841cb2a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java @@ -80,7 +80,7 @@ public class PbapServerProfile implements LocalBluetoothProfile { BluetoothPbap pbap = new BluetoothPbap(context, new PbapServiceListener()); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java index 2c455d5f4c32..f7cd39372e11 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java @@ -106,7 +106,7 @@ final class SapProfile implements LocalBluetoothProfile { BluetoothProfile.SAP); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 9e4810cb08ca..35abb0a523a1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -342,12 +342,11 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe case SimPuk: // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); - if (securityMode != SecurityMode.None - || !mLockPatternUtils.isLockScreenDisabled( + if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser())) { - showSecurityScreen(securityMode); - } else { finish = true; + } else { + showSecurityScreen(securityMode); } break; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 0b9832d90f7d..6fa17d8d5c01 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -627,6 +627,13 @@ public class AudioService extends IAudioService.Stub // If absolute volume is supported in AVRCP device private boolean mAvrcpAbsVolSupported = false; + // Pre-scale for Bluetooth Absolute Volume + private float[] mPrescaleAbsoluteVolume = new float[] { + 0.5f, // Pre-scale for index 1 + 0.7f, // Pre-scale for index 2 + 0.85f, // Pre-scale for index 3 + }; + private static Long mLastDeviceConnectMsgTime = new Long(0); private NotificationManager mNm; @@ -878,6 +885,23 @@ public class AudioService extends IAudioService.Stub mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); mRecordMonitor.initMonitor(); + + final float[] preScale = new float[3]; + preScale[0] = mContext.getResources().getFraction( + com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, + 1, 1); + preScale[1] = mContext.getResources().getFraction( + com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, + 1, 1); + preScale[2] = mContext.getResources().getFraction( + com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, + 1, 1); + for (int i = 0; i < preScale.length; i++) { + if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { + mPrescaleAbsoluteVolume[i] = preScale[i]; + } + } + } public void systemReady() { @@ -4879,18 +4903,12 @@ public class AudioService extends IAudioService.Stub if (index == 0) { // 0% for volume 0 index = 0; - } else if (index == 1) { - // 50% for volume 1 - index = (int)(mIndexMax * 0.5) /10; - } else if (index == 2) { - // 70% for volume 2 - index = (int)(mIndexMax * 0.70) /10; - } else if (index == 3) { - // 85% for volume 3 - index = (int)(mIndexMax * 0.85) /10; + } else if (index > 0 && index <= 3) { + // Pre-scale for volume steps 1 2 and 3 + index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10; } else { // otherwise, full gain - index = (mIndexMax + 5)/10; + index = (mIndexMax + 5) / 10; } return index; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 271d205cb69b..fae4db9a81de 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17529,7 +17529,8 @@ public class PackageManagerService extends IPackageManager.Stub // Prepare the application profiles for the new code paths. // This needs to be done before invoking dexopt so that any install-time profile // can be used for optimizations. - mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier())); + mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()), + /* updateReferenceProfileContent= */ true); // Check whether we need to dexopt the app. // @@ -22606,8 +22607,18 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); // // We also have to cover non system users because we do not call the usual install package // methods for them. + // + // NOTE: in order to speed up first boot time we only create the current profile and do not + // update the content of the reference profile. A system image should already be configured + // with the right profile keys and the profiles for the speed-profile prebuilds should + // already be copied. That's done in #performDexOptUpgrade. + // + // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of + // manually copying them in #performDexOptUpgrade. When we do that we should have a more + // granular check here and only update the existing profiles. if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) { - mArtManagerService.prepareAppProfiles(pkg, userId); + mArtManagerService.prepareAppProfiles(pkg, userId, + /* updateReferenceProfileContent= */ false); } if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 0ba78226a38f..833cc5bd91f2 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -389,7 +389,8 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { * - create the current primary profile to save time at app startup time. * - copy the profiles from the associated dex metadata file to the reference profile. */ - public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user) { + public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user, + boolean updateReferenceProfileContent) { final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); if (user < 0) { Slog.wtf(TAG, "Invalid user id: " + user); @@ -404,8 +405,14 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { for (int i = codePathsProfileNames.size() - 1; i >= 0; i--) { String codePath = codePathsProfileNames.keyAt(i); String profileName = codePathsProfileNames.valueAt(i); - File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath)); - String dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath(); + String dexMetadataPath = null; + // Passing the dex metadata file to the prepare method will update the reference + // profile content. As such, we look for the dex metadata file only if we need to + // perform an update. + if (updateReferenceProfileContent) { + File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath)); + dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath(); + } synchronized (mInstaller) { boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId, profileName, codePath, dexMetadataPath); @@ -423,9 +430,10 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { /** * Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}. */ - public void prepareAppProfiles(PackageParser.Package pkg, int[] user) { + public void prepareAppProfiles(PackageParser.Package pkg, int[] user, + boolean updateReferenceProfileContent) { for (int i = 0; i < user.length; i++) { - prepareAppProfiles(pkg, user[i]); + prepareAppProfiles(pkg, user[i], updateReferenceProfileContent); } } diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java index f7bf393f367b..5a73a4e492ee 100644 --- a/services/net/java/android/net/util/SharedLog.java +++ b/services/net/java/android/net/util/SharedLog.java @@ -17,6 +17,7 @@ package android.net.util; import android.annotation.NonNull; +import android.annotation.Nullable; import android.text.TextUtils; import android.util.LocalLog; import android.util.Log; @@ -92,10 +93,17 @@ public class SharedLog { } /** - * Log an error due to an exception, with the exception stacktrace. + * Log an error due to an exception, with the exception stacktrace if provided. + * + * <p>The error and exception message appear in the shared log, but the stacktrace is only + * logged in general log output (logcat). */ - public void e(@NonNull String msg, @NonNull Throwable e) { - Log.e(mTag, record(Category.ERROR, msg + ": " + e.getMessage()), e); + public void e(@NonNull String msg, @Nullable Throwable exception) { + if (exception == null) { + e(msg); + return; + } + Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception); } public void i(String msg) { diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 26bd4a106ca6..08bc9bcc4003 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -141,6 +141,8 @@ public final class Call { * The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to * Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_REQUEST_HANDOVER = "android.telecom.event.REQUEST_HANDOVER"; @@ -149,6 +151,8 @@ public final class Call { * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the * {@link PhoneAccountHandle} to which a call should be handed over to. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE"; @@ -161,6 +165,8 @@ public final class Call { * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and * {@link VideoProfile#STATE_TX_ENABLED}. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EXTRA_HANDOVER_VIDEO_STATE = "android.telecom.extra.HANDOVER_VIDEO_STATE"; @@ -176,6 +182,8 @@ public final class Call { * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} * is called to initate the handover. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS"; @@ -186,6 +194,8 @@ public final class Call { * <p> * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_COMPLETE = "android.telecom.event.HANDOVER_COMPLETE"; @@ -198,6 +208,8 @@ public final class Call { * <p> * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED = "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED"; @@ -209,6 +221,8 @@ public final class Call { * <p> * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_FAILED = "android.telecom.event.HANDOVER_FAILED"; diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index dbaea85e9224..ee1ca5f120e8 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -593,6 +593,8 @@ public abstract class Connection extends Conferenceable { * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has * successfully completed. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_COMPLETE = "android.telecom.event.HANDOVER_COMPLETE"; @@ -602,6 +604,8 @@ public abstract class Connection extends Conferenceable { * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has failed * to complete. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_FAILED = "android.telecom.event.HANDOVER_FAILED"; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 2d1b6adc8126..d8743bcfd21d 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -2116,6 +2116,16 @@ public class CarrierConfigManager { public static final String KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING = "call_redirection_service_component_name_string"; + /** + * Flag specifying whether to show notification(call blocking disabled) when Enhanced Call + * Blocking(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL) is enabled and making emergency call. + * When true, notification is shown always. + * When false, notification is shown only when any setting of "Enhanced Blocked number" is + * enabled. + */ + public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = + "show_call_blocking_disabled_notification_always_bool"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -2454,6 +2464,7 @@ public class CarrierConfigManager { }); sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, ""); sDefaults.putBoolean(KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL, false); + sDefaults.putBoolean(KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL, false); } /** diff --git a/telephony/java/android/telephony/MbmsGroupCallSession.java b/telephony/java/android/telephony/MbmsGroupCallSession.java new file mode 100644 index 000000000000..e3737976adf7 --- /dev/null +++ b/telephony/java/android/telephony/MbmsGroupCallSession.java @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2018 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 android.telephony; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.content.ComponentName; +import android.content.Context; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; +import android.telephony.mbms.GroupCall; +import android.telephony.mbms.GroupCallCallback; +import android.telephony.mbms.InternalGroupCallCallback; +import android.telephony.mbms.InternalGroupCallSessionCallback; +import android.telephony.mbms.MbmsErrors; +import android.telephony.mbms.MbmsGroupCallSessionCallback; +import android.telephony.mbms.MbmsUtils; +import android.telephony.mbms.vendor.IMbmsGroupCallService; +import android.util.ArraySet; +import android.util.Log; + +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +/** + * This class provides functionality for accessing group call functionality over MBMS. + */ +public class MbmsGroupCallSession implements AutoCloseable { + private static final String LOG_TAG = "MbmsGroupCallSession"; + + /** + * Service action which must be handled by the middleware implementing the MBMS group call + * interface. + * @hide + */ + @SystemApi + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) + public static final String MBMS_GROUP_CALL_SERVICE_ACTION = + "android.telephony.action.EmbmsGroupCall"; + + /** + * Metadata key that specifies the component name of the service to bind to for group calls. + * @hide + */ + @TestApi + public static final String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA = + "mbms-group-call-service-override"; + + private static AtomicBoolean sIsInitialized = new AtomicBoolean(false); + + private AtomicReference<IMbmsGroupCallService> mService = new AtomicReference<>(null); + private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { + @Override + public void binderDied() { + sIsInitialized.set(false); + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Received death notification"); + } + }; + + private InternalGroupCallSessionCallback mInternalCallback; + private Set<GroupCall> mKnownActiveGroupCalls = new ArraySet<>(); + + private final Context mContext; + private int mSubscriptionId; + + /** @hide */ + private MbmsGroupCallSession(Context context, Executor executor, int subscriptionId, + MbmsGroupCallSessionCallback callback) { + mContext = context; + mSubscriptionId = subscriptionId; + mInternalCallback = new InternalGroupCallSessionCallback(callback, executor); + } + + /** + * Create a new {@link MbmsGroupCallSession} using the given subscription ID. + * + * You may only have one instance of {@link MbmsGroupCallSession} per UID. If you call this + * method while there is an active instance of {@link MbmsGroupCallSession} in your process + * (in other words, one that has not had {@link #close()} called on it), this method will + * throw an {@link IllegalStateException}. If you call this method in a different process + * running under the same UID, an error will be indicated via + * {@link MbmsGroupCallSessionCallback#onError(int, String)}. + * + * Note that initialization may fail asynchronously. If you wish to try again after you + * receive such an asynchronous error, you must call {@link #close()} on the instance of + * {@link MbmsGroupCallSession} that you received before calling this method again. + * + * @param context The {@link Context} to use. + * @param executor The executor on which you wish to execute callbacks. + * @param subscriptionId The subscription ID to use. + * @param callback A callback object on which you wish to receive results of asynchronous + * operations. + * @return An instance of {@link MbmsGroupCallSession}, or null if an error occurred. + */ + public static @Nullable MbmsGroupCallSession create(@NonNull Context context, + @NonNull Executor executor, int subscriptionId, + final @NonNull MbmsGroupCallSessionCallback callback) { + if (!sIsInitialized.compareAndSet(false, true)) { + throw new IllegalStateException("Cannot create two instances of MbmsGroupCallSession"); + } + MbmsGroupCallSession session = new MbmsGroupCallSession(context, executor, + subscriptionId, callback); + + final int result = session.bindAndInitialize(); + if (result != MbmsErrors.SUCCESS) { + sIsInitialized.set(false); + executor.execute(new Runnable() { + @Override + public void run() { + callback.onError(result, null); + } + }); + return null; + } + return session; + } + + /** + * Create a new {@link MbmsGroupCallSession} using the system default data subscription ID. + * See {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)}. + */ + public static MbmsGroupCallSession create(@NonNull Context context, + @NonNull Executor executor, @NonNull MbmsGroupCallSessionCallback callback) { + return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback); + } + + /** + * Terminates this instance. Also terminates + * any group calls spawned from this instance as if + * {@link GroupCall#close()} had been called on them. After this method returns, + * no further callbacks originating from the middleware will be enqueued on the provided + * instance of {@link MbmsGroupCallSessionCallback}, but callbacks that have already been + * enqueued will still be delivered. + * + * It is safe to call {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)} to + * obtain another instance of {@link MbmsGroupCallSession} immediately after this method + * returns. + * + * May throw an {@link IllegalStateException} + */ + public void close() { + try { + IMbmsGroupCallService groupCallService = mService.get(); + if (groupCallService == null) { + // Ignore and return, assume already disposed. + return; + } + groupCallService.dispose(mSubscriptionId); + for (GroupCall s : mKnownActiveGroupCalls) { + s.getCallback().stop(); + } + mKnownActiveGroupCalls.clear(); + } catch (RemoteException e) { + // Ignore for now + } finally { + mService.set(null); + sIsInitialized.set(false); + mInternalCallback.stop(); + } + } + + /** + * Starts the requested group call, reporting status to the indicated callback. + * Returns an object used to control that call. + * + * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException} + * + * Asynchronous errors through the callback include any of the errors in + * {@link MbmsErrors.GeneralErrors}. + * + * @param executor The executor on which you wish to execute callbacks for this stream. + * @param tmgi The TMGI, an identifier for the group call you want to join. + * @param saiArray An array of SAIs for the group call that should be negotiated separately with + * the carrier. + * @param frequencyArray An array of frequencies for the group call that should be negotiated + * separately with the carrier. + * @param callback The callback that you want to receive information about the call on. + * @return An instance of {@link GroupCall} through which the call can be controlled. + * May be {@code null} if an error occurred. + */ + public @Nullable GroupCall startGroupCall(@NonNull Executor executor, long tmgi, int[] saiArray, + int[] frequencyArray, @NonNull GroupCallCallback callback) { + IMbmsGroupCallService groupCallService = mService.get(); + if (groupCallService == null) { + throw new IllegalStateException("Middleware not yet bound"); + } + + InternalGroupCallCallback serviceCallback = new InternalGroupCallCallback( + callback, executor); + + GroupCall serviceForApp = new GroupCall(mSubscriptionId, + groupCallService, this, tmgi, serviceCallback); + mKnownActiveGroupCalls.add(serviceForApp); + + try { + int returnCode = groupCallService.startGroupCall( + mSubscriptionId, tmgi, saiArray, frequencyArray, serviceCallback); + if (returnCode == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return an unknown error code"); + } + if (returnCode != MbmsErrors.SUCCESS) { + mInternalCallback.onError(returnCode, null); + return null; + } + } catch (RemoteException e) { + Log.w(LOG_TAG, "Remote process died"); + mService.set(null); + sIsInitialized.set(false); + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); + return null; + } + + return serviceForApp; + } + + /** @hide */ + public void onGroupCallStopped(GroupCall service) { + mKnownActiveGroupCalls.remove(service); + } + + private int bindAndInitialize() { + return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION, + new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsGroupCallService groupCallService = + IMbmsGroupCallService.Stub.asInterface(service); + int result; + try { + result = groupCallService.initialize(mInternalCallback, + mSubscriptionId); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return" + + " an unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + mInternalCallback.onError(result, + "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + groupCallService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(groupCallService); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + sIsInitialized.set(false); + mService.set(null); + } + }); + } +} diff --git a/telephony/java/android/telephony/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java index 7c7d7a0397ad..202da6817cb5 100644 --- a/telephony/java/android/telephony/NetworkScan.java +++ b/telephony/java/android/telephony/NetworkScan.java @@ -16,11 +16,10 @@ package android.telephony; +import android.annotation.IntDef; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; -import android.annotation.IntDef; -import android.util.Log; import com.android.internal.telephony.ITelephony; @@ -113,6 +112,8 @@ public class NetworkScan { } try { telephony.stopNetworkScan(mSubId, mScanId); + } catch (IllegalArgumentException ex) { + Rlog.d(TAG, "stopNetworkScan - no active scan for ScanID=" + mScanId); } catch (RemoteException ex) { Rlog.e(TAG, "stopNetworkScan RemoteException", ex); } catch (RuntimeException ex) { diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index ec266229b83a..22c1e58449de 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -33,11 +33,13 @@ import android.graphics.Typeface; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import java.util.Arrays; import java.util.List; +import java.util.Objects; /** * A Parcelable class for Subscription Information. @@ -552,11 +554,49 @@ public class SubscriptionInfo implements Parcelable { String cardIdToPrint = givePrintableIccid(mCardId); return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex + " displayName=" + mDisplayName + " carrierName=" + mCarrierName - + " nameSource=" + mNameSource + " iconTint=" + mIconTint + + " nameSource=" + mNameSource + " iconTint=" + mIconTint + " mNumber=" + mNumber + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc - + " mnc " + mMnc + " isEmbedded " + mIsEmbedded + + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded + " accessRules " + Arrays.toString(mAccessRules) + " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic + " parentSubId=" + mParentSubId + "}"; } -} + + @Override + public int hashCode() { + return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded, + mIsOpportunistic, mParentSubId, mIccId, mNumber, mMcc, mMnc, mCountryIso, + mCardId, mDisplayName, mCarrierName, mAccessRules); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj == this) return true; + + SubscriptionInfo toCompare; + try { + toCompare = (SubscriptionInfo) obj; + } catch (ClassCastException ex) { + return false; + } + + return mId == toCompare.mId + && mSimSlotIndex == toCompare.mSimSlotIndex + && mNameSource == toCompare.mNameSource + && mIconTint == toCompare.mIconTint + && mDataRoaming == toCompare.mDataRoaming + && mIsEmbedded == toCompare.mIsEmbedded + && mIsOpportunistic == toCompare.mIsOpportunistic + && mParentSubId == toCompare.mParentSubId + && Objects.equals(mIccId, toCompare.mIccId) + && Objects.equals(mNumber, toCompare.mNumber) + && Objects.equals(mMcc, toCompare.mMcc) + && Objects.equals(mMnc, toCompare.mMnc) + && Objects.equals(mCountryIso, toCompare.mCountryIso) + && Objects.equals(mCardId, toCompare.mCardId) + && TextUtils.equals(mDisplayName, toCompare.mDisplayName) + && TextUtils.equals(mCarrierName, toCompare.mCarrierName) + && Arrays.equals(mAccessRules, toCompare.mAccessRules); + } +}
\ No newline at end of file diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 8f7993cc7251..3ef80c2efcb5 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -1847,6 +1847,19 @@ public class SubscriptionManager { } /** + * Checks if the supplied subscription ID corresponds to an active subscription. + * + * @param subscriptionId the subscription ID. + * @return {@code true} if the supplied subscription ID corresponds to an active subscription; + * {@code false} if it does not correspond to an active subscription; or throw a + * SecurityException if the caller hasn't got the right permission. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public boolean isActiveSubscriptionId(int subscriptionId) { + return isActiveSubId(subscriptionId); + } + + /** * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription * and the SIM providing the subscription is present in a slot and in "LOADED" state. * @hide @@ -1856,7 +1869,7 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - return iSub.isActiveSubId(subId); + return iSub.isActiveSubId(subId, mContext.getOpPackageName()); } } catch (RemoteException ex) { } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 7f27009205c4..92030efb1a28 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -16,6 +16,8 @@ package android.telephony; +import static android.content.Context.TELECOM_SERVICE; + import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntDef; @@ -2089,10 +2091,37 @@ public class TelephonyManager { /** Max network type number. Update as new types are added. Don't add negative types. {@hide} */ public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_LTE_CA; + + /** @hide */ + @IntDef({ + NETWORK_TYPE_UNKNOWN, + NETWORK_TYPE_GPRS, + NETWORK_TYPE_EDGE, + NETWORK_TYPE_UMTS, + NETWORK_TYPE_CDMA, + NETWORK_TYPE_EVDO_0, + NETWORK_TYPE_EVDO_A, + NETWORK_TYPE_1xRTT, + NETWORK_TYPE_HSDPA, + NETWORK_TYPE_HSUPA, + NETWORK_TYPE_HSPA, + NETWORK_TYPE_IDEN, + NETWORK_TYPE_EVDO_B, + NETWORK_TYPE_LTE, + NETWORK_TYPE_EHRPD, + NETWORK_TYPE_HSPAP, + NETWORK_TYPE_GSM, + NETWORK_TYPE_TD_SCDMA, + NETWORK_TYPE_IWLAN, + NETWORK_TYPE_LTE_CA, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NetworkType{} + /** * @return the NETWORK_TYPE_xxxx for current data connection. */ - public int getNetworkType() { + public @NetworkType int getNetworkType() { try { ITelephony telephony = getITelephony(); if (telephony != null) { @@ -2137,24 +2166,24 @@ public class TelephonyManager { * @hide */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - @UnsupportedAppUsage - public int getNetworkType(int subId) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName()); - } else { - // This can happen when the ITelephony interface is not up yet. - return NETWORK_TYPE_UNKNOWN; - } - } catch(RemoteException ex) { - // This shouldn't happen in the normal case - return NETWORK_TYPE_UNKNOWN; - } catch (NullPointerException ex) { - // This could happen before phone restarts due to crashing - return NETWORK_TYPE_UNKNOWN; - } - } + @UnsupportedAppUsage + public int getNetworkType(int subId) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName()); + } else { + // This can happen when the ITelephony interface is not up yet. + return NETWORK_TYPE_UNKNOWN; + } + } catch (RemoteException ex) { + // This shouldn't happen in the normal case + return NETWORK_TYPE_UNKNOWN; + } catch (NullPointerException ex) { + // This could happen before phone restarts due to crashing + return NETWORK_TYPE_UNKNOWN; + } + } /** * Returns a constant indicating the radio technology (network type) @@ -2187,7 +2216,7 @@ public class TelephonyManager { */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public int getDataNetworkType() { + public @NetworkType int getDataNetworkType() { return getDataNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId())); } @@ -2227,7 +2256,7 @@ public class TelephonyManager { */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public int getVoiceNetworkType() { + public @NetworkType int getVoiceNetworkType() { return getVoiceNetworkType(getSubId()); } @@ -4139,11 +4168,16 @@ public class TelephonyManager { } /** - * Returns the IMS home network domain name that was loaded from the ISIM. - * @return the IMS domain name, or null if not present or not loaded + * Returns the IMS home network domain name that was loaded from the ISIM {@see #APPTYPE_ISIM}. + * @return the IMS domain name. Returns {@code null} if ISIM hasn't been loaded or IMS domain + * hasn't been loaded or isn't present on the ISIM. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} * @hide */ - @UnsupportedAppUsage + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain() { try { IPhoneSubInfo info = getSubscriberInfo(); @@ -4371,7 +4405,7 @@ public class TelephonyManager { * @hide */ private ITelecomService getTelecomService() { - return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE)); + return ITelecomService.Stub.asInterface(ServiceManager.getService(TELECOM_SERVICE)); } private ITelephonyRegistry getTelephonyRegistry() { @@ -5397,7 +5431,19 @@ public class TelephonyManager { } } - // ICC SIM Application Types + /** + * UICC SIM Application Types + * @hide + */ + @IntDef(prefix = { "APPTYPE_" }, value = { + APPTYPE_SIM, + APPTYPE_USIM, + APPTYPE_RUIM, + APPTYPE_CSIM, + APPTYPE_ISIM + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UiccAppType{} /** UICC application type is SIM */ public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM; /** UICC application type is USIM */ @@ -5408,6 +5454,7 @@ public class TelephonyManager { public static final int APPTYPE_CSIM = PhoneConstants.APPTYPE_CSIM; /** UICC application type is ISIM */ public static final int APPTYPE_ISIM = PhoneConstants.APPTYPE_ISIM; + // authContext (parameter P2) when doing UICC challenge, // per 3GPP TS 31.102 (Section 7.1.2) /** Authentication type for UICC challenge is EAP SIM. See RFC 4186 for details. */ @@ -5691,6 +5738,203 @@ public class TelephonyManager { } } + /** @hide */ + @IntDef(prefix = { "NETWORK_MODE_" }, value = { + NETWORK_MODE_WCDMA_PREF, + NETWORK_MODE_GSM_ONLY, + NETWORK_MODE_WCDMA_ONLY, + NETWORK_MODE_GSM_UMTS, + NETWORK_MODE_CDMA_EVDO, + NETWORK_MODE_CDMA_NO_EVDO, + NETWORK_MODE_EVDO_NO_CDMA, + NETWORK_MODE_GLOBAL, + NETWORK_MODE_LTE_CDMA_EVDO, + NETWORK_MODE_LTE_GSM_WCDMA, + NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA, + NETWORK_MODE_LTE_ONLY, + NETWORK_MODE_LTE_WCDMA, + NETWORK_MODE_TDSCDMA_ONLY, + NETWORK_MODE_TDSCDMA_WCDMA, + NETWORK_MODE_LTE_TDSCDMA, + NETWORK_MODE_TDSCDMA_GSM, + NETWORK_MODE_LTE_TDSCDMA_GSM, + NETWORK_MODE_TDSCDMA_GSM_WCDMA, + NETWORK_MODE_LTE_TDSCDMA_WCDMA, + NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA, + NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA, + NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA + }) + @Retention(RetentionPolicy.SOURCE) + public @interface PrefNetworkMode{} + + /** + * network mode is GSM/WCDMA (WCDMA preferred). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF; + + /** + * network mode is GSM only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY; + + /** + * network mode is WCDMA only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY; + + /** + * network mode is GSM/WCDMA (auto mode, according to PRL). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS; + + /** + * network mode is CDMA and EvDo (auto mode, according to PRL). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_CDMA_EVDO = RILConstants.NETWORK_MODE_CDMA; + + /** + * network mode is CDMA only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO; + + /** + * network mode is EvDo only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA; + + /** + * network mode is GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL; + + /** + * network mode is LTE, CDMA and EvDo. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_CDMA_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO; + + /** + * preferred network mode is LTE, GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA; + + /** + * network mode is LTE, CDMA, EvDo, GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; + + /** + * network mode is LTE Only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY; + + /** + * network mode is LTE/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_WCDMA = RILConstants.NETWORK_MODE_LTE_WCDMA; + + /** + * network mode is TD-SCDMA only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_ONLY = RILConstants.NETWORK_MODE_TDSCDMA_ONLY; + + /** + * network mode is TD-SCDMA and WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA; + + /** + * network mode is TD-SCDMA and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA; + + /** + * network mode is TD-SCDMA and GSM. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_TDSCDMA_GSM; + + /** + * network mode is TD-SCDMA,GSM and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; + + /** + * network mode is TD-SCDMA, GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = + RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; + + /** + * network mode is TD-SCDMA, WCDMA and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; + + /** + * network mode is TD-SCDMA, GSM/WCDMA and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; + + /** + * network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; + + /** + * network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; + /** * Get the preferred network type. * Used for device configuration by some CDMA operators. @@ -5699,11 +5943,12 @@ public class TelephonyManager { * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). * - * @return the preferred network type, defined in RILConstants.java. + * @return the preferred network type. * @hide */ - @UnsupportedAppUsage - public int getPreferredNetworkType(int subId) { + @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE)) + @SystemApi + public @PrefNetworkMode int getPreferredNetworkType(int subId) { try { ITelephony telephony = getITelephony(); if (telephony != null) @@ -6285,7 +6530,7 @@ public class TelephonyManager { } /** - * @deprecated Use {@link android.telecom.TelecomManager#endCall()} instead. + * @removed Use {@link android.telecom.TelecomManager#endCall()} instead. * @hide * @removed */ @@ -6297,7 +6542,7 @@ public class TelephonyManager { } /** - * @deprecated Use {@link android.telecom.TelecomManager#acceptRingingCall} instead + * @removed Use {@link android.telecom.TelecomManager#acceptRingingCall} instead * @hide * @removed */ @@ -6305,26 +6550,22 @@ public class TelephonyManager { @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall() { - + // No-op } /** - * @deprecated Use {@link android.telecom.TelecomManager#silenceRinger} instead + * @removed Use {@link android.telecom.TelecomManager#silenceRinger} instead * @hide */ @Deprecated @SystemApi @SuppressLint("Doclava125") public void silenceRinger() { - try { - getTelecomService().silenceRinger(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelecomService#silenceRinger", e); - } + // No-op } /** - * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead + * @removed Use {@link android.telecom.TelecomManager#isInCall} instead * @hide */ @Deprecated @@ -6334,18 +6575,11 @@ public class TelephonyManager { android.Manifest.permission.READ_PHONE_STATE }) public boolean isOffhook() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.isOffhook(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#isOffhook", e); - } return false; } /** - * @deprecated Use {@link android.telecom.TelecomManager#isRinging} instead + * @removed Use {@link android.telecom.TelecomManager#isRinging} instead * @hide */ @Deprecated @@ -6355,18 +6589,11 @@ public class TelephonyManager { android.Manifest.permission.READ_PHONE_STATE }) public boolean isRinging() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.isRinging(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#isRinging", e); - } return false; } /** - * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead + * @removed Use {@link android.telecom.TelecomManager#isInCall} instead * @hide */ @Deprecated @@ -6376,13 +6603,6 @@ public class TelephonyManager { android.Manifest.permission.READ_PHONE_STATE }) public boolean isIdle() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.isIdle(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#isIdle", e); - } return true; } @@ -7868,26 +8088,23 @@ public class TelephonyManager { } /** - * Return the application ID for the app type like {@link APPTYPE_CSIM}. - * - * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission + * Return the application ID for the uicc application type like {@link #APPTYPE_CSIM}. + * All uicc applications are uniquely identified by application ID. See ETSI 102.221 and 101.220 + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} * - * @param appType the uicc app type like {@link APPTYPE_CSIM} - * @return Application ID for specificied app type or null if no uicc or error. + * @param appType the uicc app type. + * @return Application ID for specified app type or {@code null} if no uicc or error. * @hide */ - public String getAidForAppType(int appType) { + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public String getAidForAppType(@UiccAppType int appType) { return getAidForAppType(getSubId(), appType); } /** - * Return the application ID for the app type like {@link APPTYPE_CSIM}. - * - * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission - * - * @param subId the subscription ID that this request applies to. - * @param appType the uicc app type, like {@link APPTYPE_CSIM} - * @return Application ID for specificied app type or null if no uicc or error. + * same as {@link #getAidForAppType(int)} * @hide */ public String getAidForAppType(int subId, int appType) { diff --git a/telephony/java/android/telephony/mbms/GroupCall.java b/telephony/java/android/telephony/mbms/GroupCall.java new file mode 100644 index 000000000000..9aca18e07812 --- /dev/null +++ b/telephony/java/android/telephony/mbms/GroupCall.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2018 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 android.telephony.mbms; + +import android.annotation.IntDef; +import android.os.RemoteException; +import android.telephony.MbmsGroupCallSession; +import android.telephony.mbms.vendor.IMbmsGroupCallService; +import android.util.Log; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Class used to represent a single MBMS group call. After a call has been started with + * {@link MbmsGroupCallSession#startGroupCall}, + * this class is used to hold information about the call and control it. + */ +public class GroupCall implements AutoCloseable { + private static final String LOG_TAG = "MbmsGroupCall"; + + /** + * The state of a group call, reported via + * {@link GroupCallCallback#onGroupCallStateChanged(int, int)} + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "STATE_" }, value = {STATE_STOPPED, STATE_STARTED, STATE_STALLED}) + public @interface GroupCallState {} + public static final int STATE_STOPPED = 1; + public static final int STATE_STARTED = 2; + public static final int STATE_STALLED = 3; + + /** + * The reason for a call state change, reported via + * {@link GroupCallCallback#onGroupCallStateChanged(int, int)} + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "REASON_" }, + value = {REASON_BY_USER_REQUEST, REASON_FREQUENCY_CONFLICT, + REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE, + REASON_LEFT_MBMS_BROADCAST_AREA, REASON_NONE}) + public @interface GroupCallStateChangeReason {} + + /** + * Indicates that the middleware does not have a reason to provide for the state change. + */ + public static final int REASON_NONE = 0; + + /** + * State changed due to a call to {@link #close()} or + * {@link MbmsGroupCallSession#startGroupCall} + */ + public static final int REASON_BY_USER_REQUEST = 1; + + // 2 is unused to match up with streaming. + + /** + * State changed due to a frequency conflict with another requested call. + */ + public static final int REASON_FREQUENCY_CONFLICT = 3; + + /** + * State changed due to the middleware running out of memory + */ + public static final int REASON_OUT_OF_MEMORY = 4; + + /** + * State changed due to the device leaving the home carrier's LTE network. + */ + public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; + + /** + * State changed due to the device leaving the area where this call is being broadcast. + */ + public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6; + + private final int mSubscriptionId; + private final long mTmgi; + private final MbmsGroupCallSession mParentSession; + private final InternalGroupCallCallback mCallback; + private IMbmsGroupCallService mService; + + /** + * @hide + */ + public GroupCall(int subscriptionId, + IMbmsGroupCallService service, + MbmsGroupCallSession session, + long tmgi, + InternalGroupCallCallback callback) { + mSubscriptionId = subscriptionId; + mParentSession = session; + mService = service; + mTmgi = tmgi; + mCallback = callback; + } + + /** + * Retrieve the TMGI (Temporary Mobile Group Identity) corresponding to this call. + */ + public long getTmgi() { + return mTmgi; + } + + /** + * Send an update to the middleware when the SAI (Service Area Identifier) list and frequency + * information of the group call has * changed. Callers must obtain this information from the + * wireless carrier independently. + * @param saiArray New array of SAIs that the call is available on. + * @param frequencyArray New array of frequencies that the call is available on. + */ + public void updateGroupCall(int[] saiArray, int[] frequencyArray) { + if (mService == null) { + throw new IllegalStateException("No group call service attached"); + } + + try { + mService.updateGroupCall(mSubscriptionId, mTmgi, saiArray, frequencyArray); + } catch (RemoteException e) { + Log.w(LOG_TAG, "Remote process died"); + mService = null; + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); + } finally { + mParentSession.onGroupCallStopped(this); + } + } + + /** + * Stop this group call. Further operations on this object will fail with an + * {@link IllegalStateException}. + * + * May throw an {@link IllegalStateException} + */ + @Override + public void close() { + if (mService == null) { + throw new IllegalStateException("No group call service attached"); + } + + try { + mService.stopGroupCall(mSubscriptionId, mTmgi); + } catch (RemoteException e) { + Log.w(LOG_TAG, "Remote process died"); + mService = null; + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); + } finally { + mParentSession.onGroupCallStopped(this); + } + } + + /** @hide */ + public InternalGroupCallCallback getCallback() { + return mCallback; + } + + private void sendErrorToApp(int errorCode, String message) { + mCallback.onError(errorCode, message); + } +} + diff --git a/telephony/java/android/telephony/mbms/GroupCallCallback.java b/telephony/java/android/telephony/mbms/GroupCallCallback.java new file mode 100644 index 000000000000..001bb02aad94 --- /dev/null +++ b/telephony/java/android/telephony/mbms/GroupCallCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2018 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 android.telephony.mbms; + +import android.annotation.IntDef; +import android.annotation.Nullable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A callback class for use when the application is in a group call. The middleware + * will provide updates on the status of the call via this callback. + */ +public class GroupCallCallback { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE, + MbmsErrors.ERROR_MIDDLEWARE_LOST, + MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY, + MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE, + MbmsErrors.GeneralErrors.ERROR_IN_E911, + MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE, + MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM, + MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" }) + private @interface GroupCallError{} + + /** + * Indicates broadcast signal strength is not available for this call. + * + * This may be due to the call no longer being available due to geography + * or timing (end of service) + */ + public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; + + /** + * Called by the middleware when it has detected an error condition in this group call. The + * possible error codes are listed in {@link MbmsErrors}. + * @param errorCode The error code. + * @param message A human-readable message generated by the middleware for debugging purposes. + */ + public void onError(@GroupCallError int errorCode, @Nullable String message) { + // default implementation empty + } + + /** + * Called to indicate this call has changed state. + * + * See {@link GroupCall#STATE_STOPPED}, {@link GroupCall#STATE_STARTED} + * and {@link GroupCall#STATE_STALLED}. + */ + public void onGroupCallStateChanged(@GroupCall.GroupCallState int state, + @GroupCall.GroupCallStateChangeReason int reason) { + // default implementation empty + } + + /** + * Broadcast Signal Strength updated. + * + * This signal strength is the BROADCAST signal strength which, + * depending on technology in play and it's deployment, may be + * stronger or weaker than the traditional UNICAST signal + * strength. It a simple int from 0-4 for valid levels or + * {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available + * for this call due to timing, geography or popularity. + */ + public void onBroadcastSignalStrengthUpdated(int signalStrength) { + // default implementation empty + } +} diff --git a/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl new file mode 100755 index 000000000000..844b6344a34c --- /dev/null +++ b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 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 android.telephony.mbms; + +/** + * @hide + */ +oneway interface IGroupCallCallback { + void onError(int errorCode, String message); + void onGroupCallStateChanged(int state, int reason); + void onBroadcastSignalStrengthUpdated(int signalStrength); +} diff --git a/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl new file mode 100755 index 000000000000..1a1c7f8af5df --- /dev/null +++ b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl @@ -0,0 +1,33 @@ +/* +** Copyright 2018, 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 android.telephony.mbms; + +import java.util.List; + +/** + * @hide + */ +oneway interface IMbmsGroupCallSessionCallback +{ + void onError(int errorCode, String message); + + void onAvailableSaisUpdated(in List currentSai, in List availableSais); + + void onServiceInterfaceAvailable(String interfaceName, int index); + + void onMiddlewareReady(); +} diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java new file mode 100644 index 000000000000..2910bb313d84 --- /dev/null +++ b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2018 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 android.telephony.mbms; + +import android.os.Binder; + +import java.util.concurrent.Executor; + +/** @hide */ +public class InternalGroupCallCallback extends IGroupCallCallback.Stub { + private final GroupCallCallback mAppCallback; + private final Executor mExecutor; + private volatile boolean mIsStopped = false; + + public InternalGroupCallCallback(GroupCallCallback appCallback, + Executor executor) { + mAppCallback = appCallback; + mExecutor = executor; + } + + @Override + public void onError(final int errorCode, final String message) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onError(errorCode, message); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onGroupCallStateChanged(final int state, final int reason) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onGroupCallStateChanged(state, reason); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onBroadcastSignalStrengthUpdated(final int signalStrength) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onBroadcastSignalStrengthUpdated(signalStrength); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + /** Prevents this callback from calling the app */ + public void stop() { + mIsStopped = true; + } +} diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java new file mode 100644 index 000000000000..4c9cf4dd7c92 --- /dev/null +++ b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2018 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 android.telephony.mbms; + +import android.os.Binder; + +import java.util.List; +import java.util.concurrent.Executor; + +/** @hide */ +public class InternalGroupCallSessionCallback extends IMbmsGroupCallSessionCallback.Stub { + private final Executor mExecutor; + private final MbmsGroupCallSessionCallback mAppCallback; + private volatile boolean mIsStopped = false; + + public InternalGroupCallSessionCallback(MbmsGroupCallSessionCallback appCallback, + Executor executor) { + mAppCallback = appCallback; + mExecutor = executor; + } + + @Override + public void onError(final int errorCode, final String message) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onError(errorCode, message); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onAvailableSaisUpdated(final List currentSais, final List availableSais) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onAvailableSaisUpdated(currentSais, availableSais); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onServiceInterfaceAvailable(final String interfaceName, final int index) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onServiceInterfaceAvailable(interfaceName, index); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onMiddlewareReady() { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onMiddlewareReady(); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + /** Prevents this callback from calling the app */ + public void stop() { + mIsStopped = true; + } +} diff --git a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java new file mode 100644 index 000000000000..7da734ee5837 --- /dev/null +++ b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 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 android.telephony.mbms; + +import android.annotation.IntDef; +import android.annotation.Nullable; +import android.content.Context; +import android.telephony.MbmsGroupCallSession; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.concurrent.Executor; + +/** + * A callback class that is used to receive information from the middleware on MBMS group-call + * services. An instance of this object should be passed into + * {@link MbmsGroupCallSession#create(Context, Executor, int, MbmsGroupCallSessionCallback)}. + */ +public class MbmsGroupCallSessionCallback { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE, + MbmsErrors.ERROR_MIDDLEWARE_LOST, + MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND, + MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED, + MbmsErrors.InitializationErrors.ERROR_DUPLICATE_INITIALIZE, + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY, + MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE, + MbmsErrors.GeneralErrors.ERROR_IN_E911, + MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE, + MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM, + MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" }) + private @interface GroupCallError{} + + /** + * Called by the middleware when it has detected an error condition. The possible error codes + * are listed in {@link MbmsErrors}. + * @param errorCode The error code. + * @param message A human-readable message generated by the middleware for debugging purposes. + */ + public void onError(@GroupCallError int errorCode, @Nullable String message) { + } + + /** + * Indicates that the list of currently available SAIs has been updated. The app may use this + * information to filter the list of group calls when displaying available group calls to + * the user by matching the SAIs with a list of group calls separately negotiated with the + * carrier. The app may also report the aggregate list of SAIs to the group call application + * server so that a network entity can determine when, and where to activate the broadcast of + * particular group calls. + * @param currentSais The available SAIs on the current cell. + * @param availableSais A list of lists of available SAIS in neighboring cells, where each list + * contains the available SAIs in an individual cell. + */ + public void onAvailableSaisUpdated(List<Integer> currentSais, + List<List<Integer>> availableSais) { + } + + /** + * Called soon after the app calls {@link MbmsGroupCallSession#create}. The information supplied + * via this callback may be used to establish a data-link interface with the modem before the + * middleware is ready. + * Note that this method may be called before {@link #onMiddlewareReady()}. + * + * @param interfaceName The interface name for the data link. + * @param index The index for the data link. + */ + public void onServiceInterfaceAvailable(String interfaceName, int index) { + } + + /** + * Called to indicate that the middleware has been initialized and is ready. + * + * Before this method is called, calling any method on an instance of + * {@link MbmsGroupCallSession} will result in an {@link IllegalStateException} or an error + * delivered via {@link #onError(int, String)} with error code + * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}. + */ + public void onMiddlewareReady() { + } +} diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java index 06b2120b59c1..95b4d37e5840 100644 --- a/telephony/java/android/telephony/mbms/MbmsUtils.java +++ b/telephony/java/android/telephony/mbms/MbmsUtils.java @@ -23,6 +23,7 @@ import android.content.ServiceConnection; import android.content.pm.*; import android.content.pm.ServiceInfo; import android.telephony.MbmsDownloadSession; +import android.telephony.MbmsGroupCallSession; import android.telephony.MbmsStreamingSession; import android.util.Log; @@ -59,6 +60,9 @@ public class MbmsUtils { case MbmsStreamingSession.MBMS_STREAMING_SERVICE_ACTION: metaDataKey = MbmsStreamingSession.MBMS_STREAMING_SERVICE_OVERRIDE_METADATA; break; + case MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_ACTION: + metaDataKey = MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA; + break; } if (metaDataKey == null) { return null; diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl new file mode 100755 index 000000000000..721256a95396 --- /dev/null +++ b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl @@ -0,0 +1,39 @@ +/* +** Copyright 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 android.telephony.mbms.vendor; + +import android.net.Uri; +import android.telephony.mbms.IMbmsGroupCallSessionCallback; +import android.telephony.mbms.IGroupCallCallback; + +/** + * @hide + */ +interface IMbmsGroupCallService +{ + int initialize(IMbmsGroupCallSessionCallback callback, int subId); + + void stopGroupCall(int subId, long tmgi); + + void updateGroupCall(int subscriptionId, long tmgi, in int[] saiArray, + in int[] frequencyArray); + + int startGroupCall(int subscriptionId, long tmgi, in int[] saiArray, + in int[] frequencyArray, IGroupCallCallback callback); + + void dispose(int subId); +} diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java new file mode 100644 index 000000000000..3734ca7d6fc9 --- /dev/null +++ b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2018 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 android.telephony.mbms.vendor; + +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.app.Service; +import android.content.Intent; +import android.os.Binder; +import android.os.IBinder; +import android.os.RemoteException; +import android.telephony.mbms.GroupCallCallback; +import android.telephony.mbms.IGroupCallCallback; +import android.telephony.mbms.IMbmsGroupCallSessionCallback; +import android.telephony.mbms.MbmsErrors; +import android.telephony.mbms.MbmsGroupCallSessionCallback; +import android.telephony.mbms.vendor.IMbmsGroupCallService.Stub; + +import java.util.List; + +/** + * Base class for MBMS group-call services. The middleware should override this class to implement + * its {@link Service} for group calls + * Subclasses should call this class's {@link #onBind} method to obtain an {@link IBinder} if they + * override {@link #onBind}. + * @hide + */ +@SystemApi +@TestApi +public class MbmsGroupCallServiceBase extends Service { + private final IBinder mInterface = new Stub() { + @Override + public int initialize(final IMbmsGroupCallSessionCallback callback, + final int subscriptionId) throws RemoteException { + if (callback == null) { + throw new NullPointerException("Callback must not be null"); + } + + final int uid = Binder.getCallingUid(); + + int result = MbmsGroupCallServiceBase.this.initialize( + new MbmsGroupCallSessionCallback() { + @Override + public void onError(final int errorCode, final String message) { + try { + if (errorCode == MbmsErrors.UNKNOWN) { + throw new IllegalArgumentException( + "Middleware cannot send an unknown error."); + } + callback.onError(errorCode, message); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + @Override + public void onAvailableSaisUpdated(final List currentSais, + final List availableSais) { + try { + callback.onAvailableSaisUpdated(currentSais, availableSais); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + @Override + public void onServiceInterfaceAvailable(final String interfaceName, + final int index) { + try { + callback.onServiceInterfaceAvailable(interfaceName, index); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + @Override + public void onMiddlewareReady() { + try { + callback.onMiddlewareReady(); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + }, subscriptionId); + + if (result == MbmsErrors.SUCCESS) { + callback.asBinder().linkToDeath(new DeathRecipient() { + @Override + public void binderDied() { + onAppCallbackDied(uid, subscriptionId); + } + }, 0); + } + + return result; + } + + @Override + public void stopGroupCall(int subId, long tmgi) { + MbmsGroupCallServiceBase.this.stopGroupCall(subId, tmgi); + } + + @Override + public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray, + int[] frequencyArray) { + MbmsGroupCallServiceBase.this.updateGroupCall( + subscriptionId, tmgi, saiArray, frequencyArray); + } + + @Override + public int startGroupCall(final int subscriptionId, final long tmgi, final int[] saiArray, + final int[] frequencyArray, final IGroupCallCallback callback) + throws RemoteException { + if (callback == null) { + throw new NullPointerException("Callback must not be null"); + } + + final int uid = Binder.getCallingUid(); + + int result = MbmsGroupCallServiceBase.this.startGroupCall( + subscriptionId, tmgi, saiArray, frequencyArray, new GroupCallCallback() { + @Override + public void onError(final int errorCode, final String message) { + try { + if (errorCode == MbmsErrors.UNKNOWN) { + throw new IllegalArgumentException( + "Middleware cannot send an unknown error."); + } + callback.onError(errorCode, message); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + public void onGroupCallStateChanged(int state, int reason) { + try { + callback.onGroupCallStateChanged(state, reason); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + public void onBroadcastSignalStrengthUpdated(int signalStrength) { + try { + callback.onBroadcastSignalStrengthUpdated(signalStrength); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + }); + + if (result == MbmsErrors.SUCCESS) { + callback.asBinder().linkToDeath(new DeathRecipient() { + @Override + public void binderDied() { + onAppCallbackDied(uid, subscriptionId); + } + }, 0); + } + + return result; + } + + @Override + public void dispose(int subId) throws RemoteException { + MbmsGroupCallServiceBase.this.dispose(subId); + } + }; + + /** + * Initialize the group call service for this app and subscription ID, registering the callback. + * + * May throw an {@link IllegalArgumentException} or a {@link SecurityException}, which + * will be intercepted and passed to the app as + * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE} + * + * May return any value from {@link MbmsErrors.InitializationErrors} + * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via + * {@link IMbmsGroupCallSessionCallback#onError(int, String)}. + * + * @param callback The callback to use to communicate with the app. + * @param subscriptionId The subscription ID to use. + */ + public int initialize(MbmsGroupCallSessionCallback callback, int subscriptionId) + throws RemoteException { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Starts a particular group call. This method may perform asynchronous work. When + * the call is ready for consumption, the middleware should inform the app via + * {@link IGroupCallCallback#onGroupCallStateChanged(int, int)}. + * + * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException} + * + * @param subscriptionId The subscription id to use. + * @param tmgi The TMGI, an identifier for the group call. + * @param saiArray An array of SAIs for the group call. + * @param frequencyArray An array of frequencies for the group call. + * @param callback The callback object on which the app wishes to receive updates. + * @return Any error in {@link MbmsErrors.GeneralErrors} + */ + public int startGroupCall(int subscriptionId, long tmgi, int[] saiArray, int[] frequencyArray, + GroupCallCallback callback) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Stop the group call identified by {@code tmgi}. + * + * The callback provided via {@link #startGroupCall} should no longer be + * used after this method has called by the app. + * + * May throw an {@link IllegalStateException} + * + * @param subscriptionId The subscription id to use. + * @param tmgi The TMGI for the call to stop. + */ + public void stopGroupCall(int subscriptionId, long tmgi) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Called when the app receives new SAI and frequency information for the group call identified + * by {@code tmgi}. + * @param saiArray New array of SAIs that the call is available on. + * @param frequencyArray New array of frequencies that the call is available on. + */ + public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray, + int[] frequencyArray) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Signals that the app wishes to dispose of the session identified by the + * {@code subscriptionId} argument and the caller's uid. No notification back to the + * app is required for this operation, and the corresponding callback provided via + * {@link #initialize} should no longer be used + * after this method has been called by the app. + * + * May throw an {@link IllegalStateException} + * + * @param subscriptionId The subscription id to use. + */ + public void dispose(int subscriptionId) throws RemoteException { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Indicates that the app identified by the given UID and subscription ID has died. + * @param uid the UID of the app, as returned by {@link Binder#getCallingUid()}. + * @param subscriptionId The subscription ID the app is using. + */ + public void onAppCallbackDied(int uid, int subscriptionId) { + } + + @Override + public IBinder onBind(Intent intent) { + return mInterface; + } +} diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 6521f0b41cb2..0ccd748c31df 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -232,5 +232,5 @@ interface ISub { */ int getSimStateForSlotIndex(int slotIndex); - boolean isActiveSubId(int subId); + boolean isActiveSubId(int subId, String callingPackage); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index df3944018e3c..33616149c3b4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -75,116 +75,6 @@ interface ITelephony { void call(String callingPackage, String number); /** - * End call if there is a call in progress, otherwise does nothing. - * - * @return whether it hung up - */ - boolean endCall(); - - /** - * End call on particular subId or go to the Home screen - * @param subId user preferred subId. - * @return whether it hung up - */ - boolean endCallForSubscriber(int subId); - - /** - * Answer the currently-ringing call. - * - * If there's already a current active call, that call will be - * automatically put on hold. If both lines are currently in use, the - * current active call will be ended. - * - * TODO: provide a flag to let the caller specify what policy to use - * if both lines are in use. (The current behavior is hardwired to - * "answer incoming, end ongoing", which is how the CALL button - * is specced to behave.) - * - * TODO: this should be a oneway call (especially since it's called - * directly from the key queue thread). - */ - void answerRingingCall(); - - /** - * Answer the currently-ringing call on particular subId . - * - * If there's already a current active call, that call will be - * automatically put on hold. If both lines are currently in use, the - * current active call will be ended. - * - * TODO: provide a flag to let the caller specify what policy to use - * if both lines are in use. (The current behavior is hardwired to - * "answer incoming, end ongoing", which is how the CALL button - * is specced to behave.) - * - * TODO: this should be a oneway call (especially since it's called - * directly from the key queue thread). - */ - void answerRingingCallForSubscriber(int subId); - - /** - * Silence the ringer if an incoming call is currently ringing. - * (If vibrating, stop the vibrator also.) - * - * It's safe to call this if the ringer has already been silenced, or - * even if there's no incoming call. (If so, this method will do nothing.) - * - * TODO: this should be a oneway call too (see above). - * (Actually *all* the methods here that return void can - * probably be oneway.) - */ - void silenceRinger(); - - /** - * Check if we are in either an active or holding call - * @param callingPackage the name of the package making the call. - * @return true if the phone state is OFFHOOK. - */ - boolean isOffhook(String callingPackage); - - /** - * Check if a particular subId has an active or holding call - * - * @param subId user preferred subId. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is OFFHOOK. - */ - boolean isOffhookForSubscriber(int subId, String callingPackage); - - /** - * Check if an incoming phone call is ringing or call waiting - * on a particular subId. - * - * @param subId user preferred subId. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is RINGING. - */ - boolean isRingingForSubscriber(int subId, String callingPackage); - - /** - * Check if an incoming phone call is ringing or call waiting. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is RINGING. - */ - boolean isRinging(String callingPackage); - - /** - * Check if the phone is idle. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is IDLE. - */ - boolean isIdle(String callingPackage); - - /** - * Check if the phone is idle on a particular subId. - * - * @param subId user preferred subId. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is IDLE. - */ - boolean isIdleForSubscriber(int subId, String callingPackage); - - /** * Check to see if the radio is on or not. * @param callingPackage the name of the package making the call. * @return returns true if the radio is on. diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java index 6ce66f0f4546..639ed7d55384 100644 --- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java +++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java @@ -245,8 +245,14 @@ public class AppLaunch extends InstrumentationTestCase { mIterationCycle = false; // In the "applaunch.txt" file, trail launches is referenced using // "TRIAL_LAUNCH" - String appPkgName = mNameToIntent.get(launch.getApp()) - .getComponent().getPackageName(); + Intent startIntent = mNameToIntent.get(launch.getApp()); + if (startIntent == null) { + Log.w(TAG, "App does not exist: " + launch.getApp()); + mResult.putString(mNameToResultKey.get(launch.getApp()), + "App does not exist"); + continue; + } + String appPkgName = startIntent.getComponent().getPackageName(); if (SPEED_PROFILE_FILTER.equals(launch.getCompilerFilter())) { assertTrue(String.format("Not able to compile the app : %s", appPkgName), compileApp(VERIFY_FILTER, appPkgName)); diff --git a/tests/net/java/android/net/util/SharedLogTest.java b/tests/net/java/android/net/util/SharedLogTest.java index d46facfaba06..86048604e95f 100644 --- a/tests/net/java/android/net/util/SharedLogTest.java +++ b/tests/net/java/android/net/util/SharedLogTest.java @@ -44,6 +44,8 @@ public class SharedLogTest { final SharedLog logLevel2a = logTop.forSubComponent("twoA"); final SharedLog logLevel2b = logTop.forSubComponent("twoB"); logLevel2b.e("2b or not 2b"); + logLevel2b.e("No exception", null); + logLevel2b.e("Wait, here's one", new Exception("Test")); logLevel2a.w("second post?"); final SharedLog logLevel3 = logLevel2a.forSubComponent("three"); @@ -54,6 +56,9 @@ public class SharedLogTest { final String[] expected = { " - MARK first post!", " - [twoB] ERROR 2b or not 2b", + " - [twoB] ERROR No exception", + // No stacktrace in shared log, only in logcat + " - [twoB] ERROR Wait, here's one: Test", " - [twoA] WARN second post?", " - still logging", " - [twoA.three] 3 >> 2", diff --git a/tools/aapt2/io/FileStream_test.cpp b/tools/aapt2/io/FileStream_test.cpp index c0eaa8e08418..7872738320c3 100644 --- a/tools/aapt2/io/FileStream_test.cpp +++ b/tools/aapt2/io/FileStream_test.cpp @@ -41,46 +41,46 @@ TEST(FileInputStreamTest, NextAndBackup) { ASSERT_FALSE(in.HadError()); EXPECT_THAT(in.ByteCount(), Eq(0u)); - const char* buffer; + const void* buffer; size_t size; - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)) << in.GetError(); + ASSERT_TRUE(in.Next(&buffer, &size)) << in.GetError(); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(in.ByteCount(), Eq(10u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("this is a ")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("this is a ")); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(in.ByteCount(), Eq(20u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin")); in.BackUp(5u); EXPECT_THAT(in.ByteCount(), Eq(15u)); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(5u)); ASSERT_THAT(buffer, NotNull()); ASSERT_THAT(in.ByteCount(), Eq(20u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("strin")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("strin")); // Backup 1 more than possible. Should clamp. in.BackUp(11u); EXPECT_THAT(in.ByteCount(), Eq(10u)); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); ASSERT_THAT(in.ByteCount(), Eq(20u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin")); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(1u)); ASSERT_THAT(buffer, NotNull()); ASSERT_THAT(in.ByteCount(), Eq(21u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("g")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("g")); - EXPECT_FALSE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + EXPECT_FALSE(in.Next(&buffer, &size)); EXPECT_FALSE(in.HadError()); } @@ -93,25 +93,25 @@ TEST(FileOutputStreamTest, NextAndBackup) { ASSERT_FALSE(out.HadError()); EXPECT_THAT(out.ByteCount(), Eq(0u)); - char* buffer; + void* buffer; size_t size; - ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size)); + ASSERT_TRUE(out.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(out.ByteCount(), Eq(10u)); - memcpy(buffer, input.c_str(), size); + memcpy(reinterpret_cast<char*>(buffer), input.c_str(), size); - ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size)); + ASSERT_TRUE(out.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(out.ByteCount(), Eq(20u)); - memcpy(buffer, input.c_str() + 10u, size); + memcpy(reinterpret_cast<char*>(buffer), input.c_str() + 10u, size); - ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size)); + ASSERT_TRUE(out.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(out.ByteCount(), Eq(30u)); - buffer[0] = input[20u]; + reinterpret_cast<char*>(buffer)[0] = input[20u]; out.BackUp(size - 1); EXPECT_THAT(out.ByteCount(), Eq(21u)); |