Merge "Update OWNER files for connectivity"
diff --git a/Android.bp b/Android.bp
index 69fb459..0cd985d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -460,8 +460,8 @@
"telecomm/java/com/android/internal/telecom/IInCallService.aidl",
"telecomm/java/com/android/internal/telecom/ITelecomService.aidl",
"telecomm/java/com/android/internal/telecom/RemoteServiceCallback.aidl",
- "telephony/java/android/telephony/data/IDataService.aidl",
- "telephony/java/android/telephony/data/IDataServiceCallback.aidl",
+ "telephony/java/android/telephony/data/IDataService.aidl",
+ "telephony/java/android/telephony/data/IDataServiceCallback.aidl",
"telephony/java/android/telephony/ims/internal/aidl/IImsCallSessionListener.aidl",
"telephony/java/android/telephony/ims/internal/aidl/IImsCapabilityCallback.aidl",
"telephony/java/android/telephony/ims/internal/aidl/IImsConfig.aidl",
@@ -471,8 +471,7 @@
"telephony/java/android/telephony/ims/internal/aidl/IImsRcsFeature.aidl",
"telephony/java/android/telephony/ims/internal/aidl/IImsServiceController.aidl",
"telephony/java/android/telephony/ims/internal/aidl/IImsServiceControllerListener.aidl",
- "telephony/java/android/telephony/ims/internal/aidl/IImsSmsListener.aidl",
- "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
+ "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
"telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
"telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl",
"telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl",
@@ -496,6 +495,7 @@
"telephony/java/com/android/ims/internal/IImsService.aidl",
"telephony/java/com/android/ims/internal/IImsServiceController.aidl",
"telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl",
+ "telephony/java/com/android/ims/internal/IImsSmsListener.aidl",
"telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl",
"telephony/java/com/android/ims/internal/IImsUt.aidl",
"telephony/java/com/android/ims/internal/IImsUtListener.aidl",
diff --git a/api/current.txt b/api/current.txt
index a9bf7d1..e047bdc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27545,10 +27545,14 @@
field public static final java.lang.String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
field public static final java.lang.String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
field public static final java.lang.String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
+ field public static final java.lang.String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED";
field public static final java.lang.String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
+ field public static final java.lang.String EXTRA_AID = "android.nfc.extra.AID";
+ field public static final java.lang.String EXTRA_DATA = "android.nfc.extra.DATA";
field public static final java.lang.String EXTRA_ID = "android.nfc.extra.ID";
field public static final java.lang.String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
field public static final java.lang.String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
+ field public static final java.lang.String EXTRA_SE_NAME = "android.nfc.extra.SE_NAME";
field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
field public static final int FLAG_READER_NFC_A = 1; // 0x1
field public static final int FLAG_READER_NFC_B = 2; // 0x2
@@ -40394,10 +40398,10 @@
method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, android.os.Handler);
method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, int, android.os.Handler);
method public int download(android.telephony.mbms.DownloadRequest);
- method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
method public java.io.File getTempFileRootDirectory();
method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
method public int registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback, android.os.Handler);
+ method public void requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
method public void requestUpdateFileServices(java.util.List<java.lang.String>);
method public void resetDownloadKnowledge(android.telephony.mbms.DownloadRequest);
method public void setTempFileRootDirectory(java.io.File);
@@ -41280,6 +41284,7 @@
public static class MbmsErrors.DownloadErrors {
field public static final int ERROR_CANNOT_CHANGE_TEMP_FILE_ROOT = 401; // 0x191
field public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402; // 0x192
+ field public static final int ERROR_UNKNOWN_FILE_INFO = 403; // 0x193
}
public static class MbmsErrors.GeneralErrors {
@@ -44088,6 +44093,7 @@
field public static final int DENSITY_360 = 360; // 0x168
field public static final int DENSITY_400 = 400; // 0x190
field public static final int DENSITY_420 = 420; // 0x1a4
+ field public static final int DENSITY_440 = 440; // 0x1b8
field public static final int DENSITY_560 = 560; // 0x230
field public static final int DENSITY_DEFAULT = 160; // 0xa0
field public static final int DENSITY_DEVICE_STABLE;
diff --git a/api/system-current.txt b/api/system-current.txt
index 041c213..0371f91 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -28,6 +28,7 @@
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
+ field public static final java.lang.String BIND_TELEPHONY_DATA_SERVICE = "android.permission.BIND_TELEPHONY_DATA_SERVICE";
field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final java.lang.String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
@@ -4044,6 +4045,24 @@
public final class SmsManager {
method public void sendMultipartTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
method public void sendTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
+ field public static final int RESULT_CANCELLED = 23; // 0x17
+ field public static final int RESULT_ENCODING_ERROR = 18; // 0x12
+ field public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; // 0x6
+ field public static final int RESULT_ERROR_NONE = 0; // 0x0
+ field public static final int RESULT_INTERNAL_ERROR = 21; // 0x15
+ field public static final int RESULT_INVALID_ARGUMENTS = 11; // 0xb
+ field public static final int RESULT_INVALID_SMSC_ADDRESS = 19; // 0x13
+ field public static final int RESULT_INVALID_SMS_FORMAT = 14; // 0xe
+ field public static final int RESULT_INVALID_STATE = 12; // 0xc
+ field public static final int RESULT_MODEM_ERROR = 16; // 0x10
+ field public static final int RESULT_NETWORK_ERROR = 17; // 0x11
+ field public static final int RESULT_NETWORK_REJECT = 10; // 0xa
+ field public static final int RESULT_NO_MEMORY = 13; // 0xd
+ field public static final int RESULT_NO_RESOURCES = 22; // 0x16
+ field public static final int RESULT_OPERATION_NOT_ALLOWED = 20; // 0x14
+ field public static final int RESULT_RADIO_NOT_AVAILABLE = 9; // 0x9
+ field public static final int RESULT_REQUEST_NOT_SUPPORTED = 24; // 0x18
+ field public static final int RESULT_SYSTEM_ERROR = 15; // 0xf
}
public class SubscriptionManager {
@@ -4287,6 +4306,30 @@
}
+package android.telephony.ims.internal.stub {
+
+ public class SmsImplBase {
+ ctor public SmsImplBase();
+ method public void acknowledgeSms(int, int, int);
+ method public void acknowledgeSmsReport(int, int, int);
+ method public java.lang.String getSmsFormat();
+ method public void onReady();
+ method public final void onSendSmsResult(int, int, int, int) throws java.lang.RuntimeException;
+ method public final void onSmsReceived(int, java.lang.String, byte[]) throws java.lang.RuntimeException;
+ method public final void onSmsStatusReportReceived(int, int, java.lang.String, byte[]) throws java.lang.RuntimeException;
+ method public void sendSms(int, int, java.lang.String, java.lang.String, boolean, byte[]);
+ field public static final int DELIVER_STATUS_ERROR = 2; // 0x2
+ field public static final int DELIVER_STATUS_OK = 1; // 0x1
+ field public static final int SEND_STATUS_ERROR = 2; // 0x2
+ field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4
+ field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3
+ field public static final int SEND_STATUS_OK = 1; // 0x1
+ field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2
+ field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1
+ }
+
+}
+
package android.telephony.mbms {
public final class DownloadRequest implements android.os.Parcelable {
@@ -4337,11 +4380,11 @@
method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
method public void dispose(int) throws android.os.RemoteException;
method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
method public void onAppCallbackDied(int, int);
method public int registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback) throws android.os.RemoteException;
+ method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 75ff437..93de1c2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -495,11 +495,11 @@
method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
method public void dispose(int) throws android.os.RemoteException;
method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
- method public int getDownloadStatus(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
method public void onAppCallbackDied(int, int);
method public int registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback) throws android.os.RemoteException;
+ method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index a2af342..3df4336 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -1507,6 +1507,38 @@
}
/**
+ * Request an LE connection parameter update.
+ *
+ * <p>This function will send an LE connection parameters update request to the remote device.
+ *
+ * @return true, if the request is send to the Bluetooth stack.
+ * @hide
+ */
+ public boolean requestLeConnectionUpdate(int minConnectionInterval,
+ int maxConnectionInterval,
+ int slaveLatency, int supervisionTimeout) {
+ if (DBG) {
+ Log.d(TAG, "requestLeConnectionUpdate() - min=(" + minConnectionInterval
+ + ")" + (1.25 * minConnectionInterval)
+ + "msec, max=(" + maxConnectionInterval + ")"
+ + (1.25 * maxConnectionInterval) + "msec, latency=" + slaveLatency
+ + ", timeout=" + supervisionTimeout + "msec");
+ }
+ if (mService == null || mClientIf == 0) return false;
+
+ try {
+ mService.leConnectionUpdate(mClientIf, mDevice.getAddress(),
+ minConnectionInterval, maxConnectionInterval,
+ slaveLatency, supervisionTimeout);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
* Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
* with {@link BluetoothProfile#GATT} as argument
*
diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java
index 31a3096..ecccda5 100644
--- a/core/java/android/net/EthernetManager.java
+++ b/core/java/android/net/EthernetManager.java
@@ -18,9 +18,6 @@
import android.annotation.SystemService;
import android.content.Context;
-import android.net.IEthernetManager;
-import android.net.IEthernetServiceListener;
-import android.net.IpConfiguration;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
@@ -45,18 +42,18 @@
if (msg.what == MSG_AVAILABILITY_CHANGED) {
boolean isAvailable = (msg.arg1 == 1);
for (Listener listener : mListeners) {
- listener.onAvailabilityChanged(isAvailable);
+ listener.onAvailabilityChanged((String) msg.obj, isAvailable);
}
}
}
};
- private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
+ private final ArrayList<Listener> mListeners = new ArrayList<>();
private final IEthernetServiceListener.Stub mServiceListener =
new IEthernetServiceListener.Stub() {
@Override
- public void onAvailabilityChanged(boolean isAvailable) {
+ public void onAvailabilityChanged(String iface, boolean isAvailable) {
mHandler.obtainMessage(
- MSG_AVAILABILITY_CHANGED, isAvailable ? 1 : 0, 0, null).sendToTarget();
+ MSG_AVAILABILITY_CHANGED, isAvailable ? 1 : 0, 0, iface).sendToTarget();
}
};
@@ -66,9 +63,10 @@
public interface Listener {
/**
* Called when Ethernet port's availability is changed.
- * @param isAvailable {@code true} if one or more Ethernet port exists.
+ * @param iface Ethernet interface name
+ * @param isAvailable {@code true} if Ethernet port exists.
*/
- public void onAvailabilityChanged(boolean isAvailable);
+ void onAvailabilityChanged(String iface, boolean isAvailable);
}
/**
@@ -86,9 +84,9 @@
* Get Ethernet configuration.
* @return the Ethernet Configuration, contained in {@link IpConfiguration}.
*/
- public IpConfiguration getConfiguration() {
+ public IpConfiguration getConfiguration(String iface) {
try {
- return mService.getConfiguration();
+ return mService.getConfiguration(iface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -97,21 +95,29 @@
/**
* Set Ethernet configuration.
*/
- public void setConfiguration(IpConfiguration config) {
+ public void setConfiguration(String iface, IpConfiguration config) {
try {
- mService.setConfiguration(config);
+ mService.setConfiguration(iface, config);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
- * Indicates whether the system currently has one or more
- * Ethernet interfaces.
+ * Indicates whether the system currently has one or more Ethernet interfaces.
*/
public boolean isAvailable() {
+ return getAvailableInterfaces().length > 0;
+ }
+
+ /**
+ * Indicates whether the system has given interface.
+ *
+ * @param iface Ethernet interface name
+ */
+ public boolean isAvailable(String iface) {
try {
- return mService.isAvailable();
+ return mService.isAvailable(iface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -137,6 +143,17 @@
}
/**
+ * Returns an array of available Ethernet interface names.
+ */
+ public String[] getAvailableInterfaces() {
+ try {
+ return mService.getAvailableInterfaces();
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
* Removes a listener.
* @param listener A {@link Listener} to remove.
* @throws IllegalArgumentException If the listener is null.
diff --git a/core/java/android/net/IEthernetManager.aidl b/core/java/android/net/IEthernetManager.aidl
index 7a92eb9..94960b5 100644
--- a/core/java/android/net/IEthernetManager.aidl
+++ b/core/java/android/net/IEthernetManager.aidl
@@ -26,9 +26,10 @@
/** {@hide} */
interface IEthernetManager
{
- IpConfiguration getConfiguration();
- void setConfiguration(in IpConfiguration config);
- boolean isAvailable();
+ String[] getAvailableInterfaces();
+ IpConfiguration getConfiguration(String iface);
+ void setConfiguration(String iface, in IpConfiguration config);
+ boolean isAvailable(String iface);
void addListener(in IEthernetServiceListener listener);
void removeListener(in IEthernetServiceListener listener);
}
diff --git a/core/java/android/net/IEthernetServiceListener.aidl b/core/java/android/net/IEthernetServiceListener.aidl
index 356690e8..782fa19 100644
--- a/core/java/android/net/IEthernetServiceListener.aidl
+++ b/core/java/android/net/IEthernetServiceListener.aidl
@@ -19,5 +19,5 @@
/** @hide */
oneway interface IEthernetServiceListener
{
- void onAvailabilityChanged(boolean isAvailable);
+ void onAvailabilityChanged(String iface, boolean isAvailable);
}
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 196a3bc..fa4624e 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -433,6 +433,10 @@
}
}
+ private static long addIfSupported(long stat) {
+ return (stat == UNSUPPORTED) ? 0 : stat;
+ }
+
/**
* Return number of packets transmitted across mobile networks since device
* boot. Counts packets across all mobile network interfaces, and always
@@ -445,7 +449,7 @@
public static long getMobileTxPackets() {
long total = 0;
for (String iface : getMobileIfaces()) {
- total += getTxPackets(iface);
+ total += addIfSupported(getTxPackets(iface));
}
return total;
}
@@ -462,7 +466,7 @@
public static long getMobileRxPackets() {
long total = 0;
for (String iface : getMobileIfaces()) {
- total += getRxPackets(iface);
+ total += addIfSupported(getRxPackets(iface));
}
return total;
}
@@ -479,7 +483,7 @@
public static long getMobileTxBytes() {
long total = 0;
for (String iface : getMobileIfaces()) {
- total += getTxBytes(iface);
+ total += addIfSupported(getTxBytes(iface));
}
return total;
}
@@ -496,7 +500,7 @@
public static long getMobileRxBytes() {
long total = 0;
for (String iface : getMobileIfaces()) {
- total += getRxBytes(iface);
+ total += addIfSupported(getRxBytes(iface));
}
return total;
}
@@ -511,9 +515,7 @@
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- if (stat != UNSUPPORTED) {
- total += stat;
- }
+ total += addIfSupported(stat);
}
return total;
}
@@ -528,9 +530,7 @@
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- if (stat != UNSUPPORTED) {
- total += stat;
- }
+ total += addIfSupported(stat);
}
return total;
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index debef63..b02d48d 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -147,6 +147,19 @@
public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
/**
+ * Broadcast Action: Intent to notify an application that an transaction event has occurred
+ * on the Secure Element.
+ *
+ * <p>This intent will only be sent if the application has requested permission for
+ * {@link android.Manifest.permission#NFC_TRANSACTION_EVENT} and if the application has the
+ * necessary access to Secure Element which witnessed the particular event.
+ */
+ @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT)
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_TRANSACTION_DETECTED =
+ "android.nfc.action.TRANSACTION_DETECTED";
+
+ /**
* Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
* @hide
*/
@@ -197,6 +210,23 @@
*/
public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
+ /**
+ * Mandatory byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
+ */
+ public static final String EXTRA_AID = "android.nfc.extra.AID";
+
+ /**
+ * Optional byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
+ */
+ public static final String EXTRA_DATA = "android.nfc.extra.DATA";
+
+ /**
+ * Mandatory String extra field in {@link #ACTION_TRANSACTION_DETECTED}
+ * Indicates the Secure Element on which the transaction occurred.
+ * eSE1...eSEn for Embedded Secure Elements, SIM1...SIMn for UICC, etc.
+ */
+ public static final String EXTRA_SE_NAME = "android.nfc.extra.SE_NAME";
+
public static final int STATE_OFF = 1;
public static final int STATE_TURNING_ON = 2;
public static final int STATE_ON = 3;
diff --git a/core/java/android/se/omapi/Channel.java b/core/java/android/se/omapi/Channel.java
index f0b9fa2d..65ce67f 100644
--- a/core/java/android/se/omapi/Channel.java
+++ b/core/java/android/se/omapi/Channel.java
@@ -25,6 +25,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import java.io.IOException;
@@ -168,8 +169,10 @@
throw new IOException("Error in communicating with Secure Element");
}
return response;
- } catch (RemoteException e) {
+ } catch (ServiceSpecificException e) {
throw new IOException(e.getMessage());
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e.getMessage());
}
}
}
@@ -244,8 +247,10 @@
synchronized (mLock) {
return mChannel.selectNext();
}
- } catch (RemoteException e) {
+ } catch (ServiceSpecificException e) {
throw new IOException(e.getMessage());
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e.getMessage());
}
}
}
diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java
index 9f15739..3dec976 100644
--- a/core/java/android/se/omapi/Reader.java
+++ b/core/java/android/se/omapi/Reader.java
@@ -24,6 +24,7 @@
import android.annotation.NonNull;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import java.io.IOException;
@@ -45,8 +46,7 @@
private final Object mLock = new Object();
- Reader(SEService service, String name, ISecureElementReader reader) throws
- IOException {
+ Reader(SEService service, String name, ISecureElementReader reader) {
if (reader == null || service == null || name == null) {
throw new IllegalArgumentException("Parameters cannot be null");
}
@@ -96,8 +96,10 @@
ISecureElementSession session;
try {
session = mReader.openSession();
- } catch (RemoteException e) {
+ } catch (ServiceSpecificException e) {
throw new IOException(e.getMessage());
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e.getMessage());
}
if (session == null) {
throw new IOException("service session is null.");
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index 1e37277d..b8937e6 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -42,6 +42,23 @@
*/
public class SEService {
+ /**
+ * Error code used with ServiceSpecificException.
+ * Thrown if there was an error communicating with the Secure Element.
+ *
+ * @hide
+ */
+ public static final int IO_ERROR = 1;
+
+ /**
+ * Error code used with ServiceSpecificException.
+ * Thrown if AID cannot be selected or is not available when opening
+ * a logical channel.
+ *
+ * @hide
+ */
+ public static final int NO_SUCH_ELEMENT_ERROR = 2;
+
private static final String TAG = "OMAPI.SEService";
private final Object mLock = new Object();
diff --git a/core/java/android/se/omapi/Session.java b/core/java/android/se/omapi/Session.java
index bb2a032..19a018e 100644
--- a/core/java/android/se/omapi/Session.java
+++ b/core/java/android/se/omapi/Session.java
@@ -25,6 +25,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import java.io.IOException;
@@ -207,8 +208,16 @@
return null;
}
return new Channel(mService, this, channel);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == SEService.IO_ERROR) {
+ throw new IOException(e.getMessage());
+ } else if (e.errorCode == SEService.NO_SUCH_ELEMENT_ERROR) {
+ throw new NoSuchElementException(e.getMessage());
+ } else {
+ throw new IllegalStateException(e.getMessage());
+ }
} catch (RemoteException e) {
- throw new IOException(e.getMessage());
+ throw new IllegalStateException(e.getMessage());
}
}
}
@@ -311,8 +320,16 @@
return null;
}
return new Channel(mService, this, channel);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == SEService.IO_ERROR) {
+ throw new IOException(e.getMessage());
+ } else if (e.errorCode == SEService.NO_SUCH_ELEMENT_ERROR) {
+ throw new NoSuchElementException(e.getMessage());
+ } else {
+ throw new IllegalStateException(e.getMessage());
+ }
} catch (RemoteException e) {
- throw new IOException(e.getMessage());
+ throw new IllegalStateException(e.getMessage());
}
}
}
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index b7099b6..13de172 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -120,6 +120,14 @@
public static final int DENSITY_420 = 420;
/**
+ * Intermediate density for screens that sit somewhere between
+ * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
+ * This is not a density that applications should target, instead relying
+ * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
+ */
+ public static final int DENSITY_440 = 440;
+
+ /**
* Standard quantized DPI for extra-extra-high-density screens.
*/
public static final int DENSITY_XXHIGH = 480;
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index d0f5ba7..03e5667 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -57,6 +57,8 @@
public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
/** Do not enfore hidden API access restrictions. */
public static final int DISABLE_HIDDEN_API_CHECKS = 1 << 11;
+ /** Force generation of native debugging information for backtraces. */
+ public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 12;
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = 0;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 43d7df3..ada9bd7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1756,6 +1756,15 @@
<permission android:name="android.permission.BIND_IMS_SERVICE"
android:protectionLevel="signature|privileged" />
+ <!-- Must be required by a telephony data service to ensure that only the
+ system can bind to it.
+ <p>Protection level: signature
+ @SystemApi
+ @hide
+ -->
+ <permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- Allows an application to manage embedded subscriptions (those on a eUICC) through
EuiccManager APIs.
<p>Protection level: signature|privileged|development
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5cc727d..a8a5700 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -360,6 +360,23 @@
<!-- Regex of wired ethernet ifaces -->
<string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>
+
+
+ <!-- Configuration of Ethernet interfaces in the following format:
+ <interface name|mac address>;[Network Capabilities];[IP config]
+ Where
+ [Network Capabilities] Optional. A comma seprated list of network capabilities.
+ Values must be from NetworkCapabilities#NET_CAPABILITIES_* constants.
+ [IP config] Optional. If empty or not specified - DHCP will be used, otherwise
+ static IP address with the mask.
+ -->
+ <string-array translatable="false" name="config_ethernet_interfaces">
+ <!--
+ <item>eth1;12,13,14,15;192.168.0.10/24</item>
+ <item>eth2;;192.168.0.11/24</item>
+ -->
+ </string-array>
+
<!-- If the mobile hotspot feature requires provisioning, a package name and class name
can be provided to launch a supported application that provisions the devices.
@@ -2468,6 +2485,14 @@
<!-- Flag specifying whether or not IMS will use the dynamic ImsResolver -->
<bool name="config_dynamic_bind_ims">false</bool>
+ <!-- Cellular data service package name to bind to by default. If none is specified in an overlay, an
+ empty string is passed in -->
+ <string name="config_wwan_data_service_package" translatable="false">com.android.phone</string>
+
+ <!-- IWLAN data service package name to bind to by default. If none is specified in an overlay, an
+ empty string is passed in -->
+ <string name="config_wlan_data_service_package" translatable="false"></string>
+
<bool name="config_networkSamplingWakesDevice">true</bool>
<!-- Home (non-roaming) values for CDMA roaming indicator.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fb755a1..08be23d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -264,6 +264,8 @@
<java-symbol type="bool" name="config_mms_content_disposition_support" />
<java-symbol type="string" name="config_ims_package" />
<java-symbol type="bool" name="config_dynamic_bind_ims" />
+ <java-symbol type="string" name="config_wwan_data_service_package" />
+ <java-symbol type="string" name="config_wlan_data_service_package" />
<java-symbol type="bool" name="config_networkSamplingWakesDevice" />
<java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" />
<java-symbol type="bool" name="config_sip_wifi_only" />
@@ -634,6 +636,7 @@
<java-symbol type="string" name="chooseActivity" />
<java-symbol type="string" name="config_default_dns_server" />
<java-symbol type="string" name="config_ethernet_iface_regex" />
+ <java-symbol type="array" name="config_ethernet_interfaces" />
<java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 6a3a973..5b6577f 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -134,6 +134,7 @@
<permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_SERVICES"/>
<permission name="android.permission.BIND_IMS_SERVICE"/>
+ <permission name="android.permission.BIND_TELEPHONY_DATA_SERVICE"/>
<permission name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
<permission name="android.permission.CALL_PRIVILEGED"/>
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
@@ -146,6 +147,7 @@
<permission name="android.permission.LOCAL_MAC_ADDRESS"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
+ <permission name="android.permission.PACKAGE_USAGE_STATS"/>
<permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
<permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
@@ -212,6 +214,7 @@
<permission name="android.permission.CALL_PRIVILEGED"/>
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
+ <permission name="android.permission.MODIFY_AUDIO_ROUTING" />
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.STOP_APP_SWITCHES"/>
<permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index b08b26d..e467903 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -49,7 +49,6 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.qs.tiles.DndTile;
@@ -340,11 +339,15 @@
private boolean shouldShowUI(int flags) {
updateStatusBar();
- return mStatusBar != null
- && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_ASLEEP
- && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP
+ // if status bar isn't null, check if phone is in AOD, else check flags
+ // since we could be using a different status bar
+ return mStatusBar != null ?
+ mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_ASLEEP
+ && mStatusBar.getWakefulnessState() !=
+ WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP
&& mStatusBar.isDeviceInteractive()
- && (flags & AudioManager.FLAG_SHOW_UI) != 0;
+ && (flags & AudioManager.FLAG_SHOW_UI) != 0
+ : (flags & AudioManager.FLAG_SHOW_UI) != 0;
}
boolean onVolumeChangedW(int stream, int flags) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 6747be3..6743484 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -35,6 +35,7 @@
import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.DisconnectCause;
+import android.telephony.LocationAccessPolicy;
import android.telephony.PhoneStateListener;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
@@ -93,7 +94,8 @@
IPhoneStateListener callback;
IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
- int callerUserId;
+ int callerUid;
+ int callerPid;
int events;
@@ -117,7 +119,7 @@
+ " callback=" + callback
+ " onSubscriptionsChangedListenererCallback="
+ onSubscriptionsChangedListenerCallback
- + " callerUserId=" + callerUserId + " subId=" + subId + " phoneId=" + phoneId
+ + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
+ " events=" + Integer.toHexString(events)
+ " canReadPhoneState=" + canReadPhoneState + "}";
}
@@ -356,6 +358,8 @@
public void addOnSubscriptionsChangedListener(String callingPackage,
IOnSubscriptionsChangedListener callback) {
int callerUserId = UserHandle.getCallingUserId();
+ mContext.getSystemService(AppOpsManager.class)
+ .checkPackage(Binder.getCallingUid(), callingPackage);
if (VDBG) {
log("listen oscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId()
+ " callerUserId=" + callerUserId + " callback=" + callback
@@ -399,7 +403,8 @@
r.onSubscriptionsChangedListenerCallback = callback;
r.callingPackage = callingPackage;
- r.callerUserId = callerUserId;
+ r.callerUid = Binder.getCallingUid();
+ r.callerPid = Binder.getCallingPid();
r.events = 0;
r.canReadPhoneState = true; // permission has been enforced above
if (DBG) {
@@ -470,6 +475,8 @@
private void listen(String callingPackage, IPhoneStateListener callback, int events,
boolean notifyNow, int subId) {
int callerUserId = UserHandle.getCallingUserId();
+ mContext.getSystemService(AppOpsManager.class)
+ .checkPackage(Binder.getCallingUid(), callingPackage);
if (VDBG) {
log("listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events)
+ " notifyNow=" + notifyNow + " subId=" + subId + " myUserId="
@@ -514,7 +521,8 @@
r.callback = callback;
r.callingPackage = callingPackage;
- r.callerUserId = callerUserId;
+ r.callerUid = Binder.getCallingUid();
+ r.callerPid = Binder.getCallingPid();
boolean isPhoneStateEvent = (events & (CHECK_PHONE_STATE_PERMISSION_MASK
| ENFORCE_PHONE_STATE_PERMISSION_MASK)) != 0;
r.canReadPhoneState = isPhoneStateEvent && canReadPhoneState(callingPackage);
@@ -572,8 +580,10 @@
try {
if (DBG_LOC) log("listen: mCellLocation = "
+ mCellLocation[phoneId]);
- r.callback.onCellLocationChanged(
- new Bundle(mCellLocation[phoneId]));
+ if (checkLocationAccess(r)) {
+ r.callback.onCellLocationChanged(
+ new Bundle(mCellLocation[phoneId]));
+ }
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -619,7 +629,9 @@
try {
if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
+ mCellInfo.get(phoneId));
- r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+ if (checkLocationAccess(r)) {
+ r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+ }
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -979,7 +991,8 @@
mCellInfo.set(phoneId, cellInfo);
for (Record r : mRecords) {
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) &&
- idMatch(r.subId, subId, phoneId)) {
+ idMatch(r.subId, subId, phoneId) &&
+ checkLocationAccess(r)) {
try {
if (DBG_LOC) {
log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r);
@@ -1262,7 +1275,8 @@
mCellLocation[phoneId] = cellLocation;
for (Record r : mRecords) {
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
- idMatch(r.subId, subId, phoneId)) {
+ idMatch(r.subId, subId, phoneId) &&
+ checkLocationAccess(r)) {
try {
if (DBG_LOC) {
log("notifyCellLocation: cellLocation=" + cellLocation
@@ -1706,10 +1720,11 @@
boolean valid = false;
try {
foregroundUser = ActivityManager.getCurrentUser();
- valid = r.callerUserId == foregroundUser && r.matchPhoneStateListenerEvent(events);
+ valid = UserHandle.getUserId(r.callerUid) == foregroundUser
+ && r.matchPhoneStateListenerEvent(events);
if (DBG | DBG_LOC) {
log("validateEventsAndUserLocked: valid=" + valid
- + " r.callerUserId=" + r.callerUserId + " foregroundUser=" + foregroundUser
+ + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
+ " r.events=" + r.events + " events=" + events);
}
} finally {
@@ -1741,6 +1756,16 @@
}
}
+ private boolean checkLocationAccess(Record r) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ return LocationAccessPolicy.canAccessCellLocation(mContext,
+ r.callingPackage, r.callerUid, r.callerPid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
private void checkPossibleMissNotify(Record r, int phoneId) {
int events = r.events;
@@ -1788,7 +1813,9 @@
log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
+ mCellInfo.get(phoneId));
}
- r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+ if (checkLocationAccess(r)) {
+ r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+ }
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -1836,7 +1863,9 @@
try {
if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = "
+ mCellLocation[phoneId]);
- r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId]));
+ if (checkLocationAccess(r)) {
+ r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId]));
+ }
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e944326..f0d6757a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3863,9 +3863,13 @@
runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
- if ("true".equals(genDebugInfoProperty)) {
+ if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
}
+ String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
+ if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
+ runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
+ }
if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
}
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index 4d56468..e3e02e3 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -24,11 +24,11 @@
import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.net.StaticIpConfiguration;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.net.DelayedDiskWrite;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
@@ -38,8 +38,8 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.net.InetAddress;
import java.net.Inet4Address;
+import java.net.InetAddress;
public class IpConfigStore {
private static final String TAG = "IpConfigStore";
@@ -60,7 +60,7 @@
protected static final String EXCLUSION_LIST_KEY = "exclusionList";
protected static final String EOS = "eos";
- protected static final int IPCONFIG_FILE_VERSION = 2;
+ protected static final int IPCONFIG_FILE_VERSION = 3;
public IpConfigStore(DelayedDiskWrite writer) {
mWriter = writer;
@@ -70,9 +70,14 @@
this(new DelayedDiskWrite());
}
+ private static boolean writeConfig(DataOutputStream out, String configKey,
+ IpConfiguration config) throws IOException {
+ return writeConfig(out, configKey, config, IPCONFIG_FILE_VERSION);
+ }
+
@VisibleForTesting
- public static boolean writeConfig(DataOutputStream out, int configKey,
- IpConfiguration config) throws IOException {
+ public static boolean writeConfig(DataOutputStream out, String configKey,
+ IpConfiguration config, int version) throws IOException {
boolean written = false;
try {
@@ -153,7 +158,11 @@
if (written) {
out.writeUTF(ID_KEY);
- out.writeInt(configKey);
+ if (version < 3) {
+ out.writeInt(Integer.valueOf(configKey));
+ } else {
+ out.writeUTF(configKey);
+ }
}
} catch (NullPointerException e) {
loge("Failure in writing " + config + e);
@@ -163,18 +172,47 @@
return written;
}
- public void writeIpAndProxyConfigurations(String filePath,
+ /**
+ * @Deprecated use {@link #writeIpConfigurations(String, ArrayMap)} instead.
+ * New method uses string as network identifier which could be interface name or MAC address or
+ * other token.
+ */
+ @Deprecated
+ public void writeIpAndProxyConfigurationsToFile(String filePath,
final SparseArray<IpConfiguration> networks) {
- mWriter.write(filePath, new DelayedDiskWrite.Writer() {
- public void onWriteCalled(DataOutputStream out) throws IOException{
- out.writeInt(IPCONFIG_FILE_VERSION);
- for(int i = 0; i < networks.size(); i++) {
- writeConfig(out, networks.keyAt(i), networks.valueAt(i));
- }
+ mWriter.write(filePath, out -> {
+ out.writeInt(IPCONFIG_FILE_VERSION);
+ for(int i = 0; i < networks.size(); i++) {
+ writeConfig(out, String.valueOf(networks.keyAt(i)), networks.valueAt(i));
}
});
}
+ public void writeIpConfigurations(String filePath,
+ ArrayMap<String, IpConfiguration> networks) {
+ mWriter.write(filePath, out -> {
+ out.writeInt(IPCONFIG_FILE_VERSION);
+ for(int i = 0; i < networks.size(); i++) {
+ writeConfig(out, networks.keyAt(i), networks.valueAt(i));
+ }
+ });
+ }
+
+ public static ArrayMap<String, IpConfiguration> readIpConfigurations(String filePath) {
+ BufferedInputStream bufferedInputStream;
+ try {
+ bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
+ } catch (FileNotFoundException e) {
+ // Return an empty array here because callers expect an empty array when the file is
+ // not present.
+ loge("Error opening configuration file: " + e);
+ return new ArrayMap<>(0);
+ }
+ return readIpConfigurations(bufferedInputStream);
+ }
+
+ /** @Deprecated use {@link #readIpConfigurations(String)} */
+ @Deprecated
public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(String filePath) {
BufferedInputStream bufferedInputStream;
try {
@@ -188,21 +226,40 @@
return readIpAndProxyConfigurations(bufferedInputStream);
}
+ /** @Deprecated use {@link #readIpConfigurations(InputStream)} */
+ @Deprecated
public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(
InputStream inputStream) {
- SparseArray<IpConfiguration> networks = new SparseArray<IpConfiguration>();
+ ArrayMap<String, IpConfiguration> networks = readIpConfigurations(inputStream);
+ if (networks == null) {
+ return null;
+ }
+
+ SparseArray<IpConfiguration> networksById = new SparseArray<>();
+ for (int i = 0; i < networks.size(); i++) {
+ int id = Integer.valueOf(networks.keyAt(i));
+ networksById.put(id, networks.valueAt(i));
+ }
+
+ return networksById;
+ }
+
+ /** Returns a map of network identity token and {@link IpConfiguration}. */
+ public static ArrayMap<String, IpConfiguration> readIpConfigurations(
+ InputStream inputStream) {
+ ArrayMap<String, IpConfiguration> networks = new ArrayMap<>();
DataInputStream in = null;
try {
in = new DataInputStream(inputStream);
int version = in.readInt();
- if (version != 2 && version != 1) {
+ if (version != 3 && version != 2 && version != 1) {
loge("Bad version on IP configuration file, ignore read");
return null;
}
while (true) {
- int id = -1;
+ String uniqueToken = null;
// Default is DHCP with no proxy
IpAssignment ipAssignment = IpAssignment.DHCP;
ProxySettings proxySettings = ProxySettings.NONE;
@@ -217,7 +274,12 @@
key = in.readUTF();
try {
if (key.equals(ID_KEY)) {
- id = in.readInt();
+ if (version < 3) {
+ int id = in.readInt();
+ uniqueToken = String.valueOf(id);
+ } else {
+ uniqueToken = in.readUTF();
+ }
} else if (key.equals(IP_ASSIGNMENT_KEY)) {
ipAssignment = IpAssignment.valueOf(in.readUTF());
} else if (key.equals(LINK_ADDRESS_KEY)) {
@@ -280,9 +342,9 @@
}
} while (true);
- if (id != -1) {
+ if (uniqueToken != null) {
IpConfiguration config = new IpConfiguration();
- networks.put(id, config);
+ networks.put(uniqueToken, config);
switch (ipAssignment) {
case STATIC:
diff --git a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
new file mode 100644
index 0000000..9f4b754
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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 com.android.server.net;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.ProxyInfo;
+import android.net.StaticIpConfiguration;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArrayMap;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Unit tests for {@link IpConfigStore}
+ */
+@RunWith(AndroidJUnit4.class)
+public class IpConfigStoreTest {
+
+ @Test
+ public void backwardCompatibility2to3() throws IOException {
+ final int KEY_CONFIG = 17;
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ DataOutputStream outputStream = new DataOutputStream(byteStream);
+
+ IpConfiguration expectedConfig = new IpConfiguration(IpAssignment.DHCP,
+ ProxySettings.NONE, null, null);
+
+ // Emulate writing to old format.
+ writeDhcpConfigV2(outputStream, KEY_CONFIG, expectedConfig);
+
+ InputStream in = new ByteArrayInputStream(byteStream.toByteArray());
+ ArrayMap<String, IpConfiguration> configurations = IpConfigStore.readIpConfigurations(in);
+
+ assertNotNull(configurations);
+ assertEquals(1, configurations.size());
+ IpConfiguration actualConfig = configurations.get(String.valueOf(KEY_CONFIG));
+ assertNotNull(actualConfig);
+ assertEquals(expectedConfig, actualConfig);
+ }
+
+ @Test
+ public void staticIpMultiNetworks() throws Exception {
+ final String IFACE_1 = "eth0";
+ final String IFACE_2 = "eth1";
+ final String IP_ADDR_1 = "192.168.1.10/24";
+ final String IP_ADDR_2 = "192.168.1.20/24";
+ final String DNS_IP_ADDR_1 = "1.2.3.4";
+ final String DNS_IP_ADDR_2 = "5.6.7.8";
+
+ StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+ staticIpConfiguration.ipAddress = new LinkAddress(IP_ADDR_1);
+ staticIpConfiguration.dnsServers.add(NetworkUtils.numericToInetAddress(DNS_IP_ADDR_1));
+ staticIpConfiguration.dnsServers.add(NetworkUtils.numericToInetAddress(DNS_IP_ADDR_2));
+
+ ProxyInfo proxyInfo = new ProxyInfo("10.10.10.10", 88, "host1,host2");
+
+ IpConfiguration expectedConfig1 = new IpConfiguration(IpAssignment.STATIC,
+ ProxySettings.STATIC, staticIpConfiguration, proxyInfo);
+ IpConfiguration expectedConfig2 = new IpConfiguration(expectedConfig1);
+ expectedConfig2.getStaticIpConfiguration().ipAddress = new LinkAddress(IP_ADDR_2);
+
+ ArrayMap<String, IpConfiguration> expectedNetworks = new ArrayMap<>();
+ expectedNetworks.put(IFACE_1, expectedConfig1);
+ expectedNetworks.put(IFACE_2, expectedConfig2);
+
+ MockedDelayedDiskWrite writer = new MockedDelayedDiskWrite();
+ IpConfigStore store = new IpConfigStore(writer);
+ store.writeIpConfigurations("file/path/not/used/", expectedNetworks);
+
+ InputStream in = new ByteArrayInputStream(writer.byteStream.toByteArray());
+ ArrayMap<String, IpConfiguration> actualNetworks = IpConfigStore.readIpConfigurations(in);
+ assertNotNull(actualNetworks);
+ assertEquals(2, actualNetworks.size());
+ assertEquals(expectedNetworks.get(IFACE_1), actualNetworks.get(IFACE_1));
+ assertEquals(expectedNetworks.get(IFACE_2), actualNetworks.get(IFACE_2));
+ }
+
+ // This is simplified snapshot of code that was used to store values in V2 format (key as int).
+ private static void writeDhcpConfigV2(DataOutputStream out, int configKey,
+ IpConfiguration config) throws IOException {
+ out.writeInt(2); // VERSION 2
+ switch (config.ipAssignment) {
+ case DHCP:
+ out.writeUTF("ipAssignment");
+ out.writeUTF(config.ipAssignment.toString());
+ break;
+ default:
+ fail("Not supported in test environment");
+ }
+
+ out.writeUTF("id");
+ out.writeInt(configKey);
+ out.writeUTF("eos");
+ }
+
+ /** Synchronously writes into given byte steam */
+ private static class MockedDelayedDiskWrite extends DelayedDiskWrite {
+ final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+
+ @Override
+ public void write(String filePath, Writer w) {
+ DataOutputStream outputStream = new DataOutputStream(byteStream);
+
+ try {
+ w.onWriteCalled(outputStream);
+ } catch (IOException e) {
+ fail();
+ }
+ }
+ }
+}
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index fcfc593..95eb14a 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -134,6 +134,25 @@
"android.telecom.extra.LOG_SELF_MANAGED_CALLS";
/**
+ * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+ * indicates whether calls for a {@link PhoneAccount} should generate a "call recording tone"
+ * when the user is recording audio on the device.
+ * <p>
+ * The call recording tone is played over the telephony audio stream so that the remote party
+ * has an audible indication that it is possible their call is being recorded using a call
+ * recording app on the device.
+ * <p>
+ * This extra only has an effect for calls placed via Telephony (e.g.
+ * {@link #CAPABILITY_SIM_SUBSCRIPTION}).
+ * <p>
+ * The call recording tone is a 1400 hz tone which repeats every 15 seconds while recording is
+ * in progress.
+ * @hide
+ */
+ public static final String EXTRA_PLAY_CALL_RECORDING_TONE =
+ "android.telecom.extra.PLAY_CALL_RECORDING_TONE";
+
+ /**
* Flag indicating that this {@code PhoneAccount} can act as a connection manager for
* other connections. The {@link ConnectionService} associated with this {@code PhoneAccount}
* will be allowed to manage phone calls including using its own proprietary phone-call
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 94ed218..dc3195c 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -77,6 +77,14 @@
public static final String
KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
+ /**
+ * Boolean indicating if the "Call barring" item is visible in the Call Settings menu.
+ * true means visible. false means gone.
+ * @hide
+ */
+ public static final String KEY_CALL_BARRING_VISIBILITY_BOOL =
+ "call_barring_visibility_bool";
+
/**
* Flag indicating whether the Phone app should ignore EVENT_SIM_NETWORK_LOCKED
* events from the Sim.
@@ -146,6 +154,15 @@
public static final String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool";
/**
+ * Determines if the carrier requires that a tone be played to the remote party when an app is
+ * recording audio during a call (e.g. using a call recording app).
+ * <p>
+ * Note: This requires the Telephony config_supports_telephony_audio_device overlay to be true
+ * in order to work.
+ * @hide
+ */
+ public static final String KEY_PLAY_CALL_RECORDING_TONE_BOOL = "play_call_recording_tone_bool";
+ /**
* Determines if the carrier requires converting the destination number before sending out an
* SMS. Certain networks and numbering plans require different formats.
*/
@@ -491,6 +508,20 @@
public static final String KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL
= "carrier_volte_override_wfc_provisioning_bool";
+ /**
+ * Override the device's configuration for the cellular data service to use for this SIM card.
+ * @hide
+ */
+ public static final String KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING
+ = "carrier_data_service_wwan_package_override_string";
+
+ /**
+ * Override the device's configuration for the IWLAN data service to use for this SIM card.
+ * @hide
+ */
+ public static final String KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING
+ = "carrier_data_service_wlan_package_override_string";
+
/** Flag specifying whether VoLTE TTY is supported. */
public static final String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
= "carrier_volte_tty_supported_bool";
@@ -1375,6 +1406,14 @@
public static final String KEY_VIDEO_CALLS_CAN_BE_HD_AUDIO = "video_calls_can_be_hd_audio";
/**
+ * When true, indicates that the HD audio icon in the in-call screen should be shown for
+ * GSM/CDMA calls.
+ * @hide
+ */
+ public static final String KEY_GSM_CDMA_CALLS_CAN_BE_HD_AUDIO =
+ "gsm_cdma_calls_can_be_hd_audio";
+
+ /**
* Whether system apps are allowed to use fallback if carrier video call is not available.
* Defaults to {@code true}.
*
@@ -1771,6 +1810,7 @@
sDefaults.putBoolean(KEY_ADDITIONAL_CALL_SETTING_BOOL, true);
sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL, false);
sDefaults.putBoolean(KEY_ALLOW_LOCAL_DTMF_TONES_BOOL, true);
+ sDefaults.putBoolean(KEY_PLAY_CALL_RECORDING_TONE_BOOL, false);
sDefaults.putBoolean(KEY_APN_EXPAND_BOOL, true);
sDefaults.putBoolean(KEY_AUTO_RETRY_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_SETTINGS_ENABLE_BOOL, false);
@@ -1797,6 +1837,8 @@
sDefaults.putBoolean(KEY_CARRIER_IMS_GBA_REQUIRED_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, true);
+ sDefaults.putString(KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING, "");
+ sDefaults.putString(KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING, "");
sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING, "");
sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING, "");
sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING, "");
@@ -1810,6 +1852,7 @@
sDefaults.putBoolean(KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
+ sDefaults.putBoolean(KEY_CALL_BARRING_VISIBILITY_BOOL, false);
sDefaults.putBoolean(KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL, false);
sDefaults.putBoolean(KEY_MDN_IS_ADDITIONAL_VOICEMAIL_NUMBER_BOOL, false);
sDefaults.putBoolean(KEY_OPERATOR_SELECTION_EXPAND_BOOL, true);
@@ -2009,6 +2052,7 @@
sDefaults.putBoolean(KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL, true);
sDefaults.putBoolean(KEY_WIFI_CALLS_CAN_BE_HD_AUDIO, true);
sDefaults.putBoolean(KEY_VIDEO_CALLS_CAN_BE_HD_AUDIO, true);
+ sDefaults.putBoolean(KEY_GSM_CDMA_CALLS_CAN_BE_HD_AUDIO, false);
sDefaults.putBoolean(KEY_ALLOW_VIDEO_CALLING_FALLBACK_BOOL, true);
sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null);
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index dfaaab9..ece1ee3 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -36,48 +36,14 @@
private int mEvdoEcio; // This value is the EVDO Ec/Io
private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio
- /**
- * Empty constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthCdma() {
setDefaultValues();
}
- /**
- * Constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio,
int evdoSnr) {
- initialize(cdmaDbm, cdmaEcio, evdoDbm, evdoEcio, evdoSnr);
- }
-
- /**
- * Copy constructors
- *
- * @param s Source SignalStrength
- *
- * @hide
- */
- public CellSignalStrengthCdma(CellSignalStrengthCdma s) {
- copyFrom(s);
- }
-
- /**
- * Initialize all the values
- *
- * @param cdmaDbm
- * @param cdmaEcio
- * @param evdoDbm
- * @param evdoEcio
- * @param evdoSnr
- *
- * @hide
- */
- public void initialize(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr) {
mCdmaDbm = cdmaDbm;
mCdmaEcio = cdmaEcio;
mEvdoDbm = evdoDbm;
@@ -85,9 +51,12 @@
mEvdoSnr = evdoSnr;
}
- /**
- * @hide
- */
+ /** @hide */
+ public CellSignalStrengthCdma(CellSignalStrengthCdma s) {
+ copyFrom(s);
+ }
+
+ /** @hide */
protected void copyFrom(CellSignalStrengthCdma s) {
mCdmaDbm = s.mCdmaDbm;
mCdmaEcio = s.mCdmaEcio;
@@ -96,9 +65,7 @@
mEvdoSnr = s.mEvdoSnr;
}
- /**
- * @hide
- */
+ /** @hide */
@Override
public CellSignalStrengthCdma copy() {
return new CellSignalStrengthCdma(this);
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index f68d2ca..8687cd1 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -34,80 +34,40 @@
private static final int GSM_SIGNAL_STRENGTH_GOOD = 8;
private static final int GSM_SIGNAL_STRENGTH_MODERATE = 5;
- private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
+ private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
- private int mTimingAdvance;
+ private int mTimingAdvance; // range from 0-219 or Integer.MAX_VALUE if unknown
- /**
- * Empty constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthGsm() {
setDefaultValues();
}
- /**
- * Constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthGsm(int ss, int ber) {
- initialize(ss, ber);
+ this(ss, ber, Integer.MAX_VALUE);
}
- /**
- * Copy constructors
- *
- * @param s Source SignalStrength
- *
- * @hide
- */
- public CellSignalStrengthGsm(CellSignalStrengthGsm s) {
- copyFrom(s);
- }
-
- /**
- * Initialize all the values
- *
- * @param ss SignalStrength as ASU value
- * @param ber is Bit Error Rate
- *
- * @hide
- */
- public void initialize(int ss, int ber) {
- mSignalStrength = ss;
- mBitErrorRate = ber;
- mTimingAdvance = Integer.MAX_VALUE;
- }
-
- /**
- * Initialize all the values
- *
- * @param ss SignalStrength as ASU value
- * @param ber is Bit Error Rate
- * @param ta timing advance
- *
- * @hide
- */
- public void initialize(int ss, int ber, int ta) {
+ /** @hide */
+ public CellSignalStrengthGsm(int ss, int ber, int ta) {
mSignalStrength = ss;
mBitErrorRate = ber;
mTimingAdvance = ta;
}
- /**
- * @hide
- */
+ /** @hide */
+ public CellSignalStrengthGsm(CellSignalStrengthGsm s) {
+ copyFrom(s);
+ }
+
+ /** @hide */
protected void copyFrom(CellSignalStrengthGsm s) {
mSignalStrength = s.mSignalStrength;
mBitErrorRate = s.mBitErrorRate;
mTimingAdvance = s.mTimingAdvance;
}
- /**
- * @hide
- */
+ /** @hide */
@Override
public CellSignalStrengthGsm copy() {
return new CellSignalStrengthGsm(this);
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 6ffc8b6..f009fb1 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -37,50 +37,15 @@
private int mCqi;
private int mTimingAdvance;
- /**
- * Empty constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthLte() {
setDefaultValues();
}
- /**
- * Constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthLte(int signalStrength, int rsrp, int rsrq, int rssnr, int cqi,
int timingAdvance) {
- initialize(signalStrength, rsrp, rsrq, rssnr, cqi, timingAdvance);
- }
-
- /**
- * Copy constructors
- *
- * @param s Source SignalStrength
- *
- * @hide
- */
- public CellSignalStrengthLte(CellSignalStrengthLte s) {
- copyFrom(s);
- }
-
- /**
- * Initialize all the values
- *
- * @param lteSignalStrength
- * @param rsrp
- * @param rsrq
- * @param rssnr
- * @param cqi
- *
- * @hide
- */
- public void initialize(int lteSignalStrength, int rsrp, int rsrq, int rssnr, int cqi,
- int timingAdvance) {
- mSignalStrength = lteSignalStrength;
+ mSignalStrength = signalStrength;
mRsrp = rsrp;
mRsrq = rsrq;
mRssnr = rssnr;
@@ -88,25 +53,12 @@
mTimingAdvance = timingAdvance;
}
- /**
- * Initialize from the SignalStrength structure.
- *
- * @param ss
- *
- * @hide
- */
- public void initialize(SignalStrength ss, int timingAdvance) {
- mSignalStrength = ss.getLteSignalStrength();
- mRsrp = ss.getLteRsrp();
- mRsrq = ss.getLteRsrq();
- mRssnr = ss.getLteRssnr();
- mCqi = ss.getLteCqi();
- mTimingAdvance = timingAdvance;
+ /** @hide */
+ public CellSignalStrengthLte(CellSignalStrengthLte s) {
+ copyFrom(s);
}
- /**
- * @hide
- */
+ /** @hide */
protected void copyFrom(CellSignalStrengthLte s) {
mSignalStrength = s.mSignalStrength;
mRsrp = s.mRsrp;
@@ -116,9 +68,7 @@
mTimingAdvance = s.mTimingAdvance;
}
- /**
- * @hide
- */
+ /** @hide */
@Override
public CellSignalStrengthLte copy() {
return new CellSignalStrengthLte(this);
diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
index 2cd56b8..dd32a96 100644
--- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
@@ -34,62 +34,32 @@
private static final int WCDMA_SIGNAL_STRENGTH_GOOD = 8;
private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5;
- private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
- private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
+ private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
+ private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
- /**
- * Empty constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthWcdma() {
setDefaultValues();
}
- /**
- * Constructor
- *
- * @hide
- */
+ /** @hide */
public CellSignalStrengthWcdma(int ss, int ber) {
- initialize(ss, ber);
- }
-
- /**
- * Copy constructors
- *
- * @param s Source SignalStrength
- *
- * @hide
- */
- public CellSignalStrengthWcdma(CellSignalStrengthWcdma s) {
- copyFrom(s);
- }
-
- /**
- * Initialize all the values
- *
- * @param ss SignalStrength as ASU value
- * @param ber is Bit Error Rate
- *
- * @hide
- */
- public void initialize(int ss, int ber) {
mSignalStrength = ss;
mBitErrorRate = ber;
}
- /**
- * @hide
- */
+ /** @hide */
+ public CellSignalStrengthWcdma(CellSignalStrengthWcdma s) {
+ copyFrom(s);
+ }
+
+ /** @hide */
protected void copyFrom(CellSignalStrengthWcdma s) {
mSignalStrength = s.mSignalStrength;
mBitErrorRate = s.mBitErrorRate;
}
- /**
- * @hide
- */
+ /** @hide */
@Override
public CellSignalStrengthWcdma copy() {
return new CellSignalStrengthWcdma(this);
diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java
new file mode 100644
index 0000000..b362df9
--- /dev/null
+++ b/telephony/java/android/telephony/LocationAccessPolicy.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telephony;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.location.LocationManager;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Process;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.SparseBooleanArray;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper for performing location access checks.
+ * @hide
+ */
+public final class LocationAccessPolicy {
+ /**
+ * API to determine if the caller has permissions to get cell location.
+ *
+ * @param pkgName Package name of the application requesting access
+ * @param uid The uid of the package
+ * @param pid The pid of the package
+ * @return boolean true or false if permissions is granted
+ */
+ public static boolean canAccessCellLocation(@NonNull Context context, @NonNull String pkgName,
+ int uid, int pid) throws SecurityException {
+ Trace.beginSection("TelephonyLocationCheck");
+ try {
+ // Always allow the phone process to access location. This avoid breaking legacy code
+ // that rely on public-facing APIs to access cell location, and it doesn't create a
+ // info leak risk because the cell location is stored in the phone process anyway.
+ if (uid == Process.PHONE_UID) {
+ return true;
+ }
+
+ // We always require the location permission and also require the
+ // location mode to be on for non-legacy apps. Legacy apps are
+ // required to be in the foreground to at least mitigate the case
+ // where a legacy app the user is not using tracks their location.
+ // Granting ACCESS_FINE_LOCATION to an app automatically grants it
+ // ACCESS_COARSE_LOCATION.
+
+ if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, pid, uid) ==
+ PackageManager.PERMISSION_DENIED) {
+ return false;
+ }
+ final int opCode = AppOpsManager.permissionToOpCode(
+ Manifest.permission.ACCESS_COARSE_LOCATION);
+ if (opCode != AppOpsManager.OP_NONE && context.getSystemService(AppOpsManager.class)
+ .noteOpNoThrow(opCode, uid, pkgName) != AppOpsManager.MODE_ALLOWED) {
+ return false;
+ }
+ if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))
+ && !isLegacyForeground(context, pkgName, uid)) {
+ return false;
+ }
+ // If the user or profile is current, permission is granted.
+ // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission.
+ return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context);
+ } finally {
+ Trace.endSection();
+ }
+ }
+
+ private static boolean isLocationModeEnabled(@NonNull Context context, @UserIdInt int userId) {
+ int locationMode = Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF, userId);
+ return locationMode != Settings.Secure.LOCATION_MODE_OFF
+ && locationMode != Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
+ }
+
+ private static boolean isLegacyForeground(@NonNull Context context, @NonNull String pkgName,
+ int uid) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ return isLegacyVersion(context, pkgName) && isForegroundApp(context, uid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private static boolean isLegacyVersion(@NonNull Context context, @NonNull String pkgName) {
+ try {
+ if (context.getPackageManager().getApplicationInfo(pkgName, 0)
+ .targetSdkVersion <= Build.VERSION_CODES.O) {
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // In case of exception, assume known app (more strict checking)
+ // Note: This case will never happen since checkPackage is
+ // called to verify validity before checking app's version.
+ }
+ return false;
+ }
+
+ private static boolean isForegroundApp(@NonNull Context context, int uid) {
+ final ActivityManager am = context.getSystemService(ActivityManager.class);
+ return am.getUidImportance(uid) <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+ }
+
+ private static boolean checkInteractAcrossUsersFull(@NonNull Context context) {
+ return context.checkCallingOrSelfPermission(
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private static boolean isCurrentProfile(@NonNull Context context, int uid) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ final int currentUser = ActivityManager.getCurrentUser();
+ final int callingUserId = UserHandle.getUserId(uid);
+ if (callingUserId == currentUser) {
+ return true;
+ } else {
+ List<UserInfo> userProfiles = context.getSystemService(
+ UserManager.class).getProfiles(currentUser);
+ for (UserInfo user : userProfiles) {
+ if (user.id == callingUserId) {
+ return true;
+ }
+ }
+ }
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index 059a2d0..da3d87b 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -437,6 +437,7 @@
int result = downloadService.setTempFileRootDirectory(mSubscriptionId, filePath);
if (result != MbmsErrors.SUCCESS) {
sendErrorToApp(result, null);
+ return;
}
} catch (RemoteException e) {
mService.set(null);
@@ -686,30 +687,42 @@
}
/**
- * Gets information about the status of a file pending download.
+ * Requests information about the state of a file pending download.
*
- * If there was a problem communicating with the middleware or if it has no records of the
+ * The state will be delivered as a callback via
+ * {@link DownloadStateCallback#onStateUpdated(DownloadRequest, FileInfo, int)}. If no such
+ * callback has been registered via
+ * {@link #registerStateCallback(DownloadRequest, DownloadStateCallback, Handler)}, this
+ * method will be a no-op.
+ *
+ * If the middleware has no record of the
* file indicated by {@code fileInfo} being associated with {@code downloadRequest},
- * {@link #STATUS_UNKNOWN} will be returned.
+ * an {@link IllegalArgumentException} will be thrown.
*
* @param downloadRequest The download request to query.
* @param fileInfo The particular file within the request to get information on.
- * @return The status of the download.
*/
- @DownloadStatus
- public int getDownloadStatus(DownloadRequest downloadRequest, FileInfo fileInfo) {
+ public void requestDownloadState(DownloadRequest downloadRequest, FileInfo fileInfo) {
IMbmsDownloadService downloadService = mService.get();
if (downloadService == null) {
throw new IllegalStateException("Middleware not yet bound");
}
try {
- return downloadService.getDownloadStatus(downloadRequest, fileInfo);
+ int result = downloadService.requestDownloadState(downloadRequest, fileInfo);
+ if (result != MbmsErrors.SUCCESS) {
+ if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) {
+ throw new IllegalArgumentException("Unknown download request.");
+ }
+ if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_FILE_INFO) {
+ throw new IllegalArgumentException("Unknown file.");
+ }
+ sendErrorToApp(result, null);
+ }
} catch (RemoteException e) {
mService.set(null);
sIsInitialized.set(false);
sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
- return STATUS_UNKNOWN;
}
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index ff67116..fadfc91 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -22,6 +22,7 @@
import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.android.i18n.phonenumbers.ShortNumberInfo;
+import android.annotation.IntDef;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -42,6 +43,8 @@
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -49,8 +52,31 @@
/**
* Various utilities for dealing with phone number strings.
*/
-public class PhoneNumberUtils
-{
+public class PhoneNumberUtils {
+ /** {@hide} */
+ @IntDef(prefix = "BCD_EXTENDED_TYPE_", value = {
+ BCD_EXTENDED_TYPE_EF_ADN,
+ BCD_EXTENDED_TYPE_CALLED_PARTY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface BcdExtendType {}
+
+ /*
+ * The BCD extended type used to determine the extended char for the digit which is greater than
+ * 9.
+ *
+ * see TS 51.011 section 10.5.1 EF_ADN(Abbreviated dialling numbers)
+ */
+ public static final int BCD_EXTENDED_TYPE_EF_ADN = 1;
+
+ /*
+ * The BCD extended type used to determine the extended char for the digit which is greater than
+ * 9.
+ *
+ * see TS 24.008 section 10.5.4.7 Called party BCD number
+ */
+ public static final int BCD_EXTENDED_TYPE_CALLED_PARTY = 2;
+
/*
* Special characters
*
@@ -77,22 +103,6 @@
public static final int TOA_International = 0x91;
public static final int TOA_Unknown = 0x81;
- /*
- * The BCD extended type used to determine the extended char for the digit which is greater than
- * 9.
- *
- * see TS 51.011 section 10.5.1 EF_ADN(Abbreviated dialling numbers)
- */
- public static final int BCD_EXTENDED_TYPE_EF_ADN = 1;
-
- /*
- * The BCD extended type used to determine the extended char for the digit which is greater than
- * 9.
- *
- * see TS 24.008 section 10.5.4.7 Called party BCD number
- */
- public static final int BCD_EXTENDED_TYPE_CALLED_PARTY = 2;
-
static final String LOG_TAG = "PhoneNumberUtils";
private static final boolean DBG = false;
@@ -844,7 +854,7 @@
*
*/
public static String calledPartyBCDToString(
- byte[] bytes, int offset, int length, int bcdExtType) {
+ byte[] bytes, int offset, int length, @BcdExtendType int bcdExtType) {
boolean prependPlus = false;
StringBuilder ret = new StringBuilder(1 + length * 2);
@@ -944,7 +954,8 @@
}
private static void internalCalledPartyBCDFragmentToString(
- StringBuilder sb, byte [] bytes, int offset, int length, int bcdExtType) {
+ StringBuilder sb, byte [] bytes, int offset, int length,
+ @BcdExtendType int bcdExtType) {
for (int i = offset ; i < length + offset ; i++) {
byte b;
char c;
@@ -999,7 +1010,7 @@
* TOA byte. For example: SIM ADN extension fields
*/
public static String calledPartyBCDFragmentToString(
- byte[] bytes, int offset, int length, int bcdExtType) {
+ byte[] bytes, int offset, int length, @BcdExtendType int bcdExtType) {
StringBuilder ret = new StringBuilder(length * 2);
internalCalledPartyBCDFragmentToString(ret, bytes, offset, length, bcdExtType);
return ret.toString();
@@ -1009,7 +1020,7 @@
* Returns the correspond character for given {@code b} based on {@code bcdExtType}, or 0 on
* invalid code.
*/
- private static char bcdToChar(byte b, int bcdExtType) {
+ private static char bcdToChar(byte b, @BcdExtendType int bcdExtType) {
if (b < 0xa) {
return (char) ('0' + b);
}
@@ -1027,7 +1038,7 @@
return extended.charAt(b - 0xa);
}
- private static int charToBCD(char c, int bcdExtType) {
+ private static int charToBCD(char c, @BcdExtendType int bcdExtType) {
if ('0' <= c && c <= '9') {
return c - '0';
}
@@ -1134,7 +1145,7 @@
*
* @return BCD byte array
*/
- public static byte[] numberToCalledPartyBCD(String number, int bcdExtType) {
+ public static byte[] numberToCalledPartyBCD(String number, @BcdExtendType int bcdExtType) {
return numberToCalledPartyBCDHelper(number, false, bcdExtType);
}
@@ -1143,7 +1154,7 @@
* the return array.
*/
private static byte[] numberToCalledPartyBCDHelper(
- String number, boolean includeLength, int bcdExtType) {
+ String number, boolean includeLength, @BcdExtendType int bcdExtType) {
int numberLenReal = number.length();
int numberLenEffective = numberLenReal;
boolean hasPlus = number.indexOf('+') != -1;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 90a3677..1176491 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -22,13 +22,13 @@
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.text.TextUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -1340,6 +1340,39 @@
}
/** @hide */
+ public static int rilRadioTechnologyToAccessNetworkType(@RilRadioTechnology int rt) {
+ switch(rt) {
+ case RIL_RADIO_TECHNOLOGY_GPRS:
+ case RIL_RADIO_TECHNOLOGY_EDGE:
+ case RIL_RADIO_TECHNOLOGY_GSM:
+ return AccessNetworkType.GERAN;
+ case RIL_RADIO_TECHNOLOGY_UMTS:
+ case RIL_RADIO_TECHNOLOGY_HSDPA:
+ case RIL_RADIO_TECHNOLOGY_HSPAP:
+ case RIL_RADIO_TECHNOLOGY_HSUPA:
+ case RIL_RADIO_TECHNOLOGY_HSPA:
+ case RIL_RADIO_TECHNOLOGY_TD_SCDMA:
+ return AccessNetworkType.UTRAN;
+ case RIL_RADIO_TECHNOLOGY_IS95A:
+ case RIL_RADIO_TECHNOLOGY_IS95B:
+ case RIL_RADIO_TECHNOLOGY_1xRTT:
+ case RIL_RADIO_TECHNOLOGY_EVDO_0:
+ case RIL_RADIO_TECHNOLOGY_EVDO_A:
+ case RIL_RADIO_TECHNOLOGY_EVDO_B:
+ case RIL_RADIO_TECHNOLOGY_EHRPD:
+ return AccessNetworkType.CDMA2000;
+ case RIL_RADIO_TECHNOLOGY_LTE:
+ case RIL_RADIO_TECHNOLOGY_LTE_CA:
+ return AccessNetworkType.EUTRAN;
+ case RIL_RADIO_TECHNOLOGY_IWLAN:
+ return AccessNetworkType.IWLAN;
+ case RIL_RADIO_TECHNOLOGY_UNKNOWN:
+ default:
+ return AccessNetworkType.UNKNOWN;
+ }
+ }
+
+ /** @hide */
public int getDataNetworkType() {
return rilRadioTechnologyToNetworkType(mRilDataRadioTechnology);
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 78a4c65..9a45e7b 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -1127,7 +1127,11 @@
// SMS send failure result codes
- /** No error. {@hide}*/
+ /**
+ * No error.
+ * @hide
+ */
+ @SystemApi
static public final int RESULT_ERROR_NONE = 0;
/** Generic failure cause */
static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
@@ -1139,12 +1143,113 @@
static public final int RESULT_ERROR_NO_SERVICE = 4;
/** Failed because we reached the sending queue limit. */
static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5;
- /** Failed because FDN is enabled. {@hide} */
+ /**
+ * Failed because FDN is enabled.
+ * @hide
+ */
+ @SystemApi
static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6;
/** Failed because user denied the sending of this short code. */
static public final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7;
/** Failed because the user has denied this app ever send premium short codes. */
static public final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8;
+ /**
+ * Failed because the radio was not available
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_RADIO_NOT_AVAILABLE = 9;
+ /**
+ * Failed because of network rejection
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_NETWORK_REJECT = 10;
+ /**
+ * Failed because of invalid arguments
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_INVALID_ARGUMENTS = 11;
+ /**
+ * Failed because of an invalid state
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_INVALID_STATE = 12;
+ /**
+ * Failed because there is no memory
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_NO_MEMORY = 13;
+ /**
+ * Failed because the sms format is not valid
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_INVALID_SMS_FORMAT = 14;
+ /**
+ * Failed because of a system error
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_SYSTEM_ERROR = 15;
+ /**
+ * Failed because of a modem error
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_MODEM_ERROR = 16;
+ /**
+ * Failed because of a network error
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_NETWORK_ERROR = 17;
+ /**
+ * Failed because of an encoding error
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_ENCODING_ERROR = 18;
+ /**
+ * Failed because of an invalid smsc address
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_INVALID_SMSC_ADDRESS = 19;
+ /**
+ * Failed because the operation is not allowed
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_OPERATION_NOT_ALLOWED = 20;
+ /**
+ * Failed because of an internal error
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_INTERNAL_ERROR = 21;
+ /**
+ * Failed because there are no resources
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_NO_RESOURCES = 22;
+ /**
+ * Failed because the operation was cancelled
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_CANCELLED = 23;
+ /**
+ * Failed because the request is not supported
+ * @hide
+ */
+ @SystemApi
+ static public final int RESULT_REQUEST_NOT_SUPPORTED = 24;
+
static private final String PHONE_PACKAGE_NAME = "com.android.phone";
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 1fae04b..137f491 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -541,9 +541,9 @@
* onSubscriptionsChanged overridden.
*/
public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
- String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+ String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (DBG) {
- logd("register OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
+ logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
+ " listener=" + listener);
}
try {
@@ -552,7 +552,7 @@
ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
if (tr != null) {
- tr.addOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
+ tr.addOnSubscriptionsChangedListener(pkgName, listener.callback);
}
} catch (RemoteException ex) {
// Should not happen
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index 63e8c3b..e8c1cb1 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -34,6 +34,8 @@
import android.telephony.Rlog;
import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -105,7 +107,9 @@
private final SparseArray<DataServiceProvider> mServiceMap = new SparseArray<>();
- private final IBinder mBinder = new IDataServiceWrapper();
+ /** @hide */
+ @VisibleForTesting
+ public final IDataServiceWrapper mBinder = new IDataServiceWrapper();
/**
* The abstract class of the actual data service implementation. The data service provider
diff --git a/telephony/java/android/telephony/ims/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/feature/MMTelFeature.java
index 4e095e3a..93c316f 100644
--- a/telephony/java/android/telephony/ims/feature/MMTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MMTelFeature.java
@@ -19,6 +19,7 @@
import android.app.PendingIntent;
import android.os.Message;
import android.os.RemoteException;
+import android.telephony.ims.internal.stub.SmsImplBase;
import com.android.ims.ImsCallProfile;
import com.android.ims.internal.IImsCallSession;
@@ -28,6 +29,7 @@
import com.android.ims.internal.IImsMMTelFeature;
import com.android.ims.internal.IImsMultiEndpoint;
import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsSmsListener;
import com.android.ims.internal.IImsUt;
import com.android.ims.internal.ImsCallSession;
@@ -171,6 +173,49 @@
return MMTelFeature.this.getMultiEndpointInterface();
}
}
+
+ @Override
+ public void setSmsListener(IImsSmsListener l) throws RemoteException {
+ synchronized (mLock) {
+ MMTelFeature.this.setSmsListener(l);
+ }
+ }
+
+ @Override
+ public void sendSms(int token, int messageRef, String format, String smsc, boolean retry,
+ byte[] pdu) {
+ synchronized (mLock) {
+ MMTelFeature.this.sendSms(token, messageRef, format, smsc, retry, pdu);
+ }
+ }
+
+ @Override
+ public void acknowledgeSms(int token, int messageRef, int result) {
+ synchronized (mLock) {
+ MMTelFeature.this.acknowledgeSms(token, messageRef, result);
+ }
+ }
+
+ @Override
+ public void acknowledgeSmsReport(int token, int messageRef, int result) {
+ synchronized (mLock) {
+ MMTelFeature.this.acknowledgeSmsReport(token, messageRef, result);
+ }
+ }
+
+ @Override
+ public String getSmsFormat() {
+ synchronized (mLock) {
+ return MMTelFeature.this.getSmsFormat();
+ }
+ }
+
+ @Override
+ public void onSmsReady() {
+ synchronized (mLock) {
+ MMTelFeature.this.onSmsReady();
+ }
+ }
};
/**
@@ -346,6 +391,43 @@
return null;
}
+ private void setSmsListener(IImsSmsListener listener) {
+ getSmsImplementation().registerSmsListener(listener);
+ }
+
+ private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
+ byte[] pdu) {
+ getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu);
+ }
+
+ private void acknowledgeSms(int token, int messageRef,
+ @SmsImplBase.DeliverStatusResult int result) {
+ getSmsImplementation().acknowledgeSms(token, messageRef, result);
+ }
+
+ private void acknowledgeSmsReport(int token, int messageRef,
+ @SmsImplBase.StatusReportResult int result) {
+ getSmsImplementation().acknowledgeSmsReport(token, messageRef, result);
+ }
+
+ private void onSmsReady() {
+ getSmsImplementation().onReady();
+ }
+
+ /**
+ * Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default
+ * non-functional implementation is returned.
+ *
+ * @return an instance of {@link SmsImplBase} which should be implemented by the IMS Provider.
+ */
+ protected SmsImplBase getSmsImplementation() {
+ return new SmsImplBase();
+ }
+
+ public String getSmsFormat() {
+ return getSmsImplementation().getSmsFormat();
+ }
+
@Override
public void onFeatureReady() {
diff --git a/telephony/java/android/telephony/ims/internal/SmsImplBase.java b/telephony/java/android/telephony/ims/internal/SmsImplBase.java
deleted file mode 100644
index 47414cf..0000000
--- a/telephony/java/android/telephony/ims/internal/SmsImplBase.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.telephony.ims.internal;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.os.RemoteException;
-import android.telephony.SmsManager;
-import android.telephony.SmsMessage;
-import android.telephony.ims.internal.aidl.IImsSmsListener;
-import android.telephony.ims.internal.feature.MmTelFeature;
-import android.util.Log;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Base implementation for SMS over IMS.
- *
- * Any service wishing to provide SMS over IMS should extend this class and implement all methods
- * that the service supports.
- * @hide
- */
-public class SmsImplBase {
- private static final String LOG_TAG = "SmsImplBase";
-
- @IntDef({
- SEND_STATUS_OK,
- SEND_STATUS_ERROR,
- SEND_STATUS_ERROR_RETRY,
- SEND_STATUS_ERROR_FALLBACK
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SendStatusResult {}
- /**
- * Message was sent successfully.
- */
- public static final int SEND_STATUS_OK = 1;
-
- /**
- * IMS provider failed to send the message and platform should not retry falling back to sending
- * the message using the radio.
- */
- public static final int SEND_STATUS_ERROR = 2;
-
- /**
- * IMS provider failed to send the message and platform should retry again after setting TP-RD bit
- * to high.
- */
- public static final int SEND_STATUS_ERROR_RETRY = 3;
-
- /**
- * IMS provider failed to send the message and platform should retry falling back to sending
- * the message using the radio.
- */
- public static final int SEND_STATUS_ERROR_FALLBACK = 4;
-
- @IntDef({
- DELIVER_STATUS_OK,
- DELIVER_STATUS_ERROR
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface DeliverStatusResult {}
- /**
- * Message was delivered successfully.
- */
- public static final int DELIVER_STATUS_OK = 1;
-
- /**
- * Message was not delivered.
- */
- public static final int DELIVER_STATUS_ERROR = 2;
-
- @IntDef({
- STATUS_REPORT_STATUS_OK,
- STATUS_REPORT_STATUS_ERROR
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface StatusReportResult {}
-
- /**
- * Status Report was set successfully.
- */
- public static final int STATUS_REPORT_STATUS_OK = 1;
-
- /**
- * Error while setting status report.
- */
- public static final int STATUS_REPORT_STATUS_ERROR = 2;
-
-
- // Lock for feature synchronization
- private final Object mLock = new Object();
- private IImsSmsListener mListener;
-
- /**
- * Registers a listener responsible for handling tasks like delivering messages.
- *
- * @param listener listener to register.
- *
- * @hide
- */
- public final void registerSmsListener(IImsSmsListener listener) {
- synchronized (mLock) {
- mListener = listener;
- }
- }
-
- /**
- * This method will be triggered by the platform when the user attempts to send an SMS. This
- * method should be implemented by the IMS providers to provide implementation of sending an SMS
- * over IMS.
- *
- * @param smsc the Short Message Service Center address.
- * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
- * {@link SmsMessage#FORMAT_3GPP2}.
- * @param messageRef the message reference.
- * @param isRetry whether it is a retry of an already attempted message or not.
- * @param pdu PDUs representing the contents of the message.
- */
- public void sendSms(int messageRef, String format, String smsc, boolean isRetry, byte[] pdu) {
- // Base implementation returns error. Should be overridden.
- try {
- onSendSmsResult(messageRef, SEND_STATUS_ERROR, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Can not send sms: " + e.getMessage());
- }
- }
-
- /**
- * This method will be triggered by the platform after {@link #onSmsReceived(String, byte[])} has
- * been called to deliver the result to the IMS provider.
- *
- * @param result result of delivering the message. Valid values are defined in
- * {@link DeliverStatusResult}
- * @param messageRef the message reference or -1 of unavailable.
- */
- public void acknowledgeSms(int messageRef, @DeliverStatusResult int result) {
-
- }
-
- /**
- * This method will be triggered by the platform after
- * {@link #onSmsStatusReportReceived(int, int, byte[])} has been called to provide the result to
- * the IMS provider.
- *
- * @param result result of delivering the message. Valid values are defined in
- * {@link StatusReportResult}
- * @param messageRef the message reference or -1 of unavailable.
- */
- public void acknowledgeSmsReport(int messageRef, @StatusReportResult int result) {
-
- }
-
- /**
- * This method should be triggered by the IMS providers when there is an incoming message. The
- * platform will deliver the message to the messages database and notify the IMS provider of the
- * result by calling {@link #acknowledgeSms(int, int)}.
- *
- * This method must not be called before {@link MmTelFeature#onFeatureReady()} is called.
- *
- * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
- * {@link SmsMessage#FORMAT_3GPP2}.
- * @param pdu PDUs representing the contents of the message.
- * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()}
- */
- public final void onSmsReceived(String format, byte[] pdu) throws IllegalStateException {
- synchronized (mLock) {
- if (mListener == null) {
- throw new IllegalStateException("Feature not ready.");
- }
- try {
- mListener.onSmsReceived(format, pdu);
- acknowledgeSms(-1, DELIVER_STATUS_OK);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Can not deliver sms: " + e.getMessage());
- acknowledgeSms(-1, DELIVER_STATUS_ERROR);
- }
- }
- }
-
- /**
- * This method should be triggered by the IMS providers to pass the result of the sent message
- * to the platform.
- *
- * This method must not be called before {@link MmTelFeature#onFeatureReady()} is called.
- *
- * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040
- * @param status result of sending the SMS. Valid values are defined in {@link SendStatusResult}
- * @param reason reason in case status is failure. Valid values are:
- * {@link SmsManager#RESULT_ERROR_NONE},
- * {@link SmsManager#RESULT_ERROR_GENERIC_FAILURE},
- * {@link SmsManager#RESULT_ERROR_RADIO_OFF},
- * {@link SmsManager#RESULT_ERROR_NULL_PDU},
- * {@link SmsManager#RESULT_ERROR_NO_SERVICE},
- * {@link SmsManager#RESULT_ERROR_LIMIT_EXCEEDED},
- * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NOT_ALLOWED},
- * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED}
- * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()}
- * @throws RemoteException if the connection to the framework is not available. If this happens
- * attempting to send the SMS should be aborted.
- */
- public final void onSendSmsResult(int messageRef, @SendStatusResult int status, int reason)
- throws IllegalStateException, RemoteException {
- synchronized (mLock) {
- if (mListener == null) {
- throw new IllegalStateException("Feature not ready.");
- }
- mListener.onSendSmsResult(messageRef, status, reason);
- }
- }
-
- /**
- * Sets the status report of the sent message.
- *
- * @param messageRef the message reference.
- * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
- * {@link SmsMessage#FORMAT_3GPP2}.
- * @param pdu PDUs representing the content of the status report.
- * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()}
- */
- public final void onSmsStatusReportReceived(int messageRef, String format, byte[] pdu) {
- synchronized (mLock) {
- if (mListener == null) {
- throw new IllegalStateException("Feature not ready.");
- }
- try {
- mListener.onSmsStatusReportReceived(messageRef, format, pdu);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage());
- acknowledgeSmsReport(messageRef, STATUS_REPORT_STATUS_ERROR);
- }
- }
- }
-
- /**
- * Returns the SMS format. Default is {@link SmsMessage#FORMAT_3GPP} unless overridden by IMS
- * Provider.
- *
- * @return the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
- * {@link SmsMessage#FORMAT_3GPP2}.
- */
- public String getSmsFormat() {
- return SmsMessage.FORMAT_3GPP;
- }
-
-}
diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl b/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl
index d976686..e226ada 100644
--- a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl
+++ b/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl
@@ -18,7 +18,6 @@
import android.os.Message;
import android.telephony.ims.internal.aidl.IImsMmTelListener;
-import android.telephony.ims.internal.aidl.IImsSmsListener;
import android.telephony.ims.internal.aidl.IImsCapabilityCallback;
import android.telephony.ims.internal.aidl.IImsCallSessionListener;
import android.telephony.ims.internal.feature.CapabilityChangeRequest;
@@ -50,10 +49,4 @@
IImsCapabilityCallback c);
oneway void queryCapabilityConfiguration(int capability, int radioTech,
IImsCapabilityCallback c);
- // SMS APIs
- void setSmsListener(IImsSmsListener l);
- oneway void sendSms(int messageRef, String format, String smsc, boolean retry, in byte[] pdu);
- oneway void acknowledgeSms(int messageRef, int result);
- oneway void acknowledgeSmsReport(int messageRef, int result);
- String getSmsFormat();
}
diff --git a/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java
index 057c9a86..9b576c7 100644
--- a/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java
@@ -21,14 +21,10 @@
import android.os.RemoteException;
import android.telecom.TelecomManager;
import android.telephony.ims.internal.ImsCallSessionListener;
-import android.telephony.ims.internal.SmsImplBase;
-import android.telephony.ims.internal.SmsImplBase.DeliverStatusResult;
-import android.telephony.ims.internal.SmsImplBase.StatusReportResult;
import android.telephony.ims.internal.aidl.IImsCallSessionListener;
import android.telephony.ims.internal.aidl.IImsCapabilityCallback;
import android.telephony.ims.internal.aidl.IImsMmTelFeature;
import android.telephony.ims.internal.aidl.IImsMmTelListener;
-import android.telephony.ims.internal.aidl.IImsSmsListener;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.ims.stub.ImsEcbmImplBase;
import android.telephony.ims.stub.ImsMultiEndpointImplBase;
@@ -68,11 +64,6 @@
}
@Override
- public void setSmsListener(IImsSmsListener l) throws RemoteException {
- MmTelFeature.this.setSmsListener(l);
- }
-
- @Override
public int getFeatureState() throws RemoteException {
synchronized (mLock) {
return MmTelFeature.this.getFeatureState();
@@ -152,34 +143,6 @@
IImsCapabilityCallback c) {
queryCapabilityConfigurationInternal(capability, radioTech, c);
}
-
- @Override
- public void sendSms(int messageRef, String format, String smsc, boolean retry, byte[] pdu) {
- synchronized (mLock) {
- MmTelFeature.this.sendSms(messageRef, format, smsc, retry, pdu);
- }
- }
-
- @Override
- public void acknowledgeSms(int messageRef, int result) {
- synchronized (mLock) {
- MmTelFeature.this.acknowledgeSms(messageRef, result);
- }
- }
-
- @Override
- public void acknowledgeSmsReport(int messageRef, int result) {
- synchronized (mLock) {
- MmTelFeature.this.acknowledgeSmsReport(messageRef, result);
- }
- }
-
- @Override
- public String getSmsFormat() {
- synchronized (mLock) {
- return MmTelFeature.this.getSmsFormat();
- }
- }
};
/**
@@ -291,10 +254,6 @@
}
}
- private void setSmsListener(IImsSmsListener listener) {
- getSmsImplementation().registerSmsListener(listener);
- }
-
private void queryCapabilityConfigurationInternal(int capability, int radioTech,
IImsCapabilityCallback c) {
boolean enabled = queryCapabilityConfiguration(capability, radioTech);
@@ -456,32 +415,6 @@
// Base Implementation - Should be overridden
}
- private void sendSms(int messageRef, String format, String smsc, boolean isRetry, byte[] pdu) {
- getSmsImplementation().sendSms(messageRef, format, smsc, isRetry, pdu);
- }
-
- private void acknowledgeSms(int messageRef, @DeliverStatusResult int result) {
- getSmsImplementation().acknowledgeSms(messageRef, result);
- }
-
- private void acknowledgeSmsReport(int messageRef, @StatusReportResult int result) {
- getSmsImplementation().acknowledgeSmsReport(messageRef, result);
- }
-
- private String getSmsFormat() {
- return getSmsImplementation().getSmsFormat();
- }
-
- /**
- * Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default
- * non-functional implementation is returned.
- *
- * @return an instance of {@link SmsImplBase} which should be implemented by the IMS Provider.
- */
- protected SmsImplBase getSmsImplementation() {
- return new SmsImplBase();
- }
-
/**{@inheritDoc}*/
@Override
public void onFeatureRemoved() {
diff --git a/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java b/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java
new file mode 100644
index 0000000..57df526
--- /dev/null
+++ b/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java
@@ -0,0 +1,313 @@
+/*
+ * 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.ims.internal.stub;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.os.RemoteException;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+import android.util.Log;
+
+import com.android.ims.internal.IImsSmsListener;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Base implementation for SMS over IMS.
+ *
+ * Any service wishing to provide SMS over IMS should extend this class and implement all methods
+ * that the service supports.
+ *
+ * @hide
+ */
+@SystemApi
+public class SmsImplBase {
+ private static final String LOG_TAG = "SmsImplBase";
+
+ /** @hide */
+ @IntDef({
+ SEND_STATUS_OK,
+ SEND_STATUS_ERROR,
+ SEND_STATUS_ERROR_RETRY,
+ SEND_STATUS_ERROR_FALLBACK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SendStatusResult {}
+ /**
+ * Message was sent successfully.
+ */
+ public static final int SEND_STATUS_OK = 1;
+
+ /**
+ * IMS provider failed to send the message and platform should not retry falling back to sending
+ * the message using the radio.
+ */
+ public static final int SEND_STATUS_ERROR = 2;
+
+ /**
+ * IMS provider failed to send the message and platform should retry again after setting TP-RD
+ * bit to high.
+ */
+ public static final int SEND_STATUS_ERROR_RETRY = 3;
+
+ /**
+ * IMS provider failed to send the message and platform should retry falling back to sending
+ * the message using the radio.
+ */
+ public static final int SEND_STATUS_ERROR_FALLBACK = 4;
+
+ /** @hide */
+ @IntDef({
+ DELIVER_STATUS_OK,
+ DELIVER_STATUS_ERROR
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeliverStatusResult {}
+ /**
+ * Message was delivered successfully.
+ */
+ public static final int DELIVER_STATUS_OK = 1;
+
+ /**
+ * Message was not delivered.
+ */
+ public static final int DELIVER_STATUS_ERROR = 2;
+
+ /** @hide */
+ @IntDef({
+ STATUS_REPORT_STATUS_OK,
+ STATUS_REPORT_STATUS_ERROR
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StatusReportResult {}
+
+ /**
+ * Status Report was set successfully.
+ */
+ public static final int STATUS_REPORT_STATUS_OK = 1;
+
+ /**
+ * Error while setting status report.
+ */
+ public static final int STATUS_REPORT_STATUS_ERROR = 2;
+
+
+ // Lock for feature synchronization
+ private final Object mLock = new Object();
+ private IImsSmsListener mListener;
+
+ /**
+ * Registers a listener responsible for handling tasks like delivering messages.
+ *
+ * @param listener listener to register.
+ *
+ * @hide
+ */
+ public final void registerSmsListener(IImsSmsListener listener) {
+ synchronized (mLock) {
+ mListener = listener;
+ }
+ }
+
+ /**
+ * This method will be triggered by the platform when the user attempts to send an SMS. This
+ * method should be implemented by the IMS providers to provide implementation of sending an SMS
+ * over IMS.
+ *
+ * @param token unique token generated by the platform that should be used when triggering
+ * callbacks for this specific message.
+ * @param messageRef the message reference.
+ * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
+ * {@link SmsMessage#FORMAT_3GPP2}.
+ * @param smsc the Short Message Service Center address.
+ * @param isRetry whether it is a retry of an already attempted message or not.
+ * @param pdu PDUs representing the contents of the message.
+ */
+ public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
+ byte[] pdu) {
+ // Base implementation returns error. Should be overridden.
+ try {
+ onSendSmsResult(token, messageRef, SEND_STATUS_ERROR,
+ SmsManager.RESULT_ERROR_GENERIC_FAILURE);
+ } catch (RuntimeException e) {
+ Log.e(LOG_TAG, "Can not send sms: " + e.getMessage());
+ }
+ }
+
+ /**
+ * This method will be triggered by the platform after
+ * {@link #onSmsReceived(int, String, byte[])} has been called to deliver the result to the IMS
+ * provider.
+ *
+ * @param token token provided in {@link #onSmsReceived(int, String, byte[])}
+ * @param result result of delivering the message. Valid values are:
+ * {@link #DELIVER_STATUS_OK},
+ * {@link #DELIVER_STATUS_OK}
+ * @param messageRef the message reference
+ */
+ public void acknowledgeSms(int token, @DeliverStatusResult int messageRef, int result) {
+ Log.e(LOG_TAG, "acknowledgeSms() not implemented.");
+ }
+
+ /**
+ * This method will be triggered by the platform after
+ * {@link #onSmsStatusReportReceived(int, int, String, byte[])} has been called to provide the
+ * result to the IMS provider.
+ *
+ * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])}
+ * @param result result of delivering the message. Valid values are:
+ * {@link #STATUS_REPORT_STATUS_OK},
+ * {@link #STATUS_REPORT_STATUS_ERROR}
+ * @param messageRef the message reference
+ */
+ public void acknowledgeSmsReport(int token, int messageRef, @StatusReportResult int result) {
+ Log.e(LOG_TAG, "acknowledgeSmsReport() not implemented.");
+ }
+
+ /**
+ * This method should be triggered by the IMS providers when there is an incoming message. The
+ * platform will deliver the message to the messages database and notify the IMS provider of the
+ * result by calling {@link #acknowledgeSms(int, int, int)}.
+ *
+ * This method must not be called before {@link #onReady()} is called.
+ *
+ * @param token unique token generated by IMS providers that the platform will use to trigger
+ * callbacks for this message.
+ * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
+ * {@link SmsMessage#FORMAT_3GPP2}.
+ * @param pdu PDUs representing the contents of the message.
+ * @throws RuntimeException if called before {@link #onReady()} is triggered.
+ */
+ public final void onSmsReceived(int token, String format, byte[] pdu) throws RuntimeException {
+ synchronized (mLock) {
+ if (mListener == null) {
+ throw new RuntimeException("Feature not ready.");
+ }
+ try {
+ mListener.onSmsReceived(token, format, pdu);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Can not deliver sms: " + e.getMessage());
+ acknowledgeSms(token, 0, DELIVER_STATUS_ERROR);
+ }
+ }
+ }
+
+ /**
+ * This method should be triggered by the IMS providers to pass the result of the sent message
+ * to the platform.
+ *
+ * This method must not be called before {@link #onReady()} is called.
+ *
+ * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])}
+ * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040
+ * @param status result of sending the SMS. Valid values are:
+ * {@link #SEND_STATUS_OK},
+ * {@link #SEND_STATUS_ERROR},
+ * {@link #SEND_STATUS_ERROR_RETRY},
+ * {@link #SEND_STATUS_ERROR_FALLBACK},
+ * @param reason reason in case status is failure. Valid values are:
+ * {@link SmsManager#RESULT_ERROR_NONE},
+ * {@link SmsManager#RESULT_ERROR_GENERIC_FAILURE},
+ * {@link SmsManager#RESULT_ERROR_RADIO_OFF},
+ * {@link SmsManager#RESULT_ERROR_NULL_PDU},
+ * {@link SmsManager#RESULT_ERROR_NO_SERVICE},
+ * {@link SmsManager#RESULT_ERROR_LIMIT_EXCEEDED},
+ * {@link SmsManager#RESULT_ERROR_FDN_CHECK_FAILURE},
+ * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NOT_ALLOWED},
+ * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED},
+ * {@link SmsManager#RESULT_RADIO_NOT_AVAILABLE},
+ * {@link SmsManager#RESULT_NETWORK_REJECT},
+ * {@link SmsManager#RESULT_INVALID_ARGUMENTS},
+ * {@link SmsManager#RESULT_INVALID_STATE},
+ * {@link SmsManager#RESULT_NO_MEMORY},
+ * {@link SmsManager#RESULT_INVALID_SMS_FORMAT},
+ * {@link SmsManager#RESULT_SYSTEM_ERROR},
+ * {@link SmsManager#RESULT_MODEM_ERROR},
+ * {@link SmsManager#RESULT_NETWORK_ERROR},
+ * {@link SmsManager#RESULT_ENCODING_ERROR},
+ * {@link SmsManager#RESULT_INVALID_SMSC_ADDRESS},
+ * {@link SmsManager#RESULT_OPERATION_NOT_ALLOWED},
+ * {@link SmsManager#RESULT_INTERNAL_ERROR},
+ * {@link SmsManager#RESULT_NO_RESOURCES},
+ * {@link SmsManager#RESULT_CANCELLED},
+ * {@link SmsManager#RESULT_REQUEST_NOT_SUPPORTED}
+ *
+ * @throws RuntimeException if called before {@link #onReady()} is triggered or if the
+ * connection to the framework is not available. If this happens attempting to send the SMS
+ * should be aborted.
+ */
+ public final void onSendSmsResult(int token, int messageRef, @SendStatusResult int status,
+ int reason) throws RuntimeException {
+ synchronized (mLock) {
+ if (mListener == null) {
+ throw new RuntimeException("Feature not ready.");
+ }
+ try {
+ mListener.onSendSmsResult(token, messageRef, status, reason);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Sets the status report of the sent message.
+ *
+ * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])}
+ * @param messageRef the message reference.
+ * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
+ * {@link SmsMessage#FORMAT_3GPP2}.
+ * @param pdu PDUs representing the content of the status report.
+ * @throws RuntimeException if called before {@link #onReady()} is triggered
+ */
+ public final void onSmsStatusReportReceived(int token, int messageRef, String format,
+ byte[] pdu) throws RuntimeException{
+ synchronized (mLock) {
+ if (mListener == null) {
+ throw new RuntimeException("Feature not ready.");
+ }
+ try {
+ mListener.onSmsStatusReportReceived(token, messageRef, format, pdu);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage());
+ acknowledgeSmsReport(token, messageRef, STATUS_REPORT_STATUS_ERROR);
+ }
+ }
+ }
+
+ /**
+ * Returns the SMS format. Default is {@link SmsMessage#FORMAT_3GPP} unless overridden by IMS
+ * Provider.
+ *
+ * @return the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and
+ * {@link SmsMessage#FORMAT_3GPP2}.
+ */
+ public String getSmsFormat() {
+ return SmsMessage.FORMAT_3GPP;
+ }
+
+ /**
+ * Called when SmsImpl has been initialized and communication with the framework is set up.
+ * Any attempt by this class to access the framework before this method is called will return
+ * with an {@link RuntimeException}.
+ */
+ public void onReady() {
+ // Base Implementation - Should be overridden
+ }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsErrors.java b/telephony/java/android/telephony/mbms/MbmsErrors.java
index af0af24..75ca35e 100644
--- a/telephony/java/android/telephony/mbms/MbmsErrors.java
+++ b/telephony/java/android/telephony/mbms/MbmsErrors.java
@@ -128,6 +128,9 @@
/** Indicates that the middleware has no record of the supplied {@link DownloadRequest}. */
public static final int ERROR_UNKNOWN_DOWNLOAD_REQUEST = 402;
+
+ /** Indicates the the middleware has no record of the supplied {@link FileInfo} */
+ public static final int ERROR_UNKNOWN_FILE_INFO = 403;
}
private MbmsErrors() {}
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
index cb93542..7d9845f 100755
--- a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl
@@ -46,7 +46,7 @@
int cancelDownload(in DownloadRequest downloadRequest);
- int getDownloadStatus(in DownloadRequest downloadRequest, in FileInfo fileInfo);
+ int requestDownloadState(in DownloadRequest downloadRequest, in FileInfo fileInfo);
int resetDownloadKnowledge(in DownloadRequest downloadRequest);
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
index 4fee3df..86b1b7a 100644
--- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java
@@ -370,18 +370,18 @@
}
/**
- * Gets information about the status of a file pending download.
+ * Requests information about the state of a file pending download.
*
- * If the middleware has not yet been properly initialized or if it has no records of the
+ * If the middleware has no records of the
* file indicated by {@code fileInfo} being associated with {@code downloadRequest},
- * {@link MbmsDownloadSession#STATUS_UNKNOWN} must be returned.
+ * {@link MbmsErrors.DownloadErrors#ERROR_UNKNOWN_FILE_INFO} must be returned.
*
* @param downloadRequest The download request to query.
* @param fileInfo The particular file within the request to get information on.
- * @return The status of the download.
+ * @return {@link MbmsErrors#SUCCESS} if the request was successful, an error code otherwise.
*/
@Override
- public int getDownloadStatus(DownloadRequest downloadRequest, FileInfo fileInfo)
+ public int requestDownloadState(DownloadRequest downloadRequest, FileInfo fileInfo)
throws RemoteException {
return 0;
}
diff --git a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl
index 52b3853..10c7f3e 100644
--- a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl
+++ b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl
@@ -25,6 +25,7 @@
import com.android.ims.internal.IImsEcbm;
import com.android.ims.internal.IImsMultiEndpoint;
import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsSmsListener;
import com.android.ims.internal.IImsUt;
import android.os.Message;
@@ -53,4 +54,12 @@
IImsEcbm getEcbmInterface();
void setUiTTYMode(int uiTtyMode, in Message onComplete);
IImsMultiEndpoint getMultiEndpointInterface();
+ // SMS APIs
+ void setSmsListener(IImsSmsListener l);
+ oneway void sendSms(in int token, int messageRef, String format, String smsc, boolean retry,
+ in byte[] pdu);
+ oneway void acknowledgeSms(int token, int messageRef, int result);
+ oneway void acknowledgeSmsReport(int token, int messageRef, int result);
+ String getSmsFormat();
+ oneway void onSmsReady();
}
diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsSmsListener.aidl b/telephony/java/com/android/ims/internal/IImsSmsListener.aidl
similarity index 67%
rename from telephony/java/android/telephony/ims/internal/aidl/IImsSmsListener.aidl
rename to telephony/java/com/android/ims/internal/IImsSmsListener.aidl
index 468629a..5a4b7e4 100644
--- a/telephony/java/android/telephony/ims/internal/aidl/IImsSmsListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsSmsListener.aidl
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-package android.telephony.ims.internal.aidl;
+package com.android.ims.internal;
/**
- * See MMTelFeature for more information.
+ * See SmsImplBase for more information.
* {@hide}
*/
interface IImsSmsListener {
- void onSendSmsResult(in int messageRef, in int status, in int reason);
- void onSmsStatusReportReceived(in int messageRef, in String format, in byte[] pdu);
- void onSmsReceived(in String format, in byte[] pdu);
+ void onSendSmsResult(int token, int messageRef, int status, int reason);
+ void onSmsStatusReportReceived(int token, int messageRef, in String format,
+ in byte[] pdu);
+ void onSmsReceived(int token, in String format, in byte[] pdu);
}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 91032f3..d999c13 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -108,6 +108,7 @@
public static final int EVENT_SET_CARRIER_DATA_ENABLED = BASE + 46;
public static final int EVENT_DATA_RECONNECT = BASE + 47;
public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
+ public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index cdee9e6..a3a3080 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -220,11 +220,6 @@
String SETUP_DATA_PROTOCOL_IPV6 = "IPV6";
String SETUP_DATA_PROTOCOL_IPV4V6 = "IPV4V6";
- /* Deactivate data call reasons */
- int DEACTIVATE_REASON_NONE = 0;
- int DEACTIVATE_REASON_RADIO_OFF = 1;
- int DEACTIVATE_REASON_PDP_RESET = 2;
-
/* NV config radio reset types. */
int NV_CONFIG_RELOAD_RESET = 1;
int NV_CONFIG_ERASE_RESET = 2;