diff options
29 files changed, 682 insertions, 129 deletions
diff --git a/Android.bp b/Android.bp index da4691776e98..dff7ff7b53dc 100644 --- a/Android.bp +++ b/Android.bp @@ -1152,7 +1152,7 @@ stubs_defaults { previous_api: ":last-released-public-api", merge_annotations_dirs: [ "metalava-manual", - "ojluni-annotated-stubs", + "ojluni-annotated-sdk-stubs", ], } @@ -1214,7 +1214,7 @@ stubs_defaults { previous_api: ":last-released-public-api", merge_annotations_dirs: [ "metalava-manual", - "ojluni-annotated-stubs", + "ojluni-annotated-sdk-stubs", ], } @@ -1485,7 +1485,7 @@ droidstubs { previous_api: ":last-released-public-api", merge_annotations_dirs: [ "metalava-manual", - "ojluni-annotated-stubs", + "ojluni-annotated-sdk-stubs", ], args: " --show-annotation android.annotation.SystemApi", } diff --git a/Android.mk b/Android.mk index 5e86e891fcc0..d33307425968 100644 --- a/Android.mk +++ b/Android.mk @@ -60,6 +60,9 @@ INTERNAL_SDK_SOURCE_DIRS := $(addprefix $(LOCAL_PATH)/,$(dirs_to_document)) $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE)) $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE)) $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE)) +$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE):apistubs/android/public/api/android.txt) +$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE):apistubs/android/system/api/android.txt) +$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE):apistubs/android/test/api/android.txt) # sdk.atree needs to copy the whole dir: $(OUT_DOCS)/offline-sdk to the final zip. # So keep offline-sdk-timestamp target here, and unzip offline-sdk-docs.zip to diff --git a/api/current.txt b/api/current.txt index d6f5466823c6..955b13b8c018 100755 --- a/api/current.txt +++ b/api/current.txt @@ -7698,7 +7698,9 @@ package android.bluetooth { method public boolean isMultipleAdvertisementSupported(); method public boolean isOffloadedFilteringSupported(); method public boolean isOffloadedScanBatchingSupported(); + method public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException; method public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException; + method public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException; method public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException; method public boolean setName(java.lang.String); method public boolean startDiscovery(); @@ -8066,7 +8068,9 @@ package android.bluetooth { method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int); method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler); method public boolean createBond(); + method public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException; method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException; + method public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException; method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException; method public int describeContents(); method public boolean fetchUuidsWithSdp(); @@ -8482,6 +8486,7 @@ package android.bluetooth { method public android.bluetooth.BluetoothSocket accept() throws java.io.IOException; method public android.bluetooth.BluetoothSocket accept(int) throws java.io.IOException; method public void close() throws java.io.IOException; + method public int getPsm(); } public final class BluetoothSocket implements java.io.Closeable { diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index fcd1e4cf85da..1f4f3c2b11db 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -2205,6 +2205,7 @@ Lcom/android/internal/telephony/IWapPushManager;->updatePackage(Ljava/lang/Strin Lcom/android/internal/telephony/SmsHeader$ConcatRef;-><init>()V Lcom/android/internal/telephony/SmsHeader$PortAddrs;-><init>()V Lcom/android/internal/telephony/SmsMessageBase;-><init>()V +Lcom/android/internal/telephony/uicc/IccUtils;->bytesToHexString([B)Ljava/lang/String; Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String; Lcom/android/internal/view/BaseIWindow;-><init>()V @@ -2318,6 +2319,108 @@ Lcom/android/org/conscrypt/TrustedCertificateStore;-><init>()V Lcom/android/org/conscrypt/TrustedCertificateStore;->getCertificateChain(Ljava/security/cert/X509Certificate;)Ljava/util/List; Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List; +Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList; +Lcom/google/android/mms/ContentType;->getImageTypes()Ljava/util/ArrayList; +Lcom/google/android/mms/ContentType;->getVideoTypes()Ljava/util/ArrayList; +Lcom/google/android/mms/ContentType;->isAudioType(Ljava/lang/String;)Z +Lcom/google/android/mms/ContentType;->isDrmType(Ljava/lang/String;)Z +Lcom/google/android/mms/ContentType;->isImageType(Ljava/lang/String;)Z +Lcom/google/android/mms/ContentType;->isTextType(Ljava/lang/String;)Z +Lcom/google/android/mms/ContentType;->isVideoType(Ljava/lang/String;)Z +Lcom/google/android/mms/MmsException;-><init>()V +Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/String;)V +Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/Throwable;)V +Lcom/google/android/mms/pdu/AcknowledgeInd;-><init>(I[B)V +Lcom/google/android/mms/pdu/CharacterSets;->getMimeName(I)Ljava/lang/String; +Lcom/google/android/mms/pdu/DeliveryInd;->getMessageId()[B +Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(I[B)V +Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(Ljava/lang/String;)V +Lcom/google/android/mms/pdu/EncodedStringValue;-><init>([B)V +Lcom/google/android/mms/pdu/EncodedStringValue;->concat([Lcom/google/android/mms/pdu/EncodedStringValue;)Ljava/lang/String; +Lcom/google/android/mms/pdu/EncodedStringValue;->encodeStrings([Ljava/lang/String;)[Lcom/google/android/mms/pdu/EncodedStringValue; +Lcom/google/android/mms/pdu/EncodedStringValue;->getString()Ljava/lang/String; +Lcom/google/android/mms/pdu/GenericPdu;->getMessageType()I +Lcom/google/android/mms/pdu/GenericPdu;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getBody()Lcom/google/android/mms/pdu/PduBody; +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getDate()J +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getPriority()I +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getSubject()Lcom/google/android/mms/pdu/EncodedStringValue; +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getTo()[Lcom/google/android/mms/pdu/EncodedStringValue; +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setBody(Lcom/google/android/mms/pdu/PduBody;)V +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setDate(J)V +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setPriority(I)V +Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setSubject(Lcom/google/android/mms/pdu/EncodedStringValue;)V +Lcom/google/android/mms/pdu/NotificationInd;->getContentLocation()[B +Lcom/google/android/mms/pdu/NotificationInd;->getExpiry()J +Lcom/google/android/mms/pdu/NotificationInd;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue; +Lcom/google/android/mms/pdu/NotificationInd;->getMessageClass()[B +Lcom/google/android/mms/pdu/NotificationInd;->getMessageSize()J +Lcom/google/android/mms/pdu/NotificationInd;->getSubject()Lcom/google/android/mms/pdu/EncodedStringValue; +Lcom/google/android/mms/pdu/NotificationInd;->getTransactionId()[B +Lcom/google/android/mms/pdu/NotificationInd;->setContentLocation([B)V +Lcom/google/android/mms/pdu/NotifyRespInd;-><init>(I[BI)V +Lcom/google/android/mms/pdu/PduBody;-><init>()V +Lcom/google/android/mms/pdu/PduBody;->addPart(ILcom/google/android/mms/pdu/PduPart;)V +Lcom/google/android/mms/pdu/PduBody;->addPart(Lcom/google/android/mms/pdu/PduPart;)Z +Lcom/google/android/mms/pdu/PduBody;->getPart(I)Lcom/google/android/mms/pdu/PduPart; +Lcom/google/android/mms/pdu/PduBody;->getPartByContentId(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; +Lcom/google/android/mms/pdu/PduBody;->getPartByContentLocation(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; +Lcom/google/android/mms/pdu/PduBody;->getPartByFileName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; +Lcom/google/android/mms/pdu/PduBody;->getPartByName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart; +Lcom/google/android/mms/pdu/PduBody;->getPartsNum()I +Lcom/google/android/mms/pdu/PduComposer;-><init>(Landroid/content/Context;Lcom/google/android/mms/pdu/GenericPdu;)V +Lcom/google/android/mms/pdu/PduComposer;->make()[B +Lcom/google/android/mms/pdu/PduParser;->parse()Lcom/google/android/mms/pdu/GenericPdu; +Lcom/google/android/mms/pdu/PduPart;-><init>()V +Lcom/google/android/mms/pdu/PduPart;->generateLocation()Ljava/lang/String; +Lcom/google/android/mms/pdu/PduPart;->getCharset()I +Lcom/google/android/mms/pdu/PduPart;->getContentLocation()[B +Lcom/google/android/mms/pdu/PduPart;->getContentType()[B +Lcom/google/android/mms/pdu/PduPart;->getData()[B +Lcom/google/android/mms/pdu/PduPart;->getDataUri()Landroid/net/Uri; +Lcom/google/android/mms/pdu/PduPart;->getFilename()[B +Lcom/google/android/mms/pdu/PduPart;->getName()[B +Lcom/google/android/mms/pdu/PduPart;->setCharset(I)V +Lcom/google/android/mms/pdu/PduPart;->setContentId([B)V +Lcom/google/android/mms/pdu/PduPart;->setContentLocation([B)V +Lcom/google/android/mms/pdu/PduPart;->setContentType([B)V +Lcom/google/android/mms/pdu/PduPart;->setData([B)V +Lcom/google/android/mms/pdu/PduPart;->setDataUri(Landroid/net/Uri;)V +Lcom/google/android/mms/pdu/PduPersister;->getBytes(Ljava/lang/String;)[B +Lcom/google/android/mms/pdu/PduPersister;->getPduPersister(Landroid/content/Context;)Lcom/google/android/mms/pdu/PduPersister; +Lcom/google/android/mms/pdu/PduPersister;->getPendingMessages(J)Landroid/database/Cursor; +Lcom/google/android/mms/pdu/PduPersister;->load(Landroid/net/Uri;)Lcom/google/android/mms/pdu/GenericPdu; +Lcom/google/android/mms/pdu/PduPersister;->move(Landroid/net/Uri;Landroid/net/Uri;)Landroid/net/Uri; +Lcom/google/android/mms/pdu/PduPersister;->persist(Lcom/google/android/mms/pdu/GenericPdu;Landroid/net/Uri;ZZLjava/util/HashMap;)Landroid/net/Uri; +Lcom/google/android/mms/pdu/PduPersister;->persistPart(Lcom/google/android/mms/pdu/PduPart;JLjava/util/HashMap;)Landroid/net/Uri; +Lcom/google/android/mms/pdu/PduPersister;->toIsoString([B)Ljava/lang/String; +Lcom/google/android/mms/pdu/PduPersister;->updateHeaders(Landroid/net/Uri;Lcom/google/android/mms/pdu/SendReq;)V +Lcom/google/android/mms/pdu/PduPersister;->updateParts(Landroid/net/Uri;Lcom/google/android/mms/pdu/PduBody;Ljava/util/HashMap;)V +Lcom/google/android/mms/pdu/ReadOrigInd;->getMessageId()[B +Lcom/google/android/mms/pdu/ReadRecInd;-><init>(Lcom/google/android/mms/pdu/EncodedStringValue;[BII[Lcom/google/android/mms/pdu/EncodedStringValue;)V +Lcom/google/android/mms/pdu/ReadRecInd;->setDate(J)V +Lcom/google/android/mms/pdu/RetrieveConf;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue; +Lcom/google/android/mms/pdu/RetrieveConf;->getMessageId()[B +Lcom/google/android/mms/pdu/RetrieveConf;->getTransactionId()[B +Lcom/google/android/mms/pdu/SendConf;->getMessageId()[B +Lcom/google/android/mms/pdu/SendConf;->getResponseStatus()I +Lcom/google/android/mms/pdu/SendConf;->getTransactionId()[B +Lcom/google/android/mms/pdu/SendReq;-><init>()V +Lcom/google/android/mms/pdu/SendReq;->getBcc()[Lcom/google/android/mms/pdu/EncodedStringValue; +Lcom/google/android/mms/pdu/SendReq;->getTransactionId()[B +Lcom/google/android/mms/pdu/SendReq;->setDeliveryReport(I)V +Lcom/google/android/mms/pdu/SendReq;->setExpiry(J)V +Lcom/google/android/mms/pdu/SendReq;->setMessageClass([B)V +Lcom/google/android/mms/pdu/SendReq;->setMessageSize(J)V +Lcom/google/android/mms/pdu/SendReq;->setReadReport(I)V +Lcom/google/android/mms/pdu/SendReq;->setTo([Lcom/google/android/mms/pdu/EncodedStringValue;)V +Lcom/google/android/mms/util/AbstractCache;->get(Ljava/lang/Object;)Ljava/lang/Object; +Lcom/google/android/mms/util/PduCache;->getInstance()Lcom/google/android/mms/util/PduCache; +Lcom/google/android/mms/util/PduCache;->isUpdating(Landroid/net/Uri;)Z +Lcom/google/android/mms/util/PduCache;->purge(Landroid/net/Uri;)Lcom/google/android/mms/util/PduCacheEntry; +Lcom/google/android/mms/util/PduCache;->purgeAll()V +Lcom/google/android/mms/util/PduCacheEntry;->getPdu()Lcom/google/android/mms/pdu/GenericPdu; +Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri; Ldalvik/system/BaseDexClassLoader;-><init>(Ljava/lang/String;Ljava/io/File;Ljava/lang/String;Ljava/lang/ClassLoader;Z)V Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;)V Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;Z)V @@ -2621,6 +2724,7 @@ Ljava/net/Socket;->impl:Ljava/net/SocketImpl; Ljava/net/SocketException;-><init>(Ljava/lang/String;Ljava/lang/Throwable;)V Ljava/net/SocketImpl;->serverSocket:Ljava/net/ServerSocket; Ljava/net/SocketImpl;->socket:Ljava/net/Socket; +Ljava/net/SocksSocketImpl;-><init>()V Ljava/net/URI;->fragment:Ljava/lang/String; Ljava/net/URI;->host:Ljava/lang/String; Ljava/net/URI;->port:I diff --git a/config/preloaded-classes b/config/preloaded-classes index 50e97c53fe83..63c583f9264c 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -1436,6 +1436,12 @@ android.hardware.usb.UsbDevice$1 android.hardware.usb.UsbDeviceConnection android.hardware.usb.UsbManager android.hardware.usb.UsbRequest +android.hidl.base.V1_0.DebugInfo +android.hidl.base.V1_0.IBase +android.hidl.manager.V1_0.IServiceManager +android.hidl.manager.V1_0.IServiceManager$Proxy +android.hidl.manager.V1_0.IServiceNotification +android.hidl.manager.V1_0.IServiceNotification$Stub android.icu.impl.BMPSet android.icu.impl.CacheBase android.icu.impl.CacheValue diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 4c655b5ac027..654bfaf293b8 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -81,7 +81,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; * {@link #getBondedDevices()}; start device discovery with * {@link #startDiscovery()}; or create a {@link BluetoothServerSocket} to * listen for incoming RFComm connection requests with {@link - * #listenUsingRfcommWithServiceRecord(String, UUID)}; or start a scan for + * #listenUsingRfcommWithServiceRecord(String, UUID)}; listen for incoming L2CAP Connection-oriented + * Channels (CoC) connection requests with {@link #listenUsingL2capChannel()}; or start a scan for * Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}. * </p> * <p>This class is thread safe.</p> @@ -2967,7 +2968,7 @@ public final class BluetoothAdapter { /** * Create a secure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and * assign a dynamic protocol/service multiplexer (PSM) value. This socket can be used to listen - * for incoming connections. + * for incoming connections. The supported Bluetooth transport is LE only. * <p>A remote device connecting to this socket will be authenticated and communication on this * socket will be encrypted. * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening @@ -2977,21 +2978,16 @@ public final class BluetoothAdapter { * closed, Bluetooth is turned off, or the application exits unexpectedly. * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is * defined and performed by the application. - * <p>Use {@link BluetoothDevice#createL2capCocSocket(int, int)} to connect to this server + * <p>Use {@link BluetoothDevice#createL2capChannel(int)} to connect to this server * socket from another Android device that is given the PSM value. * - * @param transport Bluetooth transport to use, must be {@link BluetoothDevice#TRANSPORT_LE} * @return an L2CAP CoC BluetoothServerSocket * @throws IOException on error, for example Bluetooth not available, or insufficient * permissions, or unable to start this CoC - * @hide */ @RequiresPermission(Manifest.permission.BLUETOOTH) - public BluetoothServerSocket listenUsingL2capCoc(int transport) + public BluetoothServerSocket listenUsingL2capChannel() throws IOException { - if (transport != BluetoothDevice.TRANSPORT_LE) { - throw new IllegalArgumentException("Unsupported transport: " + transport); - } BluetoothServerSocket socket = new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, true, true, SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false); @@ -3005,7 +3001,7 @@ public final class BluetoothAdapter { throw new IOException("Error: Unable to assign PSM value"); } if (DBG) { - Log.d(TAG, "listenUsingL2capCoc: set assigned PSM to " + Log.d(TAG, "listenUsingL2capChannel: set assigned PSM to " + assignedPsm); } socket.setChannel(assignedPsm); @@ -3014,10 +3010,23 @@ public final class BluetoothAdapter { } /** + * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new + * API name, listenUsingL2capChannel. + * @hide + */ + @RequiresPermission(Manifest.permission.BLUETOOTH) + public BluetoothServerSocket listenUsingL2capCoc(int transport) + throws IOException { + Log.e(TAG, "listenUsingL2capCoc: PLEASE USE THE OFFICIAL API, listenUsingL2capChannel"); + return listenUsingL2capChannel(); + } + + /** * Create an insecure L2CAP Connection-oriented Channel (CoC) {@link BluetoothServerSocket} and - * assign a dynamic PSM value. This socket can be used to listen for incoming connections. + * assign a dynamic PSM value. This socket can be used to listen for incoming connections. The + * supported Bluetooth transport is LE only. * <p>The link key is not required to be authenticated, i.e the communication may be vulnerable - * to man-in-the-middle attacks. Use {@link #listenUsingL2capCoc}, if an encrypted and + * to man-in-the-middle attacks. Use {@link #listenUsingL2capChannel}, if an encrypted and * authenticated communication channel is desired. * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening * {@link BluetoothServerSocket}. @@ -3027,21 +3036,16 @@ public final class BluetoothAdapter { * unexpectedly. * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is * defined and performed by the application. - * <p>Use {@link BluetoothDevice#createInsecureL2capCocSocket(int, int)} to connect to this - * server socket from another Android device that is given the PSM value. + * <p>Use {@link BluetoothDevice#createInsecureL2capChannel(int)} to connect to this server + * socket from another Android device that is given the PSM value. * - * @param transport Bluetooth transport to use, must be {@link BluetoothDevice#TRANSPORT_LE} * @return an L2CAP CoC BluetoothServerSocket * @throws IOException on error, for example Bluetooth not available, or insufficient * permissions, or unable to start this CoC - * @hide */ @RequiresPermission(Manifest.permission.BLUETOOTH) - public BluetoothServerSocket listenUsingInsecureL2capCoc(int transport) + public BluetoothServerSocket listenUsingInsecureL2capChannel() throws IOException { - if (transport != BluetoothDevice.TRANSPORT_LE) { - throw new IllegalArgumentException("Unsupported transport: " + transport); - } BluetoothServerSocket socket = new BluetoothServerSocket(BluetoothSocket.TYPE_L2CAP_LE, false, false, SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false, false); @@ -3055,11 +3059,24 @@ public final class BluetoothAdapter { throw new IOException("Error: Unable to assign PSM value"); } if (DBG) { - Log.d(TAG, "listenUsingInsecureL2capOn: set assigned PSM to " + Log.d(TAG, "listenUsingInsecureL2capChannel: set assigned PSM to " + assignedPsm); } socket.setChannel(assignedPsm); return socket; } + + /** + * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new + * API name, listenUsingInsecureL2capChannel. + * @hide + */ + @RequiresPermission(Manifest.permission.BLUETOOTH) + public BluetoothServerSocket listenUsingInsecureL2capCoc(int transport) + throws IOException { + Log.e(TAG, "listenUsingInsecureL2capCoc: PLEASE USE THE OFFICIAL API, " + + "listenUsingInsecureL2capChannel"); + return listenUsingInsecureL2capChannel(); + } } diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 818a749842f7..73e98cd99f8f 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -1963,8 +1963,8 @@ public final class BluetoothDevice implements Parcelable { /** * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can * be used to start a secure outgoing connection to the remote device with the same dynamic - * protocol/service multiplexer (PSM) value. - * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingL2capCoc(int)} for + * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only. + * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingL2capChannel()} for * peer-peer Bluetooth applications. * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection. * <p>Application using this API is responsible for obtaining PSM value from remote device. @@ -1975,59 +1975,71 @@ public final class BluetoothDevice implements Parcelable { * secure socket connection is not possible, use {#link createInsecureLeL2capCocSocket(int, * int)}. * - * @param transport Bluetooth transport to use, must be {@link #TRANSPORT_LE} * @param psm dynamic PSM value from remote device * @return a CoC #BluetoothSocket ready for an outgoing connection * @throws IOException on error, for example Bluetooth not available, or insufficient * permissions - * @hide */ @RequiresPermission(Manifest.permission.BLUETOOTH) - public BluetoothSocket createL2capCocSocket(int transport, int psm) throws IOException { + public BluetoothSocket createL2capChannel(int psm) throws IOException { if (!isBluetoothEnabled()) { - Log.e(TAG, "createL2capCocSocket: Bluetooth is not enabled"); + Log.e(TAG, "createL2capChannel: Bluetooth is not enabled"); throw new IOException(); } - if (transport != BluetoothDevice.TRANSPORT_LE) { - throw new IllegalArgumentException("Unsupported transport: " + transport); - } - if (DBG) Log.d(TAG, "createL2capCocSocket: transport=" + transport + ", psm=" + psm); + if (DBG) Log.d(TAG, "createL2capChannel: psm=" + psm); return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, true, true, this, psm, null); } /** + * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new + * API name, createL2capChannel. + * @hide + */ + @RequiresPermission(Manifest.permission.BLUETOOTH) + public BluetoothSocket createL2capCocSocket(int transport, int psm) throws IOException { + Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createL2capChannel"); + return createL2capChannel(psm); + } + + /** * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can * be used to start a secure outgoing connection to the remote device with the same dynamic - * protocol/service multiplexer (PSM) value. - * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingInsecureL2capCoc(int)} - * for peer-peer Bluetooth applications. + * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only. + * <p>This is designed to be used with {@link + * BluetoothAdapter#listenUsingInsecureL2capChannel()} for peer-peer Bluetooth applications. * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection. * <p>Application using this API is responsible for obtaining PSM value from remote device. * <p> The communication channel may not have an authenticated link key, i.e. it may be subject - * to man-in-the-middle attacks. Use {@link #createL2capCocSocket(int, int)} if an encrypted and + * to man-in-the-middle attacks. Use {@link #createL2capChannel(int)} if an encrypted and * authenticated communication channel is possible. * - * @param transport Bluetooth transport to use, must be {@link #TRANSPORT_LE} * @param psm dynamic PSM value from remote device * @return a CoC #BluetoothSocket ready for an outgoing connection * @throws IOException on error, for example Bluetooth not available, or insufficient * permissions - * @hide */ @RequiresPermission(Manifest.permission.BLUETOOTH) - public BluetoothSocket createInsecureL2capCocSocket(int transport, int psm) throws IOException { + public BluetoothSocket createInsecureL2capChannel(int psm) throws IOException { if (!isBluetoothEnabled()) { - Log.e(TAG, "createInsecureL2capCocSocket: Bluetooth is not enabled"); + Log.e(TAG, "createInsecureL2capChannel: Bluetooth is not enabled"); throw new IOException(); } - if (transport != BluetoothDevice.TRANSPORT_LE) { - throw new IllegalArgumentException("Unsupported transport: " + transport); - } if (DBG) { - Log.d(TAG, "createInsecureL2capCocSocket: transport=" + transport + ", psm=" + psm); + Log.d(TAG, "createInsecureL2capChannel: psm=" + psm); } return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, false, false, this, psm, null); } + + /** + * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new + * API name, createInsecureL2capChannel. + * @hide + */ + @RequiresPermission(Manifest.permission.BLUETOOTH) + public BluetoothSocket createInsecureL2capCocSocket(int transport, int psm) throws IOException { + Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createInsecureL2capChannel"); + return createInsecureL2capChannel(psm); + } } diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java index ba4b5a566799..5fc344a14f99 100644 --- a/core/java/android/bluetooth/BluetoothServerSocket.java +++ b/core/java/android/bluetooth/BluetoothServerSocket.java @@ -203,12 +203,11 @@ public final class BluetoothServerSocket implements Closeable { /** * Returns the assigned dynamic protocol/service multiplexer (PSM) value for the listening L2CAP * Connection-oriented Channel (CoC) server socket. This server socket must be returned by the - * {#link BluetoothAdapter.listenUsingL2capCoc(int)} or {#link - * BluetoothAdapter.listenUsingInsecureL2capCoc(int)}. The returned value is undefined if this + * {#link BluetoothAdapter.listenUsingL2capChannel()} or {#link + * BluetoothAdapter.listenUsingInsecureL2capChannel()}. The returned value is undefined if this * method is called on non-L2CAP server sockets. * * @return the assigned PSM or LE_PSM value depending on transport - * @hide */ public int getPsm() { return mChannel; diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index 780f896139f9..3a1e2f58c99d 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -667,6 +667,10 @@ public final class BluetoothSocket implements Closeable { * @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP} */ public int getConnectionType() { + if (mType == TYPE_L2CAP_LE) { + // Treat the LE CoC to be the same type as L2CAP. + return TYPE_L2CAP; + } return mType; } diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index 212e13262433..7aa223cdf909 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -124,7 +124,7 @@ import java.util.Set; * * <p><strong>Data Authority</strong> matches if any of the given values match * the Intent's data authority <em>and</em> one of the data schemes in the filter - * has matched the Intent, <em>or</em> no authories were supplied in the filter. + * has matched the Intent, <em>or</em> no authorities were supplied in the filter. * The Intent authority is determined by calling * {@link Intent#getData} and {@link android.net.Uri#getAuthority} on that URI. * <em>Note that authority matching here is <b>case sensitive</b>, unlike diff --git a/core/res/res/values-mcc262-mnc02/strings.xml b/core/res/res/values-mcc262-mnc02/strings.xml deleted file mode 100644 index 2b8940195ee3..000000000000 --- a/core/res/res/values-mcc262-mnc02/strings.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/** - * Copyright (c) 2017, Google Inc. - * - * 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. - */ ---> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - - <!-- Do not translate. Template for showing mobile network operator name while WFC is active --> - <string-array name="wfcSpnFormats"> - <item>%s</item> - <item>%s Wi-Fi Calling</item> - </string-array> -</resources> diff --git a/data/etc/platform.xml b/data/etc/platform.xml index c4017d15268f..73c10d238a60 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -210,6 +210,11 @@ <allow-in-power-save-except-idle package="com.android.providers.calendar" /> <allow-in-power-save-except-idle package="com.android.providers.contacts" /> + <!-- The PAC proxy process must have network access, otherwise no app will + be able to connect to the internet when such a proxy is in use, since + all outgoing connections originate from this app. --> + <allow-in-power-save-except-idle package="com.android.proxyhandler" /> + <!-- These are the packages that are white-listed to be able to run as system user --> <system-user-whitelisted-app package="com.android.settings" /> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java index ca1eea522cd0..af78c6faae24 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java @@ -29,7 +29,7 @@ import com.android.settingslib.R; import java.util.List; /** - * HidProfile handles Bluetooth HID profile. + * HidDeviceProfile handles Bluetooth HID Device role */ public class HidDeviceProfile implements LocalBluetoothProfile { private static final String TAG = "HidDeviceProfile"; @@ -37,7 +37,6 @@ public class HidDeviceProfile implements LocalBluetoothProfile { private static final int ORDINAL = 18; // HID Device Profile is always preferred. private static final int PREFERRED_VALUE = -1; - private static final boolean DEBUG = true; private final LocalBluetoothAdapter mLocalAdapter; private final CachedBluetoothDeviceManager mDeviceManager; @@ -62,9 +61,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (DEBUG) { - Log.d(TAG,"Bluetooth service connected :-)"); - } + Log.d(TAG, "Bluetooth service connected :-), profile:" + profile); mService = (BluetoothHidDevice) proxy; // We just bound to the service, so refresh the UI for any connected HID devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -84,9 +81,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (DEBUG) { - Log.d(TAG, "Bluetooth service disconnected"); - } + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mIsProfileReady = false; } } @@ -113,6 +108,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { @Override public boolean connect(BluetoothDevice device) { + // Don't invoke method in service because settings is not allowed to connect this profile. return false; } @@ -129,11 +125,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { if (mService == null) { return BluetoothProfile.STATE_DISCONNECTED; } - List<BluetoothDevice> deviceList = mService.getConnectedDevices(); - - return !deviceList.isEmpty() && deviceList.contains(device) - ? mService.getConnectionState(device) - : BluetoothProfile.STATE_DISCONNECTED; + return mService.getConnectionState(device); } @Override @@ -188,9 +180,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } protected void finalize() { - if (DEBUG) { - Log.d(TAG, "finalize()"); - } + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HID_DEVICE, diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java index ad0d8ba7ebab..e9fcc119d5d8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java @@ -32,11 +32,10 @@ import java.util.ArrayList; import java.util.List; /** - * MapClientProfile handles Bluetooth MAP profile. + * MapClientProfile handles the Bluetooth MAP MCE role. */ public final class MapClientProfile implements LocalBluetoothProfile { private static final String TAG = "MapClientProfile"; - private static boolean V = false; private BluetoothMapClient mService; private boolean mIsProfileReady; @@ -61,7 +60,7 @@ public final class MapClientProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); + Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothMapClient) proxy; // We just bound to the service, so refresh the UI for any connected MAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -83,14 +82,14 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } } public boolean isProfileReady() { - if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady); + Log.d(TAG, "isProfileReady(): "+ mIsProfileReady); return mIsProfileReady; } @@ -118,18 +117,16 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public boolean connect(BluetoothDevice device) { - if (mService == null) return false; - List<BluetoothDevice> connectedDevices = getConnectedDevices(); - if (connectedDevices != null && connectedDevices.contains(device)) { - // Connect to same device, Ignore it - Log.d(TAG,"Ignoring Connect"); - return true; + if (mService == null) { + return false; } return mService.connect(device); } public boolean disconnect(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } // Downgrade priority as user is disconnecting. if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -138,23 +135,30 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public int getConnectionStatus(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.STATE_DISCONNECTED; - + if (mService == null) { + return BluetoothProfile.STATE_DISCONNECTED; + } return mService.getConnectionState(device); } public boolean isPreferred(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; } public int getPreferred(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.PRIORITY_OFF; + if (mService == null) { + return BluetoothProfile.PRIORITY_OFF; + } return mService.getPriority(device); } public void setPreferred(BluetoothDevice device, boolean preferred) { - if (mService == null) return; + if (mService == null) { + return; + } if (preferred) { if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -165,7 +169,9 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public List<BluetoothDevice> getConnectedDevices() { - if (mService == null) return new ArrayList<BluetoothDevice>(0); + if (mService == null) { + return new ArrayList<BluetoothDevice>(0); + } return mService.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, @@ -203,11 +209,11 @@ public final class MapClientProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP_CLIENT, - mService); + mService); mService = null; }catch (Throwable t) { Log.w(TAG, "Error cleaning up MAP Client proxy", t); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HidDeviceProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HidDeviceProfileTest.java new file mode 100644 index 000000000000..354d9261dcb5 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HidDeviceProfileTest.java @@ -0,0 +1,92 @@ +/* + * 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.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHidDevice; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class HidDeviceProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothHidDevice mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private HidDeviceProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.HID_DEVICE)); + + mProfile = new HidDeviceProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.HID_DEVICE, mService); + } + + @Test + public void connect_shouldReturnFalse() { + assertThat(mProfile.connect(mBluetoothDevice)).isFalse(); + } + + @Test + public void disconnect_shouldDisconnectBluetoothHidDevice() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/MapClientProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/MapClientProfileTest.java new file mode 100644 index 000000000000..97c9f1817a64 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/MapClientProfileTest.java @@ -0,0 +1,93 @@ +/* + * 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.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothMapClient; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class MapClientProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothMapClient mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private MapClientProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.MAP_CLIENT)); + + mProfile = new MapClientProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.MAP_CLIENT, mService); + } + + @Test + public void connect_shouldConnectBluetoothMapClient() { + mProfile.connect(mBluetoothDevice); + verify(mService).connect(mBluetoothDevice); + } + + @Test + public void disconnect_shouldDisconnectBluetoothMapClient() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index 77ef63dd5aad..dea78630e4fe 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -53,10 +53,6 @@ public class OtaDexoptService extends IOtaDexopt.Stub { private final static String TAG = "OTADexopt"; private final static boolean DEBUG_DEXOPT = true; - // The synthetic library dependencies denoting "no checks." - private final static String[] NO_LIBRARIES = - new String[] { PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK }; - // The amount of "available" (free - low threshold) space necessary at the start of an OTA to // not bulk-delete unused apps' odex files. private final static long BULK_DELETE_THRESHOLD = 1024 * 1024 * 1024; // 1GB. @@ -288,8 +284,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { throws InstallerException { final StringBuilder builder = new StringBuilder(); - // The current version. - builder.append("9 "); + // The current version. For v10, see b/115993344. + builder.append("10 "); builder.append("dexopt"); @@ -338,11 +334,6 @@ public class OtaDexoptService extends IOtaDexopt.Stub { collectingInstaller, mPackageManagerService.mInstallLock, mContext); String[] libraryDependencies = pkg.usesLibraryFiles; - if (pkg.isSystem()) { - // For system apps, we want to avoid classpaths checks. - libraryDependencies = NO_LIBRARIES; - } - optimizer.performDexOpt(pkg, libraryDependencies, null /* ISAs */, diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk index a85f21cda901..bf7836d42008 100644 --- a/services/tests/servicestests/Android.mk +++ b/services/tests/servicestests/Android.mk @@ -9,7 +9,9 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests # Include all test java files. -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES := \ + $(call all-java-files-under, src) \ + $(call all-java-files-under, utils) \ LOCAL_STATIC_JAVA_LIBRARIES := \ frameworks-base-testutils \ diff --git a/services/tests/servicestests/src/com/android/server/testutils/OffsettableClock.java b/services/tests/servicestests/utils/com/android/server/testutils/OffsettableClock.java index 8dabbc4d4356..8dabbc4d4356 100644 --- a/services/tests/servicestests/src/com/android/server/testutils/OffsettableClock.java +++ b/services/tests/servicestests/utils/com/android/server/testutils/OffsettableClock.java diff --git a/services/tests/servicestests/src/com/android/server/testutils/TestHandler.java b/services/tests/servicestests/utils/com/android/server/testutils/TestHandler.java index 1222b59e92b9..1222b59e92b9 100644 --- a/services/tests/servicestests/src/com/android/server/testutils/TestHandler.java +++ b/services/tests/servicestests/utils/com/android/server/testutils/TestHandler.java diff --git a/services/tests/servicestests/src/com/android/server/testutils/TestUtils.java b/services/tests/servicestests/utils/com/android/server/testutils/TestUtils.java index b200293ee916..b200293ee916 100644 --- a/services/tests/servicestests/src/com/android/server/testutils/TestUtils.java +++ b/services/tests/servicestests/utils/com/android/server/testutils/TestUtils.java diff --git a/services/tests/wmtests/Android.mk b/services/tests/wmtests/Android.mk new file mode 100644 index 000000000000..0f8b18ab92cf --- /dev/null +++ b/services/tests/wmtests/Android.mk @@ -0,0 +1,41 @@ +######################################################################### +# Build WmTests package +######################################################################### + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# We only want this apk build for tests. +LOCAL_MODULE_TAGS := tests + +# Include all test java files. +LOCAL_SRC_FILES := \ + $(call all-java-files-under, src) \ + $(call all-java-files-under, ../servicestests/utils) + +LOCAL_STATIC_JAVA_LIBRARIES := \ + androidx-test \ + mockito-target-minus-junit4 \ + platform-test-annotations \ + +LOCAL_JAVA_LIBRARIES := \ + android.test.mock \ + android.test.base \ + android.test.runner \ + +LOCAL_PACKAGE_NAME := WmTests +LOCAL_PRIVATE_PLATFORM_APIS := true +LOCAL_COMPATIBILITY_SUITE := device-tests + +LOCAL_CERTIFICATE := platform + +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk + +LOCAL_JACK_FLAGS := --multi-dex native +LOCAL_DX_FLAGS := --multi-dex + +LOCAL_PROGUARD_ENABLED := disabled + +include $(BUILD_PACKAGE) + +include $(call all-makefiles-under, $(LOCAL_PATH)) diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml new file mode 100644 index 000000000000..1fb947309028 --- /dev/null +++ b/services/tests/wmtests/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.wmtests"> + + <!-- Uses API introduced in P (28) --> + <uses-sdk + android:minSdkVersion="1" + android:targetSdkVersion="28" /> + + <application android:testOnly="true" /> + + <instrumentation + android:name="androidx.test.runner.AndroidJUnitRunner" + android:label="Window Manager Tests" + android:targetPackage="com.android.frameworks.wmtests" /> +</manifest> diff --git a/services/tests/wmtests/AndroidTest.xml b/services/tests/wmtests/AndroidTest.xml new file mode 100644 index 000000000000..2717ef901216 --- /dev/null +++ b/services/tests/wmtests/AndroidTest.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<configuration description="Runs Window Manager Tests."> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-instrumentation" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="install-arg" value="-t" /> + <option name="test-file-name" value="WmTests.apk" /> + </target_preparer> + + <option name="test-tag" value="WmTests" /> + <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="com.android.frameworks.wmtests" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false" /> + </test> +</configuration> diff --git a/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java b/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java new file mode 100644 index 000000000000..023e4ab6636f --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java @@ -0,0 +1,46 @@ +/* + * 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.am; + +import android.platform.test.annotations.Presubmit; + +import org.junit.Test; + +import androidx.test.filters.FlakyTest; + +/** + * Dummy test for com.android.server.am. + * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests. + */ +public class DummyAmTests { + + @Presubmit + @Test + public void preSubmitTest() {} + + @FlakyTest + @Presubmit + @Test + public void flakyPreSubmitTest() {} + + @Test + public void postSubmitTest() {} + + @FlakyTest + @Test + public void flakyPostSubmitTest() {} +} diff --git a/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java b/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java new file mode 100644 index 000000000000..aecb2783badd --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java @@ -0,0 +1,46 @@ +/* + * 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.wm; + +import android.platform.test.annotations.Presubmit; + +import org.junit.Test; + +import androidx.test.filters.FlakyTest; + +/** + * Dummy test for com.android.server.wm + * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests. + */ +public class DummyWmTests { + + @Presubmit + @Test + public void preSubmitTest() {} + + @FlakyTest + @Presubmit + @Test + public void flakyPreSubmitTest() {} + + @Test + public void postSubmitTest() {} + + @FlakyTest + @Test + public void flakyPostSubmitTest() {} +} diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index b1be801bf284..ee0512ab25fc 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1087,6 +1087,15 @@ public class CarrierConfigManager { public static final String KEY_WFC_DATA_SPN_FORMAT_IDX_INT = "wfc_data_spn_format_idx_int"; /** + * Use root locale when reading wfcSpnFormats. + * + * If true, then the root locale will always be used when reading wfcSpnFormats. This means the + * non localized version of wfcSpnFormats will be used. + * @hide + */ + public static final String KEY_WFC_SPN_USE_ROOT_LOCALE = "wfc_spn_use_root_locale"; + + /** * The Component Name of the activity that can setup the emergency addrees for WiFi Calling * as per carrier requirement. * @hide @@ -2274,6 +2283,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_WFC_OPERATOR_ERROR_CODES_STRING_ARRAY, null); sDefaults.putInt(KEY_WFC_SPN_FORMAT_IDX_INT, 0); sDefaults.putInt(KEY_WFC_DATA_SPN_FORMAT_IDX_INT, 0); + sDefaults.putBoolean(KEY_WFC_SPN_USE_ROOT_LOCALE, false); sDefaults.putString(KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING, ""); sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false); sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false); @@ -2283,7 +2293,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false); sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false); - sDefaults.putBoolean(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL, false); + sDefaults.putBoolean(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL, true); // MMS defaults sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 0c8280b9e086..8f7993cc7251 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -59,6 +59,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -1810,6 +1811,19 @@ public class SubscriptionManager { */ @UnsupportedAppUsage public static Resources getResourcesForSubId(Context context, int subId) { + return getResourcesForSubId(context, subId, false); + } + + /** + * Returns the resources associated with Subscription. + * @param context Context object + * @param subId Subscription Id of Subscription who's resources are required + * @param useRootLocale if root locale should be used. Localized locale is used if false. + * @return Resources associated with Subscription. + * @hide + */ + public static Resources getResourcesForSubId(Context context, int subId, + boolean useRootLocale) { final SubscriptionInfo subInfo = SubscriptionManager.from(context).getActiveSubscriptionInfo(subId); @@ -1821,6 +1835,11 @@ public class SubscriptionManager { newConfig.mnc = subInfo.getMnc(); if (newConfig.mnc == 0) newConfig.mnc = Configuration.MNC_ZERO; } + + if (useRootLocale) { + newConfig.setLocale(Locale.ROOT); + } + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); DisplayMetrics newMetrics = new DisplayMetrics(); newMetrics.setTo(metrics); diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java index 4790b75d9630..6b3df94063bf 100644 --- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java +++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java @@ -93,11 +93,23 @@ public class IccUtils { * converted. If the array size is more than needed, the rest of array remains unchanged. */ public static void bcdToBytes(String bcd, byte[] bytes) { + bcdToBytes(bcd, bytes, 0); + } + + /** + * Converts BCD string to bytes and put it into the given byte array. + * + * @param bcd This should have an even length. If not, an "0" will be appended to the string. + * @param bytes If the array size is less than needed, the rest of the BCD string isn't be + * converted. If the array size is more than needed, the rest of array remains unchanged. + * @param offset the offset into the bytes[] to fill the data + */ + public static void bcdToBytes(String bcd, byte[] bytes, int offset) { if (bcd.length() % 2 != 0) { bcd += "0"; } - int size = Math.min(bytes.length * 2, bcd.length()); - for (int i = 0, j = 0; i + 1 < size; i += 2, j++) { + int size = Math.min((bytes.length - offset) * 2, bcd.length()); + for (int i = 0, j = offset; i + 1 < size; i += 2, j++) { bytes[j] = (byte) (charToByte(bcd.charAt(i + 1)) << 4 | charToByte(bcd.charAt(i))); } } @@ -125,6 +137,20 @@ public class IccUtils { } /** + * Convert a 5 or 6 - digit PLMN string to a nibble-swizzled encoding as per 24.008 10.5.1.3 + * + * @param plmn the PLMN to convert + * @param data a byte array for the output + * @param offset the offset into data to start writing + */ + public static void stringToBcdPlmn(final String plmn, byte[] data, int offset) { + char digit6 = (plmn.length() > 5) ? plmn.charAt(5) : 'F'; + data[offset] = (byte) (charToByte(plmn.charAt(1)) << 4 | charToByte(plmn.charAt(0))); + data[offset + 1] = (byte) (charToByte(digit6) << 4 | charToByte(plmn.charAt(2))); + data[offset + 2] = (byte) (charToByte(plmn.charAt(4)) << 4 | charToByte(plmn.charAt(3))); + } + + /** * Some fields (like ICC ID) in GSM SIMs are stored as nibble-swizzled BCH */ public static String @@ -844,7 +870,7 @@ public class IccUtils { } /** - * Converts a character of [0-9a-aA-F] to its hex value in a byte. If the character is not a + * Converts a character of [0-9a-fA-F] to its hex value in a byte. If the character is not a * hex number, 0 will be returned. */ private static byte charToByte(char c) { |