diff options
120 files changed, 2919 insertions, 1947 deletions
diff --git a/Android.bp b/Android.bp index 6b61467b1a27..b83c63fdf3a1 100644 --- a/Android.bp +++ b/Android.bp @@ -12,12 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Build ext.jar +// ============================================================ +java_library { + name: "ext", + no_framework_libs: true, + static_libs: [ + "libphonenumber-platform", + "nist-sip", + "tagsoup", + ], + dxflags: ["--core-library"], +} + // ==== c++ proto device library ============================== cc_library { name: "libplatformprotos", host_supported: true, - // b/34740546, work around clang-tidy segmentation fault. - tidy_checks: ["-modernize*"], proto: { export_proto_headers: true, include_dirs: ["external/protobuf/src"], @@ -63,3 +74,25 @@ subdirs = [ optional_subdirs = [ "core/tests/utiltests/jni", ] + +java_library { + name: "hwbinder", + no_framework_libs: true, + + srcs: [ + "core/java/android/os/HidlSupport.java", + "core/java/android/annotation/NonNull.java", + "core/java/android/os/HwBinder.java", + "core/java/android/os/HwBlob.java", + "core/java/android/os/HwParcel.java", + "core/java/android/os/IHwBinder.java", + "core/java/android/os/IHwInterface.java", + "core/java/android/os/DeadObjectException.java", + "core/java/android/os/DeadSystemException.java", + "core/java/android/os/RemoteException.java", + "core/java/android/util/AndroidException.java", + ], + + dxflags: ["--core-library"], + installable: false, +} diff --git a/Android.mk b/Android.mk index b92f31e80f07..a437501c85e6 100644 --- a/Android.mk +++ b/Android.mk @@ -611,32 +611,6 @@ $(framework_module): | $(dir $(framework_module))framework-res.apk framework_built := $(call java-lib-deps,framework) -# HwBinder -# ======================================================= -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - core/java/android/os/HidlSupport.java \ - core/java/android/annotation/NonNull.java \ - core/java/android/os/HwBinder.java \ - core/java/android/os/HwBlob.java \ - core/java/android/os/HwParcel.java \ - core/java/android/os/IHwBinder.java \ - core/java/android/os/IHwInterface.java \ - core/java/android/os/DeadObjectException.java \ - core/java/android/os/DeadSystemException.java \ - core/java/android/os/RemoteException.java \ - core/java/android/util/AndroidException.java \ - -LOCAL_NO_STANDARD_LIBRARIES := true -LOCAL_JAVA_LIBRARIES := core-oj core-libart -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := hwbinder - -LOCAL_DX_FLAGS := --core-library -LOCAL_UNINSTALLABLE_MODULE := true -include $(BUILD_JAVA_LIBRARY) - # Copy AIDL files to be preprocessed and included in the SDK, # specified relative to the root of the build tree. # ============================================================ @@ -1463,35 +1437,6 @@ LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk include $(BUILD_DROIDDOC) -# Build ext.jar -# ============================================================ - -ext_dirs := \ - ../../external/nist-sip/java \ - ../../external/tagsoup/src \ - -ext_src_files := $(call all-java-files-under,$(ext_dirs)) - -# ==== the library ========================================= -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(ext_src_files) - -LOCAL_NO_STANDARD_LIBRARIES := true -LOCAL_JAVA_LIBRARIES := core-oj core-libart -LOCAL_STATIC_JAVA_LIBRARIES := libphonenumber-platform -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := ext - -LOCAL_DX_FLAGS := --core-library - -ifneq ($(INCREMENTAL_BUILDS),) - LOCAL_PROGUARD_ENABLED := disabled - LOCAL_JACK_ENABLED := incremental -endif - -include $(BUILD_JAVA_LIBRARY) - # ==== java proto host library ============================== include $(CLEAR_VARS) LOCAL_MODULE := platformprotos diff --git a/api/current.txt b/api/current.txt index c1f05e51836f..a0cd51b238f1 100644 --- a/api/current.txt +++ b/api/current.txt @@ -39833,8 +39833,12 @@ package android.telephony { field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT"; field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO"; field public static final int RESULT_CANCELLED = 2; // 0x2 + field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6 field public static final int RESULT_EXPIRED = 3; // 0x3 + field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8 field public static final int RESULT_IO_ERROR = 4; // 0x4 + field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7 + field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5 field public static final int RESULT_SUCCESSFUL = 1; // 0x1 field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1 field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2 @@ -40500,18 +40504,22 @@ package android.telephony.mbms { } public static class DownloadRequest.Builder { - ctor public DownloadRequest.Builder(); + ctor public DownloadRequest.Builder(android.net.Uri); method public android.telephony.mbms.DownloadRequest build(); method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent); method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo); - method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri); method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int); } public class DownloadStateCallback { ctor public DownloadStateCallback(); + ctor public DownloadStateCallback(int); + method public final boolean isFilterFlagSet(int); method public void onProgressUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int, int, int, int); method public void onStateUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int); + field public static final int ALL_UPDATES = 0; // 0x0 + field public static final int PROGRESS_UPDATES = 1; // 0x1 + field public static final int STATE_UPDATES = 2; // 0x2 } public final class FileInfo implements android.os.Parcelable { @@ -40585,6 +40593,7 @@ package android.telephony.mbms { public class ServiceInfo { method public java.util.List<java.util.Locale> getLocales(); method public java.lang.CharSequence getNameForLocale(java.util.Locale); + method public java.util.Set<java.util.Locale> getNamedContentLocales(); method public java.lang.String getServiceClassName(); method public java.lang.String getServiceId(); method public java.util.Date getSessionEndTime(); @@ -52139,6 +52148,8 @@ package dalvik.bytecode { field public static final int OP_CONST_CLASS = 28; // 0x1c field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff field public static final int OP_CONST_HIGH16 = 21; // 0x15 + field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe + field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff field public static final int OP_CONST_STRING = 26; // 0x1a field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b field public static final int OP_CONST_WIDE = 24; // 0x18 diff --git a/api/system-current.txt b/api/system-current.txt index 0ce7908166cc..c9b656bad18f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -43265,8 +43265,12 @@ package android.telephony { field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO"; field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload"; field public static final int RESULT_CANCELLED = 2; // 0x2 + field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6 field public static final int RESULT_EXPIRED = 3; // 0x3 + field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8 field public static final int RESULT_IO_ERROR = 4; // 0x4 + field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7 + field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5 field public static final int RESULT_SUCCESSFUL = 1; // 0x1 field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1 field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2 @@ -44017,20 +44021,24 @@ package android.telephony.mbms { } public static class DownloadRequest.Builder { - ctor public DownloadRequest.Builder(); + ctor public DownloadRequest.Builder(android.net.Uri); method public android.telephony.mbms.DownloadRequest build(); method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent); method public android.telephony.mbms.DownloadRequest.Builder setOpaqueData(byte[]); method public android.telephony.mbms.DownloadRequest.Builder setServiceId(java.lang.String); method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo); - method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri); method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int); } public class DownloadStateCallback { ctor public DownloadStateCallback(); + ctor public DownloadStateCallback(int); + method public final boolean isFilterFlagSet(int); method public void onProgressUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int, int, int, int); method public void onStateUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int); + field public static final int ALL_UPDATES = 0; // 0x0 + field public static final int PROGRESS_UPDATES = 1; // 0x1 + field public static final int STATE_UPDATES = 2; // 0x2 } public final class FileInfo implements android.os.Parcelable { @@ -44113,6 +44121,7 @@ package android.telephony.mbms { public class ServiceInfo { method public java.util.List<java.util.Locale> getLocales(); method public java.lang.CharSequence getNameForLocale(java.util.Locale); + method public java.util.Set<java.util.Locale> getNamedContentLocales(); method public java.lang.String getServiceClassName(); method public java.lang.String getServiceId(); method public java.util.Date getSessionEndTime(); @@ -56119,6 +56128,8 @@ package dalvik.bytecode { field public static final int OP_CONST_CLASS = 28; // 0x1c field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff field public static final int OP_CONST_HIGH16 = 21; // 0x15 + field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe + field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff field public static final int OP_CONST_STRING = 26; // 0x1a field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b field public static final int OP_CONST_WIDE = 24; // 0x18 diff --git a/api/test-current.txt b/api/test-current.txt index 685e06ac640b..6936d5618f72 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -40055,8 +40055,12 @@ package android.telephony { field public static final java.lang.String EXTRA_MBMS_DOWNLOAD_RESULT = "android.telephony.extra.MBMS_DOWNLOAD_RESULT"; field public static final java.lang.String EXTRA_MBMS_FILE_INFO = "android.telephony.extra.MBMS_FILE_INFO"; field public static final int RESULT_CANCELLED = 2; // 0x2 + field public static final int RESULT_DOWNLOAD_FAILURE = 6; // 0x6 field public static final int RESULT_EXPIRED = 3; // 0x3 + field public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; // 0x8 field public static final int RESULT_IO_ERROR = 4; // 0x4 + field public static final int RESULT_OUT_OF_STORAGE = 7; // 0x7 + field public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; // 0x5 field public static final int RESULT_SUCCESSFUL = 1; // 0x1 field public static final int STATUS_ACTIVELY_DOWNLOADING = 1; // 0x1 field public static final int STATUS_PENDING_DOWNLOAD = 2; // 0x2 @@ -40722,18 +40726,22 @@ package android.telephony.mbms { } public static class DownloadRequest.Builder { - ctor public DownloadRequest.Builder(); + ctor public DownloadRequest.Builder(android.net.Uri); method public android.telephony.mbms.DownloadRequest build(); method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent); method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo); - method public android.telephony.mbms.DownloadRequest.Builder setSource(android.net.Uri); method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int); } public class DownloadStateCallback { ctor public DownloadStateCallback(); + ctor public DownloadStateCallback(int); + method public final boolean isFilterFlagSet(int); method public void onProgressUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int, int, int, int); method public void onStateUpdated(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo, int); + field public static final int ALL_UPDATES = 0; // 0x0 + field public static final int PROGRESS_UPDATES = 1; // 0x1 + field public static final int STATE_UPDATES = 2; // 0x2 } public final class FileInfo implements android.os.Parcelable { @@ -40807,6 +40815,7 @@ package android.telephony.mbms { public class ServiceInfo { method public java.util.List<java.util.Locale> getLocales(); method public java.lang.CharSequence getNameForLocale(java.util.Locale); + method public java.util.Set<java.util.Locale> getNamedContentLocales(); method public java.lang.String getServiceClassName(); method public java.lang.String getServiceId(); method public java.util.Date getSessionEndTime(); @@ -52563,6 +52572,8 @@ package dalvik.bytecode { field public static final int OP_CONST_CLASS = 28; // 0x1c field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff field public static final int OP_CONST_HIGH16 = 21; // 0x15 + field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe + field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff field public static final int OP_CONST_STRING = 26; // 0x1a field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b field public static final int OP_CONST_WIDE = 24; // 0x18 diff --git a/compiled-classes-phone b/config/compiled-classes-phone index 71fc5c17a595..063276d9ef27 100644 --- a/compiled-classes-phone +++ b/config/compiled-classes-phone @@ -26,7 +26,7 @@ # to your device.mk, e.g., # # PRODUCT_COPY_FILES += \ -# frameworks/base/compiled-classes-phone:system/etc/compiled-classes +# frameworks/base/config/compiled-classes-phone:system/etc/compiled-classes # android.R$styleable android.accessibilityservice.AccessibilityServiceInfo diff --git a/dirty-image-objects b/config/dirty-image-objects index 9b4d199dc723..9b4d199dc723 100644 --- a/dirty-image-objects +++ b/config/dirty-image-objects diff --git a/preloaded-classes b/config/preloaded-classes index c1896aa3937a..8233b03614bc 100644 --- a/preloaded-classes +++ b/config/preloaded-classes @@ -2286,6 +2286,7 @@ android.util.IntProperty android.util.Log android.util.Log$1 android.util.Log$ImmediateLogWriter +android.util.Log$PreloadHolder android.util.Log$TerribleFailure android.util.Log$TerribleFailureHandler android.util.LogPrinter diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 70591d4d0587..84765f6d7280 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1134,6 +1134,29 @@ public final class BluetoothAdapter { } /** + * Sets the {@link BluetoothClass} Bluetooth Class of Device (CoD) of + * the local Bluetooth adapter. + * + * @param bluetoothClass {@link BluetoothClass} to set the local Bluetooth adapter to. + * @return true if successful, false if unsuccessful. + * + * @hide + */ + @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED) + public boolean setBluetoothClass(BluetoothClass bluetoothClass) { + if (getState() != STATE_ON) return false; + try { + mServiceLock.readLock().lock(); + if (mService != null) return mService.setBluetoothClass(bluetoothClass); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } + return false; + } + + /** * Get the current Bluetooth scan mode of the local Bluetooth adapter. * <p>The Bluetooth scan mode determines if the local adapter is * connectable and/or discoverable from remote Bluetooth devices. diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java index 57e4abb12987..f22ea6e88e04 100755 --- a/core/java/android/bluetooth/BluetoothClass.java +++ b/core/java/android/bluetooth/BluetoothClass.java @@ -19,6 +19,10 @@ package android.bluetooth; import android.os.Parcel; import android.os.Parcelable; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + /** * Represents a Bluetooth class, which describes general characteristics * and capabilities of a device. For example, a Bluetooth class will @@ -275,6 +279,48 @@ public final class BluetoothClass implements Parcelable { return (mClass & Device.BITMASK); } + /** + * Return the Bluetooth Class of Device (CoD) value including the + * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and + * minor device fields. + * + * <p>This value is an integer representation of Bluetooth CoD as in + * Bluetooth specification. + * + * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a> + * + * @hide + */ + public int getClassOfDevice() { + return mClass; + } + + /** + * Return the Bluetooth Class of Device (CoD) value including the + * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and + * minor device fields. + * + * <p>This value is a byte array representation of Bluetooth CoD as in + * Bluetooth specification. + * + * <p>Bluetooth COD information is 3 bytes, but stored as an int. Hence the + * MSB is useless and needs to be thrown away. The lower 3 bytes are + * converted into a byte array MSB to LSB. Hence, using BIG_ENDIAN. + * + * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a> + * + * @hide + */ + public byte[] getClassOfDeviceBytes() { + byte[] bytes = ByteBuffer.allocate(4) + .order(ByteOrder.BIG_ENDIAN) + .putInt(mClass) + .array(); + + // Discard the top byte + return Arrays.copyOfRange(bytes, 1, bytes.length); + } + /** @hide */ public static final int PROFILE_HEADSET = 0; /** @hide */ diff --git a/core/java/android/bluetooth/BluetoothInputHost.java b/core/java/android/bluetooth/BluetoothInputHost.java index 37f04278d461..e18d9d1be51b 100644 --- a/core/java/android/bluetooth/BluetoothInputHost.java +++ b/core/java/android/bluetooth/BluetoothInputHost.java @@ -74,7 +74,7 @@ public final class BluetoothInputHost implements BluetoothProfile { public static final byte SUBCLASS2_GAMEPAD = (byte) 0x02; public static final byte SUBCLASS2_REMOTE_CONTROL = (byte) 0x03; public static final byte SUBCLASS2_SENSING_DEVICE = (byte) 0x04; - public static final byte SUBCLASS2_DIGITIZER_TABLED = (byte) 0x05; + public static final byte SUBCLASS2_DIGITIZER_TABLET = (byte) 0x05; public static final byte SUBCLASS2_CARD_READER = (byte) 0x06; /** diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java index 19f5198ca71a..a1a9347df690 100644 --- a/core/java/android/bluetooth/BluetoothPbap.java +++ b/core/java/android/bluetooth/BluetoothPbap.java @@ -16,6 +16,7 @@ package android.bluetooth; +import android.annotation.SdkConstant; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -53,35 +54,32 @@ public class BluetoothPbap { private static final boolean DBG = true; private static final boolean VDBG = false; - /** int extra for PBAP_STATE_CHANGED_ACTION */ - public static final String PBAP_STATE = - "android.bluetooth.pbap.intent.PBAP_STATE"; - /** int extra for PBAP_STATE_CHANGED_ACTION */ - public static final String PBAP_PREVIOUS_STATE = - "android.bluetooth.pbap.intent.PBAP_PREVIOUS_STATE"; - /** - * Indicates the state of a pbap connection state has changed. - * This intent will always contain PBAP_STATE, PBAP_PREVIOUS_STATE and - * BluetoothIntent.ADDRESS extras. + * Intent used to broadcast the change in connection state of the PBAP + * profile. + * + * <p>This intent will have 3 extras: + * <ul> + * <li> {@link BluetoothProfile#EXTRA_STATE} - The current state of the profile. </li> + * <li> {@link BluetoothProfile#EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li> + * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li> + * </ul> + * <p>{@link BluetoothProfile#EXTRA_STATE} or {@link BluetoothProfile#EXTRA_PREVIOUS_STATE} + * can be any of {@link BluetoothProfile#STATE_DISCONNECTED}, + * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, + * {@link BluetoothProfile#STATE_DISCONNECTING}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to + * receive. */ - public static final String PBAP_STATE_CHANGED_ACTION = - "android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED"; + @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_CONNECTION_STATE_CHANGED = + "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED"; private volatile IBluetoothPbap mService; private final Context mContext; private ServiceListener mServiceListener; private BluetoothAdapter mAdapter; - /** There was an error trying to obtain the state */ - public static final int STATE_ERROR = -1; - /** No client currently connected */ - public static final int STATE_DISCONNECTED = 0; - /** Connection attempt in progress */ - public static final int STATE_CONNECTING = 1; - /** Client is currently connected */ - public static final int STATE_CONNECTED = 2; - public static final int RESULT_FAILURE = 0; public static final int RESULT_SUCCESS = 1; /** Connection canceled before completion. */ @@ -209,8 +207,8 @@ public class BluetoothPbap { /** * Get the current state of the BluetoothPbap service. * - * @return One of the STATE_ return codes, or STATE_ERROR if this proxy object is currently not - * connected to the Pbap service. + * @return One of the STATE_ return codes, or {@link BluetoothProfile#STATE_DISCONNECTED} + * if this proxy object is currently not connected to the Pbap service. */ public int getState() { if (VDBG) log("getState()"); @@ -225,7 +223,7 @@ public class BluetoothPbap { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } - return BluetoothPbap.STATE_ERROR; + return BluetoothProfile.STATE_DISCONNECTED; } /** diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java index 00a15f3f7087..01b3f6e0e841 100644 --- a/core/java/android/bluetooth/BluetoothPbapClient.java +++ b/core/java/android/bluetooth/BluetoothPbapClient.java @@ -40,7 +40,7 @@ public final class BluetoothPbapClient implements BluetoothProfile { private static final boolean VDBG = false; public static final String ACTION_CONNECTION_STATE_CHANGED = - "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED"; + "android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED"; private volatile IBluetoothPbapClient mService; private final Context mContext; diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 3460f564fcb8..0ccebc1c7a55 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1125,6 +1125,7 @@ public class ConnectivityManager { * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl() { try { return mService.getCaptivePortalServerUrl(); @@ -2083,15 +2084,30 @@ public class ConnectivityManager { * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or * due to device configuration. * + * <p>If this app does not have permission to use this API, it will always + * return false rather than throw an exception.</p> + * + * <p>If the device has a hotspot provisioning app, the caller is required to hold the + * {@link android.Manifest.permission.TETHER_PRIVILEGED} permission.</p> + * + * <p>Otherwise, this method requires the caller to hold the ability to modify system + * settings as determined by {@link android.provider.Settings.System#canWrite}.</p> + * * @return a boolean - {@code true} indicating Tethering is supported. * * {@hide} */ @SystemApi - @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED, + android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported() { + String pkgName = mContext.getOpPackageName(); try { - return mService.isTetheringSupported(); + return mService.isTetheringSupported(pkgName); + } catch (SecurityException e) { + // This API is not available to this caller, but for backward-compatibility + // this will just return false instead of throwing. + return false; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2121,6 +2137,7 @@ public class ConnectivityManager { * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int type, boolean showProvisioningUi, final OnStartTetheringCallback callback) { startTethering(type, showProvisioningUi, callback, null); diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index b9dd207aaa42..a6fe7389bc72 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -75,7 +75,7 @@ interface IConnectivityManager int getLastTetherError(String iface); - boolean isTetheringSupported(); + boolean isTetheringSupported(String callerPkg); void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi, String callerPkg); diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java index ead406c20c93..79310e295a27 100644 --- a/core/java/android/net/IpSecAlgorithm.java +++ b/core/java/android/net/IpSecAlgorithm.java @@ -24,6 +24,7 @@ import com.android.internal.util.HexDump; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; /** * IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to @@ -75,13 +76,7 @@ public final class IpSecAlgorithm implements Parcelable { public static final String AUTH_HMAC_SHA512 = "hmac(sha512)"; /** @hide */ - @StringDef({ - CRYPT_AES_CBC, - AUTH_HMAC_MD5, - AUTH_HMAC_SHA1, - AUTH_HMAC_SHA256, - AUTH_HMAC_SHA512 - }) + @StringDef({CRYPT_AES_CBC, AUTH_HMAC_MD5, AUTH_HMAC_SHA1, AUTH_HMAC_SHA256, AUTH_HMAC_SHA512}) @Retention(RetentionPolicy.SOURCE) public @interface AlgorithmName {} @@ -197,4 +192,12 @@ public final class IpSecAlgorithm implements Parcelable { .append("}") .toString(); } + + /** package */ + static boolean equals(IpSecAlgorithm lhs, IpSecAlgorithm rhs) { + if (lhs == null || rhs == null) return (lhs == rhs); + return (lhs.mName.equals(rhs.mName) + && Arrays.equals(lhs.mKey, rhs.mKey) + && lhs.mTruncLenBits == rhs.mTruncLenBits); + } }; diff --git a/core/java/android/net/IpSecConfig.java b/core/java/android/net/IpSecConfig.java index 5a5c740c7aa8..632b7fc07f0c 100644 --- a/core/java/android/net/IpSecConfig.java +++ b/core/java/android/net/IpSecConfig.java @@ -17,105 +17,170 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; -import java.net.InetAddress; -import java.net.UnknownHostException; + +import com.android.internal.annotations.VisibleForTesting; /** @hide */ public final class IpSecConfig implements Parcelable { private static final String TAG = "IpSecConfig"; - //MODE_TRANSPORT or MODE_TUNNEL - int mode; + // MODE_TRANSPORT or MODE_TUNNEL + private int mMode = IpSecTransform.MODE_TRANSPORT; - // For tunnel mode - InetAddress localAddress; + // Needs to be valid only for tunnel mode + // Preventing this from being null simplifies Java->Native binder + private String mLocalAddress = ""; - InetAddress remoteAddress; + // Preventing this from being null simplifies Java->Native binder + private String mRemoteAddress = ""; - // Limit selection by network interface - Network network; + // The underlying Network that represents the "gateway" Network + // for outbound packets. It may also be used to select packets. + private Network mNetwork; public static class Flow { // Minimum requirements for identifying a transform // SPI identifying the IPsec flow in packet processing // and a remote IP address - int spiResourceId; + private int mSpiResourceId = IpSecManager.INVALID_RESOURCE_ID; // Encryption Algorithm - IpSecAlgorithm encryption; + private IpSecAlgorithm mEncryption; // Authentication Algorithm - IpSecAlgorithm authentication; + private IpSecAlgorithm mAuthentication; @Override public String toString() { return new StringBuilder() - .append("{spiResourceId=") - .append(spiResourceId) - .append(", encryption=") - .append(encryption) - .append(", authentication=") - .append(authentication) + .append("{mSpiResourceId=") + .append(mSpiResourceId) + .append(", mEncryption=") + .append(mEncryption) + .append(", mAuthentication=") + .append(mAuthentication) .append("}") .toString(); } + + static boolean equals(IpSecConfig.Flow lhs, IpSecConfig.Flow rhs) { + if (lhs == null || rhs == null) return (lhs == rhs); + return (lhs.mSpiResourceId == rhs.mSpiResourceId + && IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption) + && IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)); + } } - final Flow[] flow = new Flow[] {new Flow(), new Flow()}; + private final Flow[] mFlow = new Flow[] {new Flow(), new Flow()}; // For tunnel mode IPv4 UDP Encapsulation // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE - int encapType; - int encapLocalPortResourceId; - int encapRemotePort; + private int mEncapType = IpSecTransform.ENCAP_NONE; + private int mEncapSocketResourceId = IpSecManager.INVALID_RESOURCE_ID; + private int mEncapRemotePort; // An interval, in seconds between the NattKeepalive packets - int nattKeepaliveInterval; + private int mNattKeepaliveInterval; + + /** Set the mode for this IPsec transform */ + public void setMode(int mode) { + mMode = mode; + } + + /** Set the local IP address for Tunnel mode */ + public void setLocalAddress(String localAddress) { + if (localAddress == null) { + throw new IllegalArgumentException("localAddress may not be null!"); + } + mLocalAddress = localAddress; + } + + /** Set the remote IP address for this IPsec transform */ + public void setRemoteAddress(String remoteAddress) { + if (remoteAddress == null) { + throw new IllegalArgumentException("remoteAddress may not be null!"); + } + mRemoteAddress = remoteAddress; + } + + /** Set the SPI for a given direction by resource ID */ + public void setSpiResourceId(int direction, int resourceId) { + mFlow[direction].mSpiResourceId = resourceId; + } + + /** Set the encryption algorithm for a given direction */ + public void setEncryption(int direction, IpSecAlgorithm encryption) { + mFlow[direction].mEncryption = encryption; + } + + /** Set the authentication algorithm for a given direction */ + public void setAuthentication(int direction, IpSecAlgorithm authentication) { + mFlow[direction].mAuthentication = authentication; + } + + public void setNetwork(Network network) { + mNetwork = network; + } + + public void setEncapType(int encapType) { + mEncapType = encapType; + } + + public void setEncapSocketResourceId(int resourceId) { + mEncapSocketResourceId = resourceId; + } + + public void setEncapRemotePort(int port) { + mEncapRemotePort = port; + } + + public void setNattKeepaliveInterval(int interval) { + mNattKeepaliveInterval = interval; + } // Transport or Tunnel public int getMode() { - return mode; + return mMode; } - public InetAddress getLocalAddress() { - return localAddress; + public String getLocalAddress() { + return mLocalAddress; } public int getSpiResourceId(int direction) { - return flow[direction].spiResourceId; + return mFlow[direction].mSpiResourceId; } - public InetAddress getRemoteAddress() { - return remoteAddress; + public String getRemoteAddress() { + return mRemoteAddress; } public IpSecAlgorithm getEncryption(int direction) { - return flow[direction].encryption; + return mFlow[direction].mEncryption; } public IpSecAlgorithm getAuthentication(int direction) { - return flow[direction].authentication; + return mFlow[direction].mAuthentication; } public Network getNetwork() { - return network; + return mNetwork; } public int getEncapType() { - return encapType; + return mEncapType; } - public int getEncapLocalResourceId() { - return encapLocalPortResourceId; + public int getEncapSocketResourceId() { + return mEncapSocketResourceId; } public int getEncapRemotePort() { - return encapRemotePort; + return mEncapRemotePort; } public int getNattKeepaliveInterval() { - return nattKeepaliveInterval; + return mNattKeepaliveInterval; } // Parcelable Methods @@ -127,82 +192,70 @@ public final class IpSecConfig implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { - // TODO: Use a byte array or other better method for storing IPs that can also include scope - out.writeString((localAddress != null) ? localAddress.getHostAddress() : null); - // TODO: Use a byte array or other better method for storing IPs that can also include scope - out.writeString((remoteAddress != null) ? remoteAddress.getHostAddress() : null); - out.writeParcelable(network, flags); - out.writeInt(flow[IpSecTransform.DIRECTION_IN].spiResourceId); - out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].encryption, flags); - out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].authentication, flags); - out.writeInt(flow[IpSecTransform.DIRECTION_OUT].spiResourceId); - out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].encryption, flags); - out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].authentication, flags); - out.writeInt(encapType); - out.writeInt(encapLocalPortResourceId); - out.writeInt(encapRemotePort); - } - - // Package Private: Used by the IpSecTransform.Builder; - // there should be no public constructor for this object - IpSecConfig() {} - - private static InetAddress readInetAddressFromParcel(Parcel in) { - String addrString = in.readString(); - if (addrString == null) { - return null; - } - try { - return InetAddress.getByName(addrString); - } catch (UnknownHostException e) { - Log.wtf(TAG, "Invalid IpAddress " + addrString); - return null; - } + out.writeInt(mMode); + out.writeString(mLocalAddress); + out.writeString(mRemoteAddress); + out.writeParcelable(mNetwork, flags); + out.writeInt(mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId); + out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mEncryption, flags); + out.writeParcelable(mFlow[IpSecTransform.DIRECTION_IN].mAuthentication, flags); + out.writeInt(mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId); + out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mEncryption, flags); + out.writeParcelable(mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication, flags); + out.writeInt(mEncapType); + out.writeInt(mEncapSocketResourceId); + out.writeInt(mEncapRemotePort); + out.writeInt(mNattKeepaliveInterval); } + @VisibleForTesting + public IpSecConfig() {} + private IpSecConfig(Parcel in) { - localAddress = readInetAddressFromParcel(in); - remoteAddress = readInetAddressFromParcel(in); - network = (Network) in.readParcelable(Network.class.getClassLoader()); - flow[IpSecTransform.DIRECTION_IN].spiResourceId = in.readInt(); - flow[IpSecTransform.DIRECTION_IN].encryption = + mMode = in.readInt(); + mLocalAddress = in.readString(); + mRemoteAddress = in.readString(); + mNetwork = (Network) in.readParcelable(Network.class.getClassLoader()); + mFlow[IpSecTransform.DIRECTION_IN].mSpiResourceId = in.readInt(); + mFlow[IpSecTransform.DIRECTION_IN].mEncryption = (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); - flow[IpSecTransform.DIRECTION_IN].authentication = + mFlow[IpSecTransform.DIRECTION_IN].mAuthentication = (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); - flow[IpSecTransform.DIRECTION_OUT].spiResourceId = in.readInt(); - flow[IpSecTransform.DIRECTION_OUT].encryption = + mFlow[IpSecTransform.DIRECTION_OUT].mSpiResourceId = in.readInt(); + mFlow[IpSecTransform.DIRECTION_OUT].mEncryption = (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); - flow[IpSecTransform.DIRECTION_OUT].authentication = + mFlow[IpSecTransform.DIRECTION_OUT].mAuthentication = (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); - encapType = in.readInt(); - encapLocalPortResourceId = in.readInt(); - encapRemotePort = in.readInt(); + mEncapType = in.readInt(); + mEncapSocketResourceId = in.readInt(); + mEncapRemotePort = in.readInt(); + mNattKeepaliveInterval = in.readInt(); } @Override public String toString() { StringBuilder strBuilder = new StringBuilder(); strBuilder - .append("{mode=") - .append(mode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT") - .append(", localAddress=") - .append(localAddress) - .append(", remoteAddress=") - .append(remoteAddress) - .append(", network=") - .append(network) - .append(", encapType=") - .append(encapType) - .append(", encapLocalPortResourceId=") - .append(encapLocalPortResourceId) - .append(", encapRemotePort=") - .append(encapRemotePort) - .append(", nattKeepaliveInterval=") - .append(nattKeepaliveInterval) - .append(", flow[OUT]=") - .append(flow[IpSecTransform.DIRECTION_OUT]) - .append(", flow[IN]=") - .append(flow[IpSecTransform.DIRECTION_IN]) + .append("{mMode=") + .append(mMode == IpSecTransform.MODE_TUNNEL ? "TUNNEL" : "TRANSPORT") + .append(", mLocalAddress=") + .append(mLocalAddress) + .append(", mRemoteAddress=") + .append(mRemoteAddress) + .append(", mNetwork=") + .append(mNetwork) + .append(", mEncapType=") + .append(mEncapType) + .append(", mEncapSocketResourceId=") + .append(mEncapSocketResourceId) + .append(", mEncapRemotePort=") + .append(mEncapRemotePort) + .append(", mNattKeepaliveInterval=") + .append(mNattKeepaliveInterval) + .append(", mFlow[OUT]=") + .append(mFlow[IpSecTransform.DIRECTION_OUT]) + .append(", mFlow[IN]=") + .append(mFlow[IpSecTransform.DIRECTION_IN]) .append("}"); return strBuilder.toString(); @@ -218,4 +271,23 @@ public final class IpSecConfig implements Parcelable { return new IpSecConfig[size]; } }; + + @VisibleForTesting + /** Equals method used for testing */ + public static boolean equals(IpSecConfig lhs, IpSecConfig rhs) { + if (lhs == null || rhs == null) return (lhs == rhs); + return (lhs.mMode == rhs.mMode + && lhs.mLocalAddress.equals(rhs.mLocalAddress) + && lhs.mRemoteAddress.equals(rhs.mRemoteAddress) + && ((lhs.mNetwork != null && lhs.mNetwork.equals(rhs.mNetwork)) + || (lhs.mNetwork == rhs.mNetwork)) + && lhs.mEncapType == rhs.mEncapType + && lhs.mEncapSocketResourceId == rhs.mEncapSocketResourceId + && lhs.mEncapRemotePort == rhs.mEncapRemotePort + && lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval + && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_OUT], + rhs.mFlow[IpSecTransform.DIRECTION_OUT]) + && IpSecConfig.Flow.equals(lhs.mFlow[IpSecTransform.DIRECTION_IN], + rhs.mFlow[IpSecTransform.DIRECTION_IN])); + } } diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index d7908c8ceef8..d7b325613fee 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -26,6 +26,8 @@ import android.os.RemoteException; import android.util.AndroidException; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + import dalvik.system.CloseGuard; import java.io.FileDescriptor; @@ -188,7 +190,8 @@ public final class IpSecManager { } /** @hide */ - int getResourceId() { + @VisibleForTesting + public int getResourceId() { return mResourceId; } } @@ -489,7 +492,8 @@ public final class IpSecManager { } /** @hide */ - int getResourceId() { + @VisibleForTesting + public int getResourceId() { return mResourceId; } }; diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java index 62fd65b9c176..e15a2c672c20 100644 --- a/core/java/android/net/IpSecTransform.java +++ b/core/java/android/net/IpSecTransform.java @@ -68,10 +68,10 @@ public final class IpSecTransform implements AutoCloseable { public @interface TransformDirection {} /** @hide */ - public static final int MODE_TUNNEL = 0; + public static final int MODE_TRANSPORT = 0; /** @hide */ - public static final int MODE_TRANSPORT = 1; + public static final int MODE_TUNNEL = 1; /** @hide */ public static final int ENCAP_NONE = 0; @@ -113,7 +113,11 @@ public final class IpSecTransform implements AutoCloseable { return IIpSecService.Stub.asInterface(b); } - private void checkResultStatusAndThrow(int status) + /** + * Checks the result status and throws an appropriate exception if + * the status is not Status.OK. + */ + private void checkResultStatus(int status) throws IOException, IpSecManager.ResourceUnavailableException, IpSecManager.SpiUnavailableException { switch (status) { @@ -141,7 +145,7 @@ public final class IpSecTransform implements AutoCloseable { IpSecTransformResponse result = svc.createTransportModeTransform(mConfig, new Binder()); int status = result.status; - checkResultStatusAndThrow(status); + checkResultStatus(status); mResourceId = result.resourceId; /* Keepalive will silently fail if not needed by the config; but, if needed and @@ -243,61 +247,20 @@ public final class IpSecTransform implements AutoCloseable { /* Package */ void startKeepalive(Context c) { - // FIXME: NO_KEEPALIVE needs to be a constant - if (mConfig.getNattKeepaliveInterval() == 0) { - return; - } - - ConnectivityManager cm = - (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE); - - if (mKeepalive != null) { - Log.wtf(TAG, "Keepalive already started for this IpSecTransform."); - return; - } - - synchronized (mKeepaliveSyncLock) { - mKeepalive = - cm.startNattKeepalive( - mConfig.getNetwork(), - mConfig.getNattKeepaliveInterval(), - mKeepaliveCallback, - mConfig.getLocalAddress(), - 0x1234, /* FIXME: get the real port number again, - which we need to retrieve from the provided - EncapsulationSocket, and which isn't currently - stashed in IpSecConfig */ - mConfig.getRemoteAddress()); - try { - // FIXME: this is still a horrible way to fudge the synchronous callback - mKeepaliveSyncLock.wait(2000); - } catch (InterruptedException e) { - } - } - if (mKeepaliveStatus != ConnectivityManager.PacketKeepalive.SUCCESS) { - throw new UnsupportedOperationException("Packet Keepalive cannot be started"); + if (mConfig.getNattKeepaliveInterval() != 0) { + Log.wtf(TAG, "Keepalive not yet supported."); } } - /* Package */ - int getResourceId() { + /** @hide */ + @VisibleForTesting + public int getResourceId() { return mResourceId; } /* Package */ void stopKeepalive() { - if (mKeepalive == null) { - return; - } - mKeepalive.stop(); - synchronized (mKeepaliveSyncLock) { - if (mKeepaliveStatus == ConnectivityManager.PacketKeepalive.SUCCESS) { - try { - mKeepaliveSyncLock.wait(2000); - } catch (InterruptedException e) { - } - } - } + return; } /** @@ -323,7 +286,7 @@ public final class IpSecTransform implements AutoCloseable { */ public IpSecTransform.Builder setEncryption( @TransformDirection int direction, IpSecAlgorithm algo) { - mConfig.flow[direction].encryption = algo; + mConfig.setEncryption(direction, algo); return this; } @@ -338,7 +301,7 @@ public final class IpSecTransform implements AutoCloseable { */ public IpSecTransform.Builder setAuthentication( @TransformDirection int direction, IpSecAlgorithm algo) { - mConfig.flow[direction].authentication = algo; + mConfig.setAuthentication(direction, algo); return this; } @@ -361,9 +324,7 @@ public final class IpSecTransform implements AutoCloseable { */ public IpSecTransform.Builder setSpi( @TransformDirection int direction, IpSecManager.SecurityParameterIndex spi) { - // TODO: convert to using the resource Id of the SPI. Then build() can validate - // the owner in the IpSecService - mConfig.flow[direction].spiResourceId = spi.getResourceId(); + mConfig.setSpiResourceId(direction, spi.getResourceId()); return this; } @@ -378,7 +339,7 @@ public final class IpSecTransform implements AutoCloseable { */ @SystemApi public IpSecTransform.Builder setUnderlyingNetwork(Network net) { - mConfig.network = net; + mConfig.setNetwork(net); return this; } @@ -395,10 +356,9 @@ public final class IpSecTransform implements AutoCloseable { */ public IpSecTransform.Builder setIpv4Encapsulation( IpSecManager.UdpEncapsulationSocket localSocket, int remotePort) { - // TODO: check encap type is valid. - mConfig.encapType = ENCAP_ESPINUDP; - mConfig.encapLocalPortResourceId = localSocket.getResourceId(); - mConfig.encapRemotePort = remotePort; + mConfig.setEncapType(ENCAP_ESPINUDP); + mConfig.setEncapSocketResourceId(localSocket.getResourceId()); + mConfig.setEncapRemotePort(remotePort); return this; } @@ -416,7 +376,7 @@ public final class IpSecTransform implements AutoCloseable { */ @SystemApi public IpSecTransform.Builder setNattKeepalive(int intervalSeconds) { - mConfig.nattKeepaliveInterval = intervalSeconds; + mConfig.setNattKeepaliveInterval(intervalSeconds); return this; } @@ -449,10 +409,8 @@ public final class IpSecTransform implements AutoCloseable { public IpSecTransform buildTransportModeTransform(InetAddress remoteAddress) throws IpSecManager.ResourceUnavailableException, IpSecManager.SpiUnavailableException, IOException { - //FIXME: argument validation here - //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation"); - mConfig.mode = MODE_TRANSPORT; - mConfig.remoteAddress = remoteAddress; + mConfig.setMode(MODE_TRANSPORT); + mConfig.setRemoteAddress(remoteAddress.getHostAddress()); return new IpSecTransform(mContext, mConfig).activate(); } @@ -473,9 +431,9 @@ public final class IpSecTransform implements AutoCloseable { InetAddress localAddress, InetAddress remoteAddress) { //FIXME: argument validation here //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation"); - mConfig.localAddress = localAddress; - mConfig.remoteAddress = remoteAddress; - mConfig.mode = MODE_TUNNEL; + mConfig.setLocalAddress(localAddress.getHostAddress()); + mConfig.setRemoteAddress(remoteAddress.getHostAddress()); + mConfig.setMode(MODE_TUNNEL); return new IpSecTransform(mContext, mConfig); } @@ -489,14 +447,5 @@ public final class IpSecTransform implements AutoCloseable { mContext = context; mConfig = new IpSecConfig(); } - - /** - * Return an {@link IpSecConfig} object for testing purposes. - * @hide - */ - @VisibleForTesting - public IpSecConfig getIpSecConfig() { - return mConfig; - } } } diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 2c9fb23e077a..4e474c8e478c 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -683,9 +683,9 @@ public final class LinkProperties implements Parcelable { */ public boolean hasIPv4Address() { for (LinkAddress address : mLinkAddresses) { - if (address.getAddress() instanceof Inet4Address) { - return true; - } + if (address.getAddress() instanceof Inet4Address) { + return true; + } } return false; } @@ -725,9 +725,9 @@ public final class LinkProperties implements Parcelable { */ public boolean hasIPv4DefaultRoute() { for (RouteInfo r : mRoutes) { - if (r.isIPv4Default()) { - return true; - } + if (r.isIPv4Default()) { + return true; + } } return false; } @@ -740,9 +740,9 @@ public final class LinkProperties implements Parcelable { */ public boolean hasIPv6DefaultRoute() { for (RouteInfo r : mRoutes) { - if (r.isIPv6Default()) { - return true; - } + if (r.isIPv6Default()) { + return true; + } } return false; } @@ -755,9 +755,9 @@ public final class LinkProperties implements Parcelable { */ public boolean hasIPv4DnsServer() { for (InetAddress ia : mDnses) { - if (ia instanceof Inet4Address) { - return true; - } + if (ia instanceof Inet4Address) { + return true; + } } return false; } @@ -770,9 +770,9 @@ public final class LinkProperties implements Parcelable { */ public boolean hasIPv6DnsServer() { for (InetAddress ia : mDnses) { - if (ia instanceof Inet6Address) { - return true; - } + if (ia instanceof Inet6Address) { + return true; + } } return false; } diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index b63e3023565f..66e16a67a22b 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -104,11 +104,6 @@ interface INetworkManagementService void setIPv6AddrGenMode(String iface, int mode); /** - * Enables or enables IPv6 ND offload. - */ - void setInterfaceIpv6NdOffload(String iface, boolean enable); - - /** * Add the specified route to the interface. */ void addRoute(int netId, in RouteInfo route); diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index c091420a31d4..7f588adbd69d 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -737,7 +737,9 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { private void closeWithStatus(int status, String msg) { if (mClosed) return; mClosed = true; - mGuard.close(); + if (mGuard != null) { + mGuard.close(); + } // Status MUST be sent before closing actual descriptor writeCommStatusAndClose(status, msg); IoUtils.closeQuietly(mFd); diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java index 951aa8df9ea3..e01a1a649173 100644 --- a/core/java/android/util/Log.java +++ b/core/java/android/util/Log.java @@ -391,7 +391,7 @@ public final class Log { // and the length of the tag. // Note: we implicitly accept possible truncation for Modified-UTF8 differences. It // is too expensive to compute that ahead of time. - int bufferSize = NoPreloadHolder.LOGGER_ENTRY_MAX_PAYLOAD // Base. + int bufferSize = PreloadHolder.LOGGER_ENTRY_MAX_PAYLOAD // Base. - 2 // Two terminators. - (tag != null ? tag.length() : 0) // Tag length. - 32; // Some slack. @@ -428,10 +428,10 @@ public final class Log { } /** - * NoPreloadHelper class. Caches the LOGGER_ENTRY_MAX_PAYLOAD value to avoid + * PreloadHelper class. Caches the LOGGER_ENTRY_MAX_PAYLOAD value to avoid * a JNI call during logging. */ - static class NoPreloadHolder { + static class PreloadHolder { public final static int LOGGER_ENTRY_MAX_PAYLOAD = logger_entry_max_payload_native(); } diff --git a/core/java/com/android/internal/os/LoggingPrintStream.java b/core/java/com/android/internal/os/LoggingPrintStream.java index f14394ad09ce..d27874cd3be2 100644 --- a/core/java/com/android/internal/os/LoggingPrintStream.java +++ b/core/java/com/android/internal/os/LoggingPrintStream.java @@ -28,12 +28,15 @@ import java.nio.charset.CodingErrorAction; import java.util.Formatter; import java.util.Locale; +import com.android.internal.annotations.VisibleForTesting; + /** * A print stream which logs output line by line. * * {@hide} */ -abstract class LoggingPrintStream extends PrintStream { +@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) +public abstract class LoggingPrintStream extends PrintStream { private final StringBuilder builder = new StringBuilder(); diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java index 1b354d0d9df0..eabe3b910b78 100644 --- a/core/java/com/android/internal/util/BitUtils.java +++ b/core/java/com/android/internal/util/BitUtils.java @@ -91,6 +91,10 @@ public final class BitUtils { return s & 0xffff; } + public static int uint16(byte hi, byte lo) { + return ((hi & 0xff) << 8) | (lo & 0xff); + } + public static long uint32(int i) { return i & 0xffffffffL; } diff --git a/core/java/com/android/internal/widget/LinearLayoutManager.java b/core/java/com/android/internal/widget/LinearLayoutManager.java index d82c746649e2..0000a74f8249 100644 --- a/core/java/com/android/internal/widget/LinearLayoutManager.java +++ b/core/java/com/android/internal/widget/LinearLayoutManager.java @@ -168,10 +168,6 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements /** * Constructor used when layout manager is set in XML by RecyclerView attribute * "layoutManager". Defaults to vertical orientation. - * - * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_android_orientation - * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_reverseLayout - * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_stackFromEnd */ public LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 6d5d71ccff6a..72795003d9df 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -19,6 +19,8 @@ #define LOG_NDEBUG 1 #include <android_runtime/AndroidRuntime.h> + +#include <android-base/properties.h> #include <binder/IBinder.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> @@ -47,8 +49,8 @@ #include <string> #include <vector> - using namespace android; +using android::base::GetProperty; extern int register_android_os_Binder(JNIEnv* env); extern int register_android_os_Process(JNIEnv* env); @@ -392,17 +394,6 @@ static bool hasFile(const char* file) { return false; } -// Convenience wrapper over the property API that returns an -// std::string. -std::string getProperty(const char* key, const char* defaultValue) { - std::vector<char> temp(PROPERTY_VALUE_MAX); - const int len = property_get(key, &temp[0], defaultValue); - if (len < 0) { - return ""; - } - return std::string(&temp[0], len); -} - /* * Read the persistent locale. Inspects the following system properties * (in order) and returns the first non-empty property in the list : @@ -419,15 +410,15 @@ std::string getProperty(const char* key, const char* defaultValue) { */ const std::string readLocale() { - const std::string locale = getProperty("persist.sys.locale", ""); + const std::string locale = GetProperty("persist.sys.locale", ""); if (!locale.empty()) { return locale; } - const std::string language = getProperty("persist.sys.language", ""); + const std::string language = GetProperty("persist.sys.language", ""); if (!language.empty()) { - const std::string country = getProperty("persist.sys.country", ""); - const std::string variant = getProperty("persist.sys.localevar", ""); + const std::string country = GetProperty("persist.sys.country", ""); + const std::string variant = GetProperty("persist.sys.localevar", ""); std::string out = language; if (!country.empty()) { @@ -441,15 +432,15 @@ const std::string readLocale() return out; } - const std::string productLocale = getProperty("ro.product.locale", ""); + const std::string productLocale = GetProperty("ro.product.locale", ""); if (!productLocale.empty()) { return productLocale; } // If persist.sys.locale and ro.product.locale are missing, // construct a locale value from the individual locale components. - const std::string productLanguage = getProperty("ro.product.locale.language", "en"); - const std::string productRegion = getProperty("ro.product.locale.region", "US"); + const std::string productLanguage = GetProperty("ro.product.locale.language", "en"); + const std::string productRegion = GetProperty("ro.product.locale.region", "US"); return productLanguage + "-" + productRegion; } @@ -649,7 +640,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX]; char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX]; char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX]; - char fingerprintBuf[sizeof("-Xfingerprint:") + PROPERTY_VALUE_MAX]; + std::string fingerprintBuf; bool checkJni = false; property_get("dalvik.vm.checkjni", propBuf, ""); @@ -964,8 +955,15 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) /* * Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will * contain the fingerprint and can be parsed. + * Fingerprints are potentially longer than PROPERTY_VALUE_MAX, so parseRuntimeOption() cannot + * be used here. + * Do not ever re-assign fingerprintBuf as its c_str() value is stored in mOptions. */ - parseRuntimeOption("ro.build.fingerprint", fingerprintBuf, "-Xfingerprint:"); + std::string fingerprint = GetProperty("ro.build.fingerprint", ""); + if (!fingerprint.empty()) { + fingerprintBuf = "-Xfingerprint:" + fingerprint; + addOption(fingerprintBuf.c_str()); + } initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray(); diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index 18f3177b95ae..09e37e1a3de6 100644 --- a/core/jni/android_app_NativeActivity.cpp +++ b/core/jni/android_app_NativeActivity.cpp @@ -40,6 +40,7 @@ #include "android_view_InputChannel.h" #include "android_view_KeyEvent.h" +#include "android-base/stringprintf.h" #include "nativebridge/native_bridge.h" #include "nativeloader/native_loader.h" @@ -265,6 +266,8 @@ static int mainWorkCallback(int fd, int events, void* data) { // ------------------------------------------------------------------------ +static thread_local std::string g_error_msg; + static jlong loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName, jobject messageQueue, jstring internalDataDir, jstring obbDir, @@ -277,7 +280,6 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName ScopedUtfChars pathStr(env, path); std::unique_ptr<NativeCode> code; bool needs_native_bridge = false; - std::string error_msg; void* handle = OpenNativeLibrary(env, sdkVersion, @@ -285,12 +287,12 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName classLoader, libraryPath, &needs_native_bridge, - &error_msg); + &g_error_msg); if (handle == nullptr) { ALOGW("NativeActivity LoadNativeLibrary(\"%s\") failed: %s", pathStr.c_str(), - error_msg.c_str()); + g_error_msg.c_str()); return 0; } @@ -306,19 +308,22 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName env->ReleaseStringUTFChars(funcName, funcStr); if (code->createActivityFunc == NULL) { - ALOGW("ANativeActivity_onCreate not found"); + g_error_msg = needs_native_bridge ? NativeBridgeGetError() : dlerror(); + ALOGW("ANativeActivity_onCreate not found: %s", g_error_msg.c_str()); return 0; } code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue); if (code->messageQueue == NULL) { - ALOGW("Unable to retrieve native MessageQueue"); + g_error_msg = "Unable to retrieve native MessageQueue"; + ALOGW("%s", g_error_msg.c_str()); return 0; } int msgpipe[2]; if (pipe(msgpipe)) { - ALOGW("could not create pipe: %s", strerror(errno)); + g_error_msg = android::base::StringPrintf("could not create pipe: %s", strerror(errno)); + ALOGW("%s", g_error_msg.c_str()); return 0; } code->mainWorkRead = msgpipe[0]; @@ -334,7 +339,8 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName code->ANativeActivity::callbacks = &code->callbacks; if (env->GetJavaVM(&code->vm) < 0) { - ALOGW("NativeActivity GetJavaVM failed"); + g_error_msg = "NativeActivity GetJavaVM failed"; + ALOGW("%s", g_error_msg.c_str()); return 0; } code->env = env; @@ -381,7 +387,9 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName } static jstring getDlError_native(JNIEnv* env, jobject clazz) { - return env->NewStringUTF(dlerror()); + jstring result = env->NewStringUTF(g_error_msg.c_str()); + g_error_msg.clear(); + return result; } static void diff --git a/core/jni/android_app_admin_SecurityLog.cpp b/core/jni/android_app_admin_SecurityLog.cpp index 5c45b4b26a1b..b3bcaa0f7f03 100644 --- a/core/jni/android_app_admin_SecurityLog.cpp +++ b/core/jni/android_app_admin_SecurityLog.cpp @@ -14,183 +14,26 @@ * limitations under the License. */ -#include <fcntl.h> +#include <log/log_id.h> +#include <private/android_logger.h> #include <nativehelper/JNIHelp.h> -#include "core_jni_helpers.h" #include "jni.h" -#include <private/android_logger.h> -// The size of the tag number comes out of the payload size. -#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t)) +#include "core_jni_helpers.h" +#include "eventlog_helper.h" namespace android { -static jclass gCollectionClass; -static jmethodID gCollectionAddID; - -static jclass gEventClass; -static jmethodID gEventInitID; - -static jclass gIntegerClass; -static jfieldID gIntegerValueID; - -static jclass gLongClass; -static jfieldID gLongValueID; - -static jclass gFloatClass; -static jfieldID gFloatValueID; - -static jclass gStringClass; - +constexpr char kSecurityLogEventClass[] = "android/app/admin/SecurityLog$SecurityEvent"; +template class EventLogHelper<log_id_t::LOG_ID_SECURITY, kSecurityLogEventClass>; +using SLog = EventLogHelper<log_id_t::LOG_ID_SECURITY, kSecurityLogEventClass>; static jboolean android_app_admin_SecurityLog_isLoggingEnabled(JNIEnv* env, jobject /* clazz */) { return (bool)__android_log_security(); } -static jint android_app_admin_SecurityLog_writeEvent_String(JNIEnv* env, - jobject /* clazz */, - jint tag, jstring value) { - uint8_t buf[MAX_EVENT_PAYLOAD]; - - // Don't throw NPE -- I feel like it's sort of mean for a logging function - // to be all crashy if you pass in NULL -- but make the NULL value explicit. - const char *str = value != NULL ? env->GetStringUTFChars(value, NULL) : "NULL"; - uint32_t len = strlen(str); - size_t max = sizeof(buf) - sizeof(len) - 2; // Type byte, final newline - if (len > max) len = max; - - buf[0] = EVENT_TYPE_STRING; - memcpy(&buf[1], &len, sizeof(len)); - memcpy(&buf[1 + sizeof(len)], str, len); - buf[1 + sizeof(len) + len] = '\n'; - - if (value != NULL) env->ReleaseStringUTFChars(value, str); - return __android_log_security_bwrite(tag, buf, 2 + sizeof(len) + len); -} - -static jint android_app_admin_SecurityLog_writeEvent_Array(JNIEnv* env, jobject clazz, - jint tag, jobjectArray value) { - if (value == NULL) { - return android_app_admin_SecurityLog_writeEvent_String(env, clazz, tag, NULL); - } - - uint8_t buf[MAX_EVENT_PAYLOAD]; - const size_t max = sizeof(buf) - 1; // leave room for final newline - size_t pos = 2; // Save room for type tag & array count - - jsize copied = 0, num = env->GetArrayLength(value); - for (; copied < num && copied < 255; ++copied) { - jobject item = env->GetObjectArrayElement(value, copied); - if (item == NULL || env->IsInstanceOf(item, gStringClass)) { - if (pos + 1 + sizeof(jint) > max) break; - const char *str = item != NULL ? env->GetStringUTFChars((jstring) item, NULL) : "NULL"; - jint len = strlen(str); - if (pos + 1 + sizeof(len) + len > max) len = max - pos - 1 - sizeof(len); - buf[pos++] = EVENT_TYPE_STRING; - memcpy(&buf[pos], &len, sizeof(len)); - memcpy(&buf[pos + sizeof(len)], str, len); - pos += sizeof(len) + len; - if (item != NULL) env->ReleaseStringUTFChars((jstring) item, str); - } else if (env->IsInstanceOf(item, gIntegerClass)) { - jint intVal = env->GetIntField(item, gIntegerValueID); - if (pos + 1 + sizeof(intVal) > max) break; - buf[pos++] = EVENT_TYPE_INT; - memcpy(&buf[pos], &intVal, sizeof(intVal)); - pos += sizeof(intVal); - } else if (env->IsInstanceOf(item, gLongClass)) { - jlong longVal = env->GetLongField(item, gLongValueID); - if (pos + 1 + sizeof(longVal) > max) break; - buf[pos++] = EVENT_TYPE_LONG; - memcpy(&buf[pos], &longVal, sizeof(longVal)); - pos += sizeof(longVal); - } else if (env->IsInstanceOf(item, gFloatClass)) { - jfloat floatVal = env->GetFloatField(item, gFloatValueID); - if (pos + 1 + sizeof(floatVal) > max) break; - buf[pos++] = EVENT_TYPE_FLOAT; - memcpy(&buf[pos], &floatVal, sizeof(floatVal)); - pos += sizeof(floatVal); - } else { - jniThrowException(env, - "java/lang/IllegalArgumentException", - "Invalid payload item type"); - return -1; - } - env->DeleteLocalRef(item); - } - - buf[0] = EVENT_TYPE_LIST; - buf[1] = copied; - buf[pos++] = '\n'; - return __android_log_security_bwrite(tag, buf, pos); -} - -static void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) { - struct logger_list *logger_list; - if (startTime) { - logger_list = android_logger_list_alloc_time(loggerMode, - log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0); - } else { - logger_list = android_logger_list_alloc(loggerMode, 0, 0); - } - if (!logger_list) { - jniThrowIOException(env, errno); - return; - } - - if (!android_logger_open(logger_list, LOG_ID_SECURITY)) { - jniThrowIOException(env, errno); - android_logger_list_free(logger_list); - return; - } - - while (1) { - log_msg log_msg; - int ret = android_logger_list_read(logger_list, &log_msg); - - if (ret == 0) { - break; - } - if (ret < 0) { - if (ret == -EINTR) { - continue; - } - if (ret == -EINVAL) { - jniThrowException(env, "java/io/IOException", "Event too short"); - } else if (ret != -EAGAIN) { - jniThrowIOException(env, -ret); // Will throw on return - } - break; - } - - if (log_msg.id() != LOG_ID_SECURITY) { - continue; - } - - jsize len = ret; - jbyteArray array = env->NewByteArray(len); - if (array == NULL) { - break; - } - - jbyte *bytes = env->GetByteArrayElements(array, NULL); - memcpy(bytes, log_msg.buf, len); - env->ReleaseByteArrayElements(array, bytes, 0); - - jobject event = env->NewObject(gEventClass, gEventInitID, array); - if (event == NULL) { - break; - } - - env->CallBooleanMethod(out, gCollectionAddID, event); - env->DeleteLocalRef(event); - env->DeleteLocalRef(array); - } - - android_logger_list_close(logger_list); -} - static void android_app_admin_SecurityLog_readEvents(JNIEnv* env, jobject /* clazz */, jobject out) { @@ -198,7 +41,7 @@ static void android_app_admin_SecurityLog_readEvents(JNIEnv* env, jobject /* cla jniThrowNullPointerException(env, NULL); return; } - readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out); + SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out); } static void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject /* clazz */, @@ -209,7 +52,7 @@ static void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject / jniThrowNullPointerException(env, NULL); return; } - readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out); + SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out); } static void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobject /* clazz */, @@ -219,7 +62,7 @@ static void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobjec jniThrowNullPointerException(env, NULL); return; } - readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out); + SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out); } static void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobject /* clazz */, @@ -229,7 +72,8 @@ static void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobj jniThrowNullPointerException(env, NULL); return; } - readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, out); + SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, + out); } /* @@ -243,11 +87,11 @@ static const JNINativeMethod gRegisterMethods[] = { }, { "writeEvent", "(ILjava/lang/String;)I", - (void*) android_app_admin_SecurityLog_writeEvent_String + (void*) SLog::writeEventString }, { "writeEvent", "(I[Ljava/lang/Object;)I", - (void*) android_app_admin_SecurityLog_writeEvent_Array + (void*) SLog::writeEventArray }, { "readEvents", "(Ljava/util/Collection;)V", @@ -267,41 +111,8 @@ static const JNINativeMethod gRegisterMethods[] = { }, }; -static struct { const char *name; jclass *clazz; } gClasses[] = { - { "android/app/admin/SecurityLog$SecurityEvent", &gEventClass }, - { "java/lang/Integer", &gIntegerClass }, - { "java/lang/Long", &gLongClass }, - { "java/lang/Float", &gFloatClass }, - { "java/lang/String", &gStringClass }, - { "java/util/Collection", &gCollectionClass }, -}; - -static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = { - { &gIntegerClass, "value", "I", &gIntegerValueID }, - { &gLongClass, "value", "J", &gLongValueID }, - { &gFloatClass, "value", "F", &gFloatValueID }, -}; - -static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = { - { &gEventClass, "<init>", "([B)V", &gEventInitID }, - { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID }, -}; - int register_android_app_admin_SecurityLog(JNIEnv* env) { - for (int i = 0; i < NELEM(gClasses); ++i) { - jclass clazz = FindClassOrDie(env, gClasses[i].name); - *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz); - } - - for (int i = 0; i < NELEM(gFields); ++i) { - *gFields[i].id = GetFieldIDOrDie(env, - *gFields[i].c, gFields[i].name, gFields[i].ft); - } - - for (int i = 0; i < NELEM(gMethods); ++i) { - *gMethods[i].id = GetMethodIDOrDie(env, - *gMethods[i].c, gMethods[i].name, gMethods[i].mt); - } + SLog::Init(env); return RegisterMethodsOrDie( env, diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp index c8eef7f3f2f8..162822092af6 100644 --- a/core/jni/android_hardware_camera2_DngCreator.cpp +++ b/core/jni/android_hardware_camera2_DngCreator.cpp @@ -23,13 +23,13 @@ #include <vector> #include <cmath> +#include <android-base/properties.h> #include <utils/Log.h> #include <utils/Errors.h> #include <utils/StrongPointer.h> #include <utils/RefBase.h> #include <utils/Vector.h> #include <utils/String8.h> -#include <cutils/properties.h> #include <system/camera_metadata.h> #include <camera/CameraMetadata.h> #include <img_utils/DngUtils.h> @@ -50,6 +50,7 @@ using namespace android; using namespace img_utils; +using android::base::GetProperty; #define BAIL_IF_INVALID_RET_BOOL(expr, jnienv, tagId, writer) \ if ((expr) != OK) { \ @@ -1237,26 +1238,24 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image { // make - char manufacturer[PROPERTY_VALUE_MAX]; - // Use "" to represent unknown make as suggested in TIFF/EP spec. - property_get("ro.product.manufacturer", manufacturer, ""); - uint32_t count = static_cast<uint32_t>(strlen(manufacturer)) + 1; + std::string manufacturer = GetProperty("ro.product.manufacturer", ""); + uint32_t count = static_cast<uint32_t>(manufacturer.size()) + 1; BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MAKE, count, - reinterpret_cast<uint8_t*>(manufacturer), TIFF_IFD_0), env, TAG_MAKE, writer); + reinterpret_cast<const uint8_t*>(manufacturer.c_str()), TIFF_IFD_0), env, TAG_MAKE, + writer); } { // model - char model[PROPERTY_VALUE_MAX]; - // Use "" to represent unknown model as suggested in TIFF/EP spec. - property_get("ro.product.model", model, ""); - uint32_t count = static_cast<uint32_t>(strlen(model)) + 1; + std::string model = GetProperty("ro.product.model", ""); + uint32_t count = static_cast<uint32_t>(model.size()) + 1; BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MODEL, count, - reinterpret_cast<uint8_t*>(model), TIFF_IFD_0), env, TAG_MODEL, writer); + reinterpret_cast<const uint8_t*>(model.c_str()), TIFF_IFD_0), env, TAG_MODEL, + writer); } { @@ -1277,11 +1276,11 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image { // software - char software[PROPERTY_VALUE_MAX]; - property_get("ro.build.fingerprint", software, ""); - uint32_t count = static_cast<uint32_t>(strlen(software)) + 1; + std::string software = GetProperty("ro.build.fingerprint", ""); + uint32_t count = static_cast<uint32_t>(software.size()) + 1; BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_SOFTWARE, count, - reinterpret_cast<uint8_t*>(software), TIFF_IFD_0), env, TAG_SOFTWARE, writer); + reinterpret_cast<const uint8_t*>(software.c_str()), TIFF_IFD_0), env, TAG_SOFTWARE, + writer); } if (nativeContext->hasCaptureTime()) { @@ -1613,20 +1612,15 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image { // Setup unique camera model tag - char model[PROPERTY_VALUE_MAX]; - property_get("ro.product.model", model, ""); - - char manufacturer[PROPERTY_VALUE_MAX]; - property_get("ro.product.manufacturer", manufacturer, ""); - - char brand[PROPERTY_VALUE_MAX]; - property_get("ro.product.brand", brand, ""); + std::string model = GetProperty("ro.product.model", ""); + std::string manufacturer = GetProperty("ro.product.manufacturer", ""); + std::string brand = GetProperty("ro.product.brand", ""); - String8 cameraModel(model); + String8 cameraModel(model.c_str()); cameraModel += "-"; - cameraModel += manufacturer; + cameraModel += manufacturer.c_str(); cameraModel += "-"; - cameraModel += brand; + cameraModel += brand.c_str(); BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_UNIQUECAMERAMODEL, cameraModel.size() + 1, reinterpret_cast<const uint8_t*>(cameraModel.string()), TIFF_IFD_0), env, diff --git a/core/jni/android_os_VintfRuntimeInfo.cpp b/core/jni/android_os_VintfRuntimeInfo.cpp index 315eac1b9414..9379ea6dcd10 100644 --- a/core/jni/android_os_VintfRuntimeInfo.cpp +++ b/core/jni/android_os_VintfRuntimeInfo.cpp @@ -29,28 +29,33 @@ namespace android { using vintf::RuntimeInfo; using vintf::VintfObject; -#define MAP_STRING_METHOD(javaMethod, cppString) \ +#define MAP_STRING_METHOD(javaMethod, cppString, flags) \ static jstring android_os_VintfRuntimeInfo_##javaMethod(JNIEnv* env, jclass clazz) \ { \ - std::shared_ptr<const RuntimeInfo> info = VintfObject::GetRuntimeInfo(); \ + std::shared_ptr<const RuntimeInfo> info = VintfObject::GetRuntimeInfo( \ + false /* skipCache */, flags); \ if (info == nullptr) return nullptr; \ return env->NewStringUTF((cppString).c_str()); \ } \ -MAP_STRING_METHOD(getCpuInfo, info->cpuInfo()); -MAP_STRING_METHOD(getOsName, info->osName()); -MAP_STRING_METHOD(getNodeName, info->nodeName()); -MAP_STRING_METHOD(getOsRelease, info->osRelease()); -MAP_STRING_METHOD(getOsVersion, info->osVersion()); -MAP_STRING_METHOD(getHardwareId, info->hardwareId()); -MAP_STRING_METHOD(getKernelVersion, vintf::to_string(info->kernelVersion())); -MAP_STRING_METHOD(getBootAvbVersion, vintf::to_string(info->bootAvbVersion())); -MAP_STRING_METHOD(getBootVbmetaAvbVersion, vintf::to_string(info->bootVbmetaAvbVersion())); +MAP_STRING_METHOD(getCpuInfo, info->cpuInfo(), RuntimeInfo::FetchFlag::CPU_INFO); +MAP_STRING_METHOD(getOsName, info->osName(), RuntimeInfo::FetchFlag::CPU_VERSION); +MAP_STRING_METHOD(getNodeName, info->nodeName(), RuntimeInfo::FetchFlag::CPU_VERSION); +MAP_STRING_METHOD(getOsRelease, info->osRelease(), RuntimeInfo::FetchFlag::CPU_VERSION); +MAP_STRING_METHOD(getOsVersion, info->osVersion(), RuntimeInfo::FetchFlag::CPU_VERSION); +MAP_STRING_METHOD(getHardwareId, info->hardwareId(), RuntimeInfo::FetchFlag::CPU_VERSION); +MAP_STRING_METHOD(getKernelVersion, vintf::to_string(info->kernelVersion()), + RuntimeInfo::FetchFlag::CPU_VERSION); +MAP_STRING_METHOD(getBootAvbVersion, vintf::to_string(info->bootAvbVersion()), + RuntimeInfo::FetchFlag::AVB); +MAP_STRING_METHOD(getBootVbmetaAvbVersion, vintf::to_string(info->bootVbmetaAvbVersion()), + RuntimeInfo::FetchFlag::AVB); static jlong android_os_VintfRuntimeInfo_getKernelSepolicyVersion(JNIEnv *env, jclass clazz) { - std::shared_ptr<const RuntimeInfo> info = VintfObject::GetRuntimeInfo(); + std::shared_ptr<const RuntimeInfo> info = VintfObject::GetRuntimeInfo( + false /* skipCache */, RuntimeInfo::FetchFlag::POLICYVERS); if (info == nullptr) return 0; return static_cast<jlong>(info->kernelSepolicyVersion()); } diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp index 9fd7c4041058..3b5a144a4e61 100644 --- a/core/jni/android_util_EventLog.cpp +++ b/core/jni/android_util_EventLog.cpp @@ -14,214 +14,20 @@ * limitations under the License. */ -#include <fcntl.h> - -#include <log/log_event_list.h> - -#include <log/log.h> +#include <android-base/macros.h> +#include <log/log_id.h> #include <nativehelper/JNIHelp.h> -#include "core_jni_helpers.h" #include "jni.h" -#define UNUSED __attribute__((__unused__)) +#include "core_jni_helpers.h" +#include "eventlog_helper.h" namespace android { -static jclass gCollectionClass; -static jmethodID gCollectionAddID; - -static jclass gEventClass; -static jmethodID gEventInitID; - -static jclass gIntegerClass; -static jfieldID gIntegerValueID; - -static jclass gLongClass; -static jfieldID gLongValueID; - -static jclass gFloatClass; -static jfieldID gFloatValueID; - -static jclass gStringClass; - -/* - * In class android.util.EventLog: - * static native int writeEvent(int tag, int value) - */ -static jint android_util_EventLog_writeEvent_Integer(JNIEnv* env UNUSED, - jobject clazz UNUSED, - jint tag, jint value) -{ - android_log_event_list ctx(tag); - ctx << (int32_t)value; - return ctx.write(); -} - -/* - * In class android.util.EventLog: - * static native int writeEvent(long tag, long value) - */ -static jint android_util_EventLog_writeEvent_Long(JNIEnv* env UNUSED, - jobject clazz UNUSED, - jint tag, jlong value) -{ - android_log_event_list ctx(tag); - ctx << (int64_t)value; - return ctx.write(); -} - -/* - * In class android.util.EventLog: - * static native int writeEvent(long tag, float value) - */ -static jint android_util_EventLog_writeEvent_Float(JNIEnv* env UNUSED, - jobject clazz UNUSED, - jint tag, jfloat value) -{ - android_log_event_list ctx(tag); - ctx << (float)value; - return ctx.write(); -} - -/* - * In class android.util.EventLog: - * static native int writeEvent(int tag, String value) - */ -static jint android_util_EventLog_writeEvent_String(JNIEnv* env, - jobject clazz UNUSED, - jint tag, jstring value) { - android_log_event_list ctx(tag); - // Don't throw NPE -- I feel like it's sort of mean for a logging function - // to be all crashy if you pass in NULL -- but make the NULL value explicit. - if (value != NULL) { - const char *str = env->GetStringUTFChars(value, NULL); - ctx << str; - env->ReleaseStringUTFChars(value, str); - } else { - ctx << "NULL"; - } - return ctx.write(); -} - -/* - * In class android.util.EventLog: - * static native int writeEvent(long tag, Object... value) - */ -static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz, - jint tag, jobjectArray value) { - android_log_event_list ctx(tag); - - if (value == NULL) { - ctx << "[NULL]"; - return ctx.write(); - } - - jsize copied = 0, num = env->GetArrayLength(value); - for (; copied < num && copied < 255; ++copied) { - if (ctx.status()) break; - jobject item = env->GetObjectArrayElement(value, copied); - if (item == NULL) { - ctx << "NULL"; - } else if (env->IsInstanceOf(item, gStringClass)) { - const char *str = env->GetStringUTFChars((jstring) item, NULL); - ctx << str; - env->ReleaseStringUTFChars((jstring) item, str); - } else if (env->IsInstanceOf(item, gIntegerClass)) { - ctx << (int32_t)env->GetIntField(item, gIntegerValueID); - } else if (env->IsInstanceOf(item, gLongClass)) { - ctx << (int64_t)env->GetLongField(item, gLongValueID); - } else if (env->IsInstanceOf(item, gFloatClass)) { - ctx << (float)env->GetFloatField(item, gFloatValueID); - } else { - jniThrowException(env, - "java/lang/IllegalArgumentException", - "Invalid payload item type"); - return -1; - } - env->DeleteLocalRef(item); - } - return ctx.write(); -} - -static void readEvents(JNIEnv* env, int loggerMode, jintArray tags, jlong startTime, jobject out) { - struct logger_list *logger_list; - if (startTime) { - logger_list = android_logger_list_alloc_time(loggerMode, - log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0); - } else { - logger_list = android_logger_list_alloc(loggerMode, 0, 0); - } - if (!logger_list) { - jniThrowIOException(env, errno); - return; - } - - if (!android_logger_open(logger_list, LOG_ID_EVENTS)) { - jniThrowIOException(env, errno); - android_logger_list_free(logger_list); - return; - } - - jsize tagLength = env->GetArrayLength(tags); - jint *tagValues = env->GetIntArrayElements(tags, NULL); - - while (1) { - log_msg log_msg; - int ret = android_logger_list_read(logger_list, &log_msg); - - if (ret == 0) { - break; - } - if (ret < 0) { - if (ret == -EINTR) { - continue; - } - if (ret == -EINVAL) { - jniThrowException(env, "java/io/IOException", "Event too short"); - } else if (ret != -EAGAIN) { - jniThrowIOException(env, -ret); // Will throw on return - } - break; - } - - if (log_msg.id() != LOG_ID_EVENTS) { - continue; - } - - int32_t tag = * (int32_t *) log_msg.msg(); - - int found = 0; - for (int i = 0; !found && i < tagLength; ++i) { - found = (tag == tagValues[i]); - } - - if (found) { - jsize len = ret; - jbyteArray array = env->NewByteArray(len); - if (array == NULL) { - break; - } - - jbyte *bytes = env->GetByteArrayElements(array, NULL); - memcpy(bytes, log_msg.buf, len); - env->ReleaseByteArrayElements(array, bytes, 0); - - jobject event = env->NewObject(gEventClass, gEventInitID, array); - if (event == NULL) { - break; - } - - env->CallBooleanMethod(out, gCollectionAddID, event); - env->DeleteLocalRef(event); - env->DeleteLocalRef(array); - } - } - - android_logger_list_close(logger_list); - - env->ReleaseIntArrayElements(tags, tagValues, 0); -} +constexpr char kEventLogEventClass[] = "android/util/EventLog$Event"; +template class EventLogHelper<log_id_t::LOG_ID_EVENTS, kEventLogEventClass>; +using ELog = EventLogHelper<log_id_t::LOG_ID_EVENTS, kEventLogEventClass>; /* * In class android.util.EventLog: @@ -229,7 +35,7 @@ static void readEvents(JNIEnv* env, int loggerMode, jintArray tags, jlong startT * * Reads events from the event log */ -static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED, +static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jintArray tags, jobject out) { @@ -238,7 +44,7 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED, return; } - readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out); + ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out); } /* * In class android.util.EventLog: @@ -246,7 +52,7 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED, * * Reads events from the event log, blocking until events after timestamp are to be overwritten. */ -static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject clazz UNUSED, +static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jintArray tags, jlong timestamp, jobject out) { @@ -254,8 +60,8 @@ static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject claz jniThrowNullPointerException(env, NULL); return; } - readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, - tags, timestamp, out); + ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, tags, + timestamp, out); } /* @@ -263,17 +69,11 @@ static void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject claz */ static const JNINativeMethod gRegisterMethods[] = { /* name, signature, funcPtr */ - { "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer }, - { "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long }, - { "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float }, - { "writeEvent", - "(ILjava/lang/String;)I", - (void*) android_util_EventLog_writeEvent_String - }, - { "writeEvent", - "(I[Ljava/lang/Object;)I", - (void*) android_util_EventLog_writeEvent_Array - }, + { "writeEvent", "(II)I", (void*) ELog::writeEventInteger }, + { "writeEvent", "(IJ)I", (void*) ELog::writeEventLong }, + { "writeEvent", "(IF)I", (void*) ELog::writeEventFloat }, + { "writeEvent", "(ILjava/lang/String;)I", (void*) ELog::writeEventString }, + { "writeEvent", "(I[Ljava/lang/Object;)I", (void*) ELog::writeEventArray }, { "readEvents", "([ILjava/util/Collection;)V", (void*) android_util_EventLog_readEvents @@ -284,41 +84,8 @@ static const JNINativeMethod gRegisterMethods[] = { }, }; -static struct { const char *name; jclass *clazz; } gClasses[] = { - { "android/util/EventLog$Event", &gEventClass }, - { "java/lang/Integer", &gIntegerClass }, - { "java/lang/Long", &gLongClass }, - { "java/lang/Float", &gFloatClass }, - { "java/lang/String", &gStringClass }, - { "java/util/Collection", &gCollectionClass }, -}; - -static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = { - { &gIntegerClass, "value", "I", &gIntegerValueID }, - { &gLongClass, "value", "J", &gLongValueID }, - { &gFloatClass, "value", "F", &gFloatValueID }, -}; - -static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = { - { &gEventClass, "<init>", "([B)V", &gEventInitID }, - { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID }, -}; - int register_android_util_EventLog(JNIEnv* env) { - for (int i = 0; i < NELEM(gClasses); ++i) { - jclass clazz = FindClassOrDie(env, gClasses[i].name); - *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz); - } - - for (int i = 0; i < NELEM(gFields); ++i) { - *gFields[i].id = GetFieldIDOrDie(env, - *gFields[i].c, gFields[i].name, gFields[i].ft); - } - - for (int i = 0; i < NELEM(gMethods); ++i) { - *gMethods[i].id = GetMethodIDOrDie(env, - *gMethods[i].c, gMethods[i].name, gMethods[i].mt); - } + ELog::Init(env); return RegisterMethodsOrDie( env, diff --git a/core/jni/eventlog_helper.h b/core/jni/eventlog_helper.h new file mode 100644 index 000000000000..3a05195ebc9e --- /dev/null +++ b/core/jni/eventlog_helper.h @@ -0,0 +1,272 @@ +/* + * 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. + */ + +#ifndef FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_ +#define FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_ + +#include <memory> + +#include <fcntl.h> + +#include <android-base/macros.h> +#include <log/log_event_list.h> + +#include <log/log.h> + +#include <nativehelper/JNIHelp.h> +#include <nativehelper/ScopedLocalRef.h> +#include <nativehelper/ScopedPrimitiveArray.h> +#include <nativehelper/ScopedUtfChars.h> +#include "core_jni_helpers.h" +#include "jni.h" + +namespace android { + +template <log_id_t LogID, const char* EventClassDescriptor> +class EventLogHelper { +public: + static void Init(JNIEnv* env) { + struct { const char *name; jclass *clazz; } gClasses[] = { + { EventClassDescriptor, &gEventClass }, + { "java/lang/Integer", &gIntegerClass }, + { "java/lang/Long", &gLongClass }, + { "java/lang/Float", &gFloatClass }, + { "java/lang/String", &gStringClass }, + { "java/util/Collection", &gCollectionClass }, + }; + struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = { + { &gIntegerClass, "value", "I", &gIntegerValueID }, + { &gLongClass, "value", "J", &gLongValueID }, + { &gFloatClass, "value", "F", &gFloatValueID }, + }; + struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = { + { &gEventClass, "<init>", "([B)V", &gEventInitID }, + { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID }, + }; + + for (size_t i = 0; i < NELEM(gClasses); ++i) { + ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, gClasses[i].name)); + *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz.get()); + } + for (size_t i = 0; i < NELEM(gFields); ++i) { + *gFields[i].id = GetFieldIDOrDie(env, + *gFields[i].c, gFields[i].name, gFields[i].ft); + } + + for (size_t i = 0; i < NELEM(gMethods); ++i) { + *gMethods[i].id = GetMethodIDOrDie(env, + *gMethods[i].c, gMethods[i].name, gMethods[i].mt); + } + } + + static jint writeEventInteger(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED, + jint tag, jint value) { + android_log_event_list ctx(tag); + ctx << (int32_t)value; + return ctx.write(LogID); + } + static jint writeEventLong(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED, + jint tag, jlong value) { + android_log_event_list ctx(tag); + ctx << (int64_t)value; + return ctx.write(LogID); + } + static jint writeEventFloat(JNIEnv* env ATTRIBUTE_UNUSED, jobject clazz ATTRIBUTE_UNUSED, + jint tag, jfloat value) { + android_log_event_list ctx(tag); + ctx << (float)value; + return ctx.write(LogID); + } + static jint writeEventString(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jint tag, + jstring value) { + android_log_event_list ctx(tag); + // Don't throw NPE -- I feel like it's sort of mean for a logging function + // to be all crashy if you pass in NULL -- but make the NULL value explicit. + ctx << (value != nullptr ? ScopedUtfChars(env, value).c_str() : "NULL"); + return ctx.write(LogID); + } + static jint writeEventArray(JNIEnv* env, jobject clazz ATTRIBUTE_UNUSED, jint tag, + jobjectArray value) { + android_log_event_list ctx(tag); + + if (value == nullptr) { + ctx << "[NULL]"; + return ctx.write(LogID); + } + + jsize copied = 0, num = env->GetArrayLength(value); + for (; copied < num && copied < 255; ++copied) { + if (ctx.status()) break; + ScopedLocalRef<jobject> item(env, env->GetObjectArrayElement(value, copied)); + if (item == nullptr) { + ctx << "NULL"; + } else if (env->IsInstanceOf(item.get(), gStringClass)) { + ctx << ScopedUtfChars(env, (jstring) item.get()).c_str(); + } else if (env->IsInstanceOf(item.get(), gIntegerClass)) { + ctx << (int32_t)env->GetIntField(item.get(), gIntegerValueID); + } else if (env->IsInstanceOf(item.get(), gLongClass)) { + ctx << (int64_t)env->GetLongField(item.get(), gLongValueID); + } else if (env->IsInstanceOf(item.get(), gFloatClass)) { + ctx << (float)env->GetFloatField(item.get(), gFloatValueID); + } else { + jniThrowException(env, + "java/lang/IllegalArgumentException", + "Invalid payload item type"); + return -1; + } + } + return ctx.write(LogID); + } + + static void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) { + readEvents(env, loggerMode, nullptr, startTime, out); + } + + static void readEvents(JNIEnv* env, int loggerMode, jintArray jTags, jlong startTime, + jobject out) { + std::unique_ptr<struct logger_list, decltype(&android_logger_list_close)> logger_list( + nullptr, android_logger_list_close); + if (startTime) { + logger_list.reset(android_logger_list_alloc_time(loggerMode, + log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0)); + } else { + logger_list.reset(android_logger_list_alloc(loggerMode, 0, 0)); + } + if (!logger_list) { + jniThrowIOException(env, errno); + return; + } + + if (!android_logger_open(logger_list.get(), LogID)) { + jniThrowIOException(env, errno); + return; + } + + ScopedIntArrayRO tags(env); + if (jTags != nullptr) { + tags.reset(jTags); + } + + while (1) { + log_msg log_msg; + int ret = android_logger_list_read(logger_list.get(), &log_msg); + + if (ret == 0) { + return; + } + if (ret < 0) { + if (ret == -EINTR) { + continue; + } + if (ret == -EINVAL) { + jniThrowException(env, "java/io/IOException", "Event too short"); + } else if (ret != -EAGAIN) { + jniThrowIOException(env, -ret); // Will throw on return + } + return; + } + + if (log_msg.id() != LogID) { + continue; + } + + int32_t tag = * (int32_t *) log_msg.msg(); + + if (jTags != nullptr) { + bool found = false; + for (size_t i = 0; !found && i < tags.size(); ++i) { + found = (tag == tags[i]); + } + if (!found) { + continue; + } + } + + jsize len = ret; + ScopedLocalRef<jbyteArray> array(env, env->NewByteArray(len)); + if (array == nullptr) { + return; + } + + { + ScopedByteArrayRW bytes(env, array.get()); + memcpy(bytes.get(), log_msg.buf, len); + } + + ScopedLocalRef<jobject> event(env, + env->NewObject(gEventClass, gEventInitID, array.get())); + if (event == nullptr) { + return; + } + + env->CallBooleanMethod(out, gCollectionAddID, event.get()); + if (env->ExceptionCheck() == JNI_TRUE) { + return; + } + } + } + +private: + static jclass gCollectionClass; + static jmethodID gCollectionAddID; + + static jclass gEventClass; + static jmethodID gEventInitID; + + static jclass gIntegerClass; + static jfieldID gIntegerValueID; + + static jclass gLongClass; + static jfieldID gLongValueID; + + static jclass gFloatClass; + static jfieldID gFloatValueID; + + static jclass gStringClass; +}; + +// Explicit instantiation declarations. +template <log_id_t LogID, const char* EventClassDescriptor> +jclass EventLogHelper<LogID, EventClassDescriptor>::gCollectionClass; +template <log_id_t LogID, const char* EventClassDescriptor> +jmethodID EventLogHelper<LogID, EventClassDescriptor>::gCollectionAddID; + +template <log_id_t LogID, const char* EventClassDescriptor> +jclass EventLogHelper<LogID, EventClassDescriptor>::gEventClass; +template <log_id_t LogID, const char* EventClassDescriptor> +jmethodID EventLogHelper<LogID, EventClassDescriptor>::gEventInitID; + +template <log_id_t LogID, const char* EventClassDescriptor> +jclass EventLogHelper<LogID, EventClassDescriptor>::gIntegerClass; +template <log_id_t LogID, const char* EventClassDescriptor> +jfieldID EventLogHelper<LogID, EventClassDescriptor>::gIntegerValueID; + +template <log_id_t LogID, const char* EventClassDescriptor> +jclass EventLogHelper<LogID, EventClassDescriptor>::gLongClass; +template <log_id_t LogID, const char* EventClassDescriptor> +jfieldID EventLogHelper<LogID, EventClassDescriptor>::gLongValueID; + +template <log_id_t LogID, const char* EventClassDescriptor> +jclass EventLogHelper<LogID, EventClassDescriptor>::gFloatClass; +template <log_id_t LogID, const char* EventClassDescriptor> +jfieldID EventLogHelper<LogID, EventClassDescriptor>::gFloatValueID; + +template <log_id_t LogID, const char* EventClassDescriptor> +jclass EventLogHelper<LogID, EventClassDescriptor>::gStringClass; + +} // namespace android + +#endif // FRAMEWORKS_BASE_CORE_JNI_EVENTLOG_HELPER_H_ diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 0668b8bec0d3..29f67a85a19f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -203,8 +203,8 @@ android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY" /> <protected-broadcast android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" /> - <protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" /> <protected-broadcast android:name="android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT" /> diff --git a/core/res/res/values-mcc001-mnc01/strings.xml b/core/res/res/values-mcc001-mnc01/strings.xml new file mode 100644 index 000000000000..96af975b50b5 --- /dev/null +++ b/core/res/res/values-mcc001-mnc01/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 2006, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> +</resources> diff --git a/core/res/res/values-mcc310-mnc030/strings.xml b/core/res/res/values-mcc310-mnc030/strings.xml index a3fea29070f5..6a404d5cee5f 100644 --- a/core/res/res/values-mcc310-mnc030/strings.xml +++ b/core/res/res/values-mcc310-mnc030/strings.xml @@ -20,4 +20,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string> <string name="mmcc_illegal_ms">SIM not allowed MM#3</string> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> </resources> diff --git a/core/res/res/values-mcc310-mnc150/strings.xml b/core/res/res/values-mcc310-mnc150/strings.xml new file mode 100644 index 000000000000..96af975b50b5 --- /dev/null +++ b/core/res/res/values-mcc310-mnc150/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 2006, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> +</resources> diff --git a/core/res/res/values-mcc310-mnc170/strings.xml b/core/res/res/values-mcc310-mnc170/strings.xml index a3fea29070f5..6a404d5cee5f 100644 --- a/core/res/res/values-mcc310-mnc170/strings.xml +++ b/core/res/res/values-mcc310-mnc170/strings.xml @@ -20,4 +20,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string> <string name="mmcc_illegal_ms">SIM not allowed MM#3</string> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> </resources> diff --git a/core/res/res/values-mcc310-mnc280/strings.xml b/core/res/res/values-mcc310-mnc280/strings.xml index a3fea29070f5..6a404d5cee5f 100644 --- a/core/res/res/values-mcc310-mnc280/strings.xml +++ b/core/res/res/values-mcc310-mnc280/strings.xml @@ -20,4 +20,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string> <string name="mmcc_illegal_ms">SIM not allowed MM#3</string> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> </resources> diff --git a/core/res/res/values-mcc310-mnc410/strings.xml b/core/res/res/values-mcc310-mnc410/strings.xml index a3fea29070f5..6a404d5cee5f 100644 --- a/core/res/res/values-mcc310-mnc410/strings.xml +++ b/core/res/res/values-mcc310-mnc410/strings.xml @@ -20,4 +20,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string> <string name="mmcc_illegal_ms">SIM not allowed MM#3</string> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> </resources> diff --git a/core/res/res/values-mcc310-mnc560/strings.xml b/core/res/res/values-mcc310-mnc560/strings.xml index a3fea29070f5..6a404d5cee5f 100644 --- a/core/res/res/values-mcc310-mnc560/strings.xml +++ b/core/res/res/values-mcc310-mnc560/strings.xml @@ -20,4 +20,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string> <string name="mmcc_illegal_ms">SIM not allowed MM#3</string> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> </resources> diff --git a/core/res/res/values-mcc310-mnc950/strings.xml b/core/res/res/values-mcc310-mnc950/strings.xml index a3fea29070f5..6a404d5cee5f 100644 --- a/core/res/res/values-mcc310-mnc950/strings.xml +++ b/core/res/res/values-mcc310-mnc950/strings.xml @@ -20,4 +20,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string> <string name="mmcc_illegal_ms">SIM not allowed MM#3</string> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> </resources> diff --git a/core/res/res/values-mcc311-mnc180/strings.xml b/core/res/res/values-mcc311-mnc180/strings.xml index a3fea29070f5..6a404d5cee5f 100644 --- a/core/res/res/values-mcc311-mnc180/strings.xml +++ b/core/res/res/values-mcc311-mnc180/strings.xml @@ -20,4 +20,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned MM#2</string> <string name="mmcc_illegal_ms">SIM not allowed MM#3</string> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> </resources> diff --git a/core/res/res/values-mcc312-mnc670/strings.xml b/core/res/res/values-mcc312-mnc670/strings.xml new file mode 100644 index 000000000000..96af975b50b5 --- /dev/null +++ b/core/res/res/values-mcc312-mnc670/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 2006, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> +</resources> diff --git a/core/res/res/values-mcc313-mnc100/strings.xml b/core/res/res/values-mcc313-mnc100/strings.xml new file mode 100644 index 000000000000..96af975b50b5 --- /dev/null +++ b/core/res/res/values-mcc313-mnc100/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 2006, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="mmcc_illegal_me">Phone not allowed MM#6</string> +</resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 7e47a2a0c912..78492452143f 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2971,4 +2971,8 @@ <!-- An array of packages that need to be treated as type service in battery settings --> <string-array translatable="false" name="config_batteryPackageTypeService"/> + + <!-- Decide whether to display 'No service' on status bar instead of 'Emergency calls only' + when SIM is unready. --> + <bool name="config_display_no_service_when_sim_unready">false</bool> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 786080f980ba..47243993c658 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3038,4 +3038,5 @@ <java-symbol type="array" name="config_batteryPackageTypeSystem" /> <java-symbol type="array" name="config_batteryPackageTypeService" /> + <java-symbol type="bool" name="config_display_no_service_when_sim_unready" /> </resources> diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk index 278419315779..c5e112b2e999 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk +++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.mk @@ -33,29 +33,17 @@ mainDexList:= \ $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex -LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\ - -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true - -################################# -include $(BUILD_SYSTEM)/configure_local_jack.mk -################################# - -ifdef LOCAL_JACK_ENABLED -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp -endif LOCAL_MIN_SDK_VERSION := 8 include $(BUILD_PACKAGE) -ifndef LOCAL_JACK_ENABLED $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES) $(hide) mkdir -p $(dir $@) $(MAINDEXCLASSES) $< 1>$@ echo "com/android/multidexlegacytestapp/Test.class" >> $@ $(built_dex_intermediate): $(mainDexList) -endif ## The application with a full main dex include $(CLEAR_VARS) @@ -76,26 +64,14 @@ mainDexList2:= \ $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList2) -LOCAL_JACK_FLAGS := -D jack.dex.output.policy=multidex -D jack.preprocessor=true\ - -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true - -################################# -include $(BUILD_SYSTEM)/configure_local_jack.mk -################################# - -ifdef LOCAL_JACK_ENABLED -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp -endif LOCAL_MIN_SDK_VERSION := 8 include $(BUILD_PACKAGE) -ifndef LOCAL_JACK_ENABLED $(mainDexList2): $(full_classes_proguard_jar) | $(MAINDEXCLASSES) $(hide) mkdir -p $(dir $@) $(MAINDEXCLASSES) $< 1>$@ echo "com/android/multidexlegacytestapp/Test.class" >> $@ $(built_dex_intermediate): $(mainDexList2) -endif
\ No newline at end of file diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp deleted file mode 100644 index a1f56565c749..000000000000 --- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/test.jpp +++ /dev/null @@ -1,3 +0,0 @@ -test: - @@com.android.jack.annotations.ForceInMainDex - class com.android.multidexlegacytestapp.Test diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk index 1c7d80790120..da48df93a1d8 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk +++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk @@ -32,24 +32,12 @@ mainDexList:= \ $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex -LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\ - -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true - -################################# -include $(BUILD_SYSTEM)/configure_local_jack.mk -################################# - -ifdef LOCAL_JACK_ENABLED -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp -endif include $(BUILD_PACKAGE) -ifndef LOCAL_JACK_ENABLED $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES) $(hide) mkdir -p $(dir $@) $(MAINDEXCLASSES) $< 1>$@ echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@ $(built_dex_intermediate): $(mainDexList) -endif
\ No newline at end of file diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp deleted file mode 100644 index 6d384e31351b..000000000000 --- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/test.jpp +++ /dev/null @@ -1,3 +0,0 @@ -test: - @@com.android.jack.annotations.ForceInMainDex - class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk index b77cf31edc62..02b3f537758e 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk +++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk @@ -32,24 +32,12 @@ mainDexList:= \ $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex -LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\ - -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true - -################################# -include $(BUILD_SYSTEM)/configure_local_jack.mk -################################# - -ifdef LOCAL_JACK_ENABLED -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp -endif include $(BUILD_PACKAGE) -ifndef LOCAL_JACK_ENABLED $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES) $(hide) mkdir -p $(dir $@) $(MAINDEXCLASSES) $< 1>$@ echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@ $(built_dex_intermediate): $(mainDexList) -endif diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp deleted file mode 100644 index 6d384e31351b..000000000000 --- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/test.jpp +++ /dev/null @@ -1,3 +0,0 @@ -test: - @@com.android.jack.annotations.ForceInMainDex - class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk index 3631626f6b31..480868460d6a 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk +++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk @@ -32,25 +32,13 @@ mainDexList:= \ LOCAL_DEX_PREOPT := false LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex -LOCAL_JACK_FLAGS := -D jack.dex.output.policy=minimal-multidex -D jack.preprocessor=true\ - -D jack.preprocessor.file=$(LOCAL_PATH)/test.jpp -D jack.dex.output.multidex.legacy=true - -################################# -include $(BUILD_SYSTEM)/configure_local_jack.mk -################################# - -ifdef LOCAL_JACK_ENABLED -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/test.jpp -endif include $(BUILD_PACKAGE) -ifndef LOCAL_JACK_ENABLED $(mainDexList): $(full_classes_proguard_jar) | $(MAINDEXCLASSES) $(hide) mkdir -p $(dir $@) $(MAINDEXCLASSES) $< 1>$@ echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@ $(built_dex_intermediate): $(mainDexList) -endif diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp deleted file mode 100644 index 6d384e31351b..000000000000 --- a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/test.jpp +++ /dev/null @@ -1,3 +0,0 @@ -test: - @@com.android.jack.annotations.ForceInMainDex - class com.android.framework.multidexlegacyversionedtestapp.MultiDexUpdateTest diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp index e764034ccd1c..c4c14c9e32d4 100644 --- a/libs/androidfw/Android.bp +++ b/libs/androidfw/Android.bp @@ -79,7 +79,7 @@ cc_library { "libutils", ], shared_libs: [ - "libz-host", + "libz", ], }, windows: { diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp index ab6420e990f9..1d4ed7eeb5e1 100644 --- a/libs/hwui/service/GraphicsStatsService.cpp +++ b/libs/hwui/service/GraphicsStatsService.cpp @@ -22,10 +22,11 @@ #include <google/protobuf/io/zero_copy_stream_impl.h> #include <log/log.h> +#include <errno.h> +#include <fcntl.h> #include <inttypes.h> -#include <sys/types.h> #include <sys/stat.h> -#include <fcntl.h> +#include <sys/types.h> #include <unistd.h> namespace android { @@ -284,4 +285,4 @@ void GraphicsStatsService::finishDump(Dump* dump) { } } /* namespace uirenderer */ -} /* namespace android */
\ No newline at end of file +} /* namespace android */ diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java index fb91bbbbb321..efaf2244e26c 100644 --- a/media/java/android/media/AmrInputStream.java +++ b/media/java/android/media/AmrInputStream.java @@ -25,12 +25,12 @@ import android.util.Log; /** - * AmrInputStream + * DO NOT USE * @hide */ public final class AmrInputStream extends InputStream { private final static String TAG = "AmrInputStream"; - + // frame is 20 msec at 8.000 khz private final static int SAMPLES_PER_FRAME = 8000 * 20 / 1000; @@ -51,10 +51,10 @@ public final class AmrInputStream extends InputStream { private byte[] mOneByte = new byte[1]; /** - * Create a new AmrInputStream, which converts 16 bit PCM to AMR - * @param inputStream InputStream containing 16 bit PCM. + * DO NOT USE - use MediaCodec instead */ public AmrInputStream(InputStream inputStream) { + Log.w(TAG, "@@@@ AmrInputStream is not a public API @@@@"); mInputStream = inputStream; MediaFormat format = new MediaFormat(); @@ -83,17 +83,26 @@ public final class AmrInputStream extends InputStream { mInfo = new BufferInfo(); } + /** + * DO NOT USE + */ @Override public int read() throws IOException { int rtn = read(mOneByte, 0, 1); return rtn == 1 ? (0xff & mOneByte[0]) : -1; } + /** + * DO NOT USE + */ @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } + /** + * DO NOT USE + */ @Override public int read(byte[] b, int offset, int length) throws IOException { if (mCodec == null) { @@ -131,19 +140,15 @@ public final class AmrInputStream extends InputStream { } } - // now read encoded data from the encoder (blocking, since we just filled up the - // encoder's input with data it should be able to output at least one buffer) - while (true) { - int index = mCodec.dequeueOutputBuffer(mInfo, -1); - if (index >= 0) { - mBufIn = mInfo.size; - ByteBuffer out = mCodec.getOutputBuffer(index); - out.get(mBuf, 0 /* offset */, mBufIn /* length */); - mCodec.releaseOutputBuffer(index, false /* render */); - if ((mInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { - mSawOutputEOS = true; - } - break; + // now read encoded data from the encoder + int index = mCodec.dequeueOutputBuffer(mInfo, 0); + if (index >= 0) { + mBufIn = mInfo.size; + ByteBuffer out = mCodec.getOutputBuffer(index); + out.get(mBuf, 0 /* offset */, mBufIn /* length */); + mCodec.releaseOutputBuffer(index, false /* render */); + if ((mInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { + mSawOutputEOS = true; } } } diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index 56a573736c31..8437d03f215d 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -838,6 +838,33 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_OK; } + private int moveObject(int handle, int newParent, String newPath) { + String[] whereArgs = new String[] { Integer.toString(handle) }; + + // do not allow renaming any of the special subdirectories + if (isStorageSubDirectory(newPath)) { + return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED; + } + + // update database + ContentValues values = new ContentValues(); + values.put(Files.FileColumns.DATA, newPath); + values.put(Files.FileColumns.PARENT, newParent); + int updated = 0; + try { + // note - we are relying on a special case in MediaProvider.update() to update + // the paths for all children in the case where this is a directory. + updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in mMediaProvider.update", e); + } + if (updated == 0) { + Log.e(TAG, "Unable to update path for " + handle + " to " + newPath); + return MtpConstants.RESPONSE_GENERAL_ERROR; + } + return MtpConstants.RESPONSE_OK; + } + private int setObjectProperty(int handle, int property, long intValue, String stringValue) { switch (property) { diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index cf4458a6fd49..b9d3d8ffd398 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -68,6 +68,7 @@ static jmethodID method_getObjectPropertyList; static jmethodID method_getObjectInfo; static jmethodID method_getObjectFilePath; static jmethodID method_deleteFile; +static jmethodID method_moveObject; static jmethodID method_getObjectReferences; static jmethodID method_setObjectReferences; static jmethodID method_sessionStarted; @@ -178,6 +179,9 @@ public: virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property); + virtual MtpResponseCode moveObject(MtpObjectHandle handle, MtpObjectHandle newParent, + MtpString& newPath); + virtual void sessionStarted(); virtual void sessionEnded(); @@ -993,6 +997,18 @@ MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) { return result; } +MtpResponseCode MyMtpDatabase::moveObject(MtpObjectHandle handle, MtpObjectHandle newParent, + MtpString &newPath) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + jstring stringValue = env->NewStringUTF((const char *) newPath); + MtpResponseCode result = env->CallIntMethod(mDatabase, method_moveObject, + (jint)handle, (jint)newParent, stringValue); + + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(stringValue); + return result; +} + struct PropertyTableEntry { MtpObjectProperty property; int type; @@ -1358,6 +1374,11 @@ int register_android_mtp_MtpDatabase(JNIEnv *env) ALOGE("Can't find deleteFile"); return -1; } + method_moveObject = env->GetMethodID(clazz, "moveObject", "(IILjava/lang/String;)I"); + if (method_moveObject == NULL) { + ALOGE("Can't find moveObject"); + return -1; + } method_getObjectReferences = env->GetMethodID(clazz, "getObjectReferences", "(I)[I"); if (method_getObjectReferences == NULL) { ALOGE("Can't find getObjectReferences"); diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp index d456950037d4..d7695ef17a08 100644 --- a/native/graphics/jni/Android.bp +++ b/native/graphics/jni/Android.bp @@ -12,6 +12,33 @@ // See the License for the specific language governing permissions and // limitations under the License. +cc_library_shared { + name: "libjnigraphics", + + cflags: [ + "-Wall", + "-Werror", + "-Wunused", + "-Wunreachable-code", + ], + + // our source files + // + srcs: ["bitmap.cpp"], + + shared_libs: [ + "libandroid_runtime", + "libskia", + ], + + arch: { + arm: { + // TODO: This is to work around b/24465209. Remove after root cause is fixed + ldflags: ["-Wl,--hash-style=both"], + }, + }, +} + // The headers module is in frameworks/native/Android.bp. ndk_library { name: "libjnigraphics", diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk deleted file mode 100644 index ec4b35aac9c3..000000000000 --- a/native/graphics/jni/Android.mk +++ /dev/null @@ -1,40 +0,0 @@ -BASE_PATH := $(call my-dir) -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -# setup for skia optimizations -# -ifneq ($(ARCH_ARM_HAVE_VFP),true) - LOCAL_CFLAGS += -DSK_SOFTWARE_FLOAT -endif - -ifeq ($(ARCH_ARM_HAVE_NEON),true) - LOCAL_CFLAGS += -D__ARM_HAVE_NEON -endif - -# our source files -# -LOCAL_SRC_FILES:= \ - bitmap.cpp - -LOCAL_SHARED_LIBRARIES := \ - libandroid_runtime \ - libskia \ - libui \ - libandroidfw - -LOCAL_C_INCLUDES += \ - frameworks/base/native/include \ - frameworks/base/core/jni/android/graphics \ - frameworks/base/libs/hwui - -LOCAL_MODULE:= libjnigraphics - -LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code - -# TODO: This is to work around b/24465209. Remove after root cause is fixed -LOCAL_LDFLAGS_arm := -Wl,--hash-style=both - -include $(BUILD_SHARED_LIBRARY) - diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp index bf5cabbe4bc2..ff14832a2f0f 100644 --- a/native/graphics/jni/bitmap.cpp +++ b/native/graphics/jni/bitmap.cpp @@ -15,7 +15,7 @@ */ #include <android/bitmap.h> -#include <Bitmap.h> +#include <android/graphics/Bitmap.h> int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap, AndroidBitmapInfo* info) { @@ -56,4 +56,3 @@ int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap) { } return ANDROID_BITMAP_RESULT_SUCCESS; } - diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java index 7baa57e7dae7..0cb6423008e5 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java @@ -57,16 +57,16 @@ public class KeyguardSecurityModel { SecurityMode getSecurityMode(int userId) { KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); - if (SubscriptionManager.isValidSubscriptionId( - monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED))) { - return SecurityMode.SimPin; - } - if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId( monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED))) { return SecurityMode.SimPuk; } + if (SubscriptionManager.isValidSubscriptionId( + monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED))) { + return SecurityMode.SimPin; + } + final int security = mLockPatternUtils.getActivePasswordQuality(userId); switch (security) { case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index fe03fba5bfda..16a0e5af1e0a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -64,7 +64,11 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView { // again when the PUK locked SIM is re-entered. case ABSENT: { KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId); - mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser()); + // onSimStateChanged callback can fire when the SIM PIN lock is not currently + // active and mCallback is null. + if (mCallback != null) { + mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser()); + } break; } default: diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 826a03d1b658..fddb12d0f765 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -70,7 +70,11 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView { // move into the READY state and the PUK lock keyguard should be removed. case READY: { KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked(mSubId); - mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser()); + // mCallback can be null if onSimStateChanged callback is called when keyguard + // isn't active. + if (mCallback != null) { + mCallback.dismiss(true, KeyguardUpdateMonitor.getCurrentUser()); + } break; } default: diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 50e4f3d8f947..05e0c9b5048f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1440,6 +1440,11 @@ public class StatusBar extends SystemUI implements DemoMode, } }; + if (hideAnimatedList.isEmpty()) { + animationFinishAction.run(); + return; + } + // let's disable our normal animations mStackScroller.setDismissAllInProgress(true); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java index 7c98e13780f4..2082daf402c2 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java @@ -154,7 +154,7 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference getContext().sendBroadcast(intent); intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_CLOCK); - intent.putExtra("hhmm", "0700"); + intent.putExtra("hhmm", "0800"); getContext().sendBroadcast(intent); intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_NETWORK); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index be236f946551..5c11100f3417 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -19,6 +19,7 @@ package com.android.server; import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.NETID_UNSET; +import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_NONE; import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.getNetworkTypeName; @@ -91,6 +92,7 @@ import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.os.UserHandle; @@ -782,6 +784,13 @@ public class ConnectivityService extends IConnectivityManager.Stub mNetworksDefined++; // used only in the log() statement below. } + // Do the same for Ethernet, since it's often not specified in the configs, although many + // devices can use it via USB host adapters. + if (mNetConfigs[TYPE_ETHERNET] == null && hasService(Context.ETHERNET_SERVICE)) { + mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET); + mNetworksDefined++; + } + if (VDBG) log("mNetworksDefined=" + mNetworksDefined); mProtectedNetworks = new ArrayList<Integer>(); @@ -2979,12 +2988,16 @@ public class ConnectivityService extends IConnectivityManager.Stub return mTethering.getTetheredDhcpRanges(); } + @Override + public boolean isTetheringSupported(String callerPkg) { + ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg); + return isTetheringSupported(); + } + // if ro.tether.denied = true we default to no tethering // gservices could set the secure setting to 1 though to enable it on a build where it // had previously been turned off. - @Override - public boolean isTetheringSupported() { - enforceTetherAccessPermission(); + private boolean isTetheringSupported() { int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true")); boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.TETHER_SUPPORTED, defaultVal)); @@ -5455,6 +5468,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public String getCaptivePortalServerUrl() { + enforceConnectivityInternalPermission(); return NetworkMonitor.getCaptivePortalServerHttpUrl(mContext); } @@ -5552,6 +5566,11 @@ public class ConnectivityService extends IConnectivityManager.Stub return new WakeupMessage(c, h, s, cmd, 0, 0, obj); } + @VisibleForTesting + public boolean hasService(String name) { + return ServiceManager.checkService(name) != null; + } + private void logDefaultNetworkEvent(NetworkAgentInfo newNai, NetworkAgentInfo prevNai) { int newNetid = NETID_UNSET; int prevNetid = NETID_UNSET; diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index 305683139ffd..2e1f142a7d19 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -33,6 +33,7 @@ import android.net.IpSecSpiResponse; import android.net.IpSecTransform; import android.net.IpSecTransformResponse; import android.net.IpSecUdpEncapResponse; +import android.net.NetworkUtils; import android.net.util.NetdService; import android.os.Binder; import android.os.IBinder; @@ -42,11 +43,14 @@ import android.os.ServiceSpecificException; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; +import android.text.TextUtils; import android.util.Log; import android.util.Slog; import android.util.SparseArray; + import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; + import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; @@ -54,6 +58,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.concurrent.atomic.AtomicInteger; + import libcore.io.IoUtils; /** @hide */ @@ -252,7 +257,11 @@ public class IpSecService extends IIpSecService.Stub { return (mReferenceCount.get() > 0); } - public void checkOwnerOrSystemAndThrow() { + /** + * Ensures that the caller is either the owner of this resource or has the system UID and + * throws a SecurityException otherwise. + */ + public void checkOwnerOrSystem() { if (uid != Binder.getCallingUid() && android.os.Process.SYSTEM_UID != Binder.getCallingUid()) { throw new SecurityException("Only the owner may access managed resources!"); @@ -335,12 +344,12 @@ public class IpSecService extends IIpSecService.Stub { private class ManagedResourceArray<T extends ManagedResource> { SparseArray<T> mArray = new SparseArray<>(); - T get(int key) { + T getAndCheckOwner(int key) { T val = mArray.get(key); // The value should never be null unless the resource doesn't exist // (since we do not allow null resources to be added). if (val != null) { - val.checkOwnerOrSystemAndThrow(); + val.checkOwnerOrSystem(); } return val; } @@ -405,12 +414,8 @@ public class IpSecService extends IIpSecService.Stub { .ipSecDeleteSecurityAssociation( mResourceId, direction, - (mConfig.getLocalAddress() != null) - ? mConfig.getLocalAddress().getHostAddress() - : "", - (mConfig.getRemoteAddress() != null) - ? mConfig.getRemoteAddress().getHostAddress() - : "", + mConfig.getLocalAddress(), + mConfig.getRemoteAddress(), spi); } catch (ServiceSpecificException e) { // FIXME: get the error code and throw is at an IOException from Errno Exception @@ -638,11 +643,45 @@ public class IpSecService extends IIpSecService.Stub { } } + /** + * Checks that the provided InetAddress is valid for use in an IPsec SA. The address must not be + * a wildcard address and must be in a numeric form such as 1.2.3.4 or 2001::1. + */ + private static void checkInetAddress(String inetAddress) { + if (TextUtils.isEmpty(inetAddress)) { + throw new IllegalArgumentException("Unspecified address"); + } + + InetAddress checkAddr = NetworkUtils.numericToInetAddress(inetAddress); + + if (checkAddr.isAnyLocalAddress()) { + throw new IllegalArgumentException("Inappropriate wildcard address: " + inetAddress); + } + } + + /** + * Checks the user-provided direction field and throws an IllegalArgumentException if it is not + * DIRECTION_IN or DIRECTION_OUT + */ + private static void checkDirection(int direction) { + switch (direction) { + case IpSecTransform.DIRECTION_OUT: + case IpSecTransform.DIRECTION_IN: + return; + } + throw new IllegalArgumentException("Invalid Direction: " + direction); + } + @Override /** Get a new SPI and maintain the reservation in the system server */ public synchronized IpSecSpiResponse reserveSecurityParameterIndex( int direction, String remoteAddress, int requestedSpi, IBinder binder) throws RemoteException { + checkDirection(direction); + checkInetAddress(remoteAddress); + /* requestedSpi can be anything in the int range, so no check is needed. */ + checkNotNull(binder, "Null Binder passed to reserveSecurityParameterIndex"); + int resourceId = mNextResourceId.getAndIncrement(); int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX; @@ -651,9 +690,7 @@ public class IpSecService extends IIpSecService.Stub { try { if (!mUserQuotaTracker.getUserRecord(Binder.getCallingUid()).spi.isAvailable()) { return new IpSecSpiResponse( - IpSecManager.Status.RESOURCE_UNAVAILABLE, - INVALID_RESOURCE_ID, - spi); + IpSecManager.Status.RESOURCE_UNAVAILABLE, INVALID_RESOURCE_ID, spi); } spi = mSrvConfig @@ -686,7 +723,7 @@ public class IpSecService extends IIpSecService.Stub { throws RemoteException { // We want to non-destructively get so that we can check credentials before removing // this from the records. - T record = resArray.get(resourceId); + T record = resArray.getAndCheckOwner(resourceId); if (record == null) { throw new IllegalArgumentException( @@ -751,6 +788,8 @@ public class IpSecService extends IIpSecService.Stub { throw new IllegalArgumentException( "Specified port number must be a valid non-reserved UDP port"); } + checkNotNull(binder, "Null Binder passed to openUdpEncapsulationSocket"); + int resourceId = mNextResourceId.getAndIncrement(); FileDescriptor sockFd = null; try { @@ -792,6 +831,68 @@ public class IpSecService extends IIpSecService.Stub { } /** + * Checks an IpSecConfig parcel to ensure that the contents are sane and throws an + * IllegalArgumentException if they are not. + */ + private void checkIpSecConfig(IpSecConfig config) { + if (config.getLocalAddress() == null) { + throw new IllegalArgumentException("Invalid null Local InetAddress"); + } + + if (config.getRemoteAddress() == null) { + throw new IllegalArgumentException("Invalid null Remote InetAddress"); + } + + switch (config.getMode()) { + case IpSecTransform.MODE_TRANSPORT: + if (!config.getLocalAddress().isEmpty()) { + throw new IllegalArgumentException("Non-empty Local Address"); + } + // Must be valid, and not a wildcard + checkInetAddress(config.getRemoteAddress()); + break; + case IpSecTransform.MODE_TUNNEL: + break; + default: + throw new IllegalArgumentException( + "Invalid IpSecTransform.mode: " + config.getMode()); + } + + switch (config.getEncapType()) { + case IpSecTransform.ENCAP_NONE: + break; + case IpSecTransform.ENCAP_ESPINUDP: + case IpSecTransform.ENCAP_ESPINUDP_NON_IKE: + if (mUdpSocketRecords.getAndCheckOwner( + config.getEncapSocketResourceId()) == null) { + throw new IllegalStateException( + "No Encapsulation socket for Resource Id: " + + config.getEncapSocketResourceId()); + } + + int port = config.getEncapRemotePort(); + if (port <= 0 || port > 0xFFFF) { + throw new IllegalArgumentException("Invalid remote UDP port: " + port); + } + break; + default: + throw new IllegalArgumentException("Invalid Encap Type: " + config.getEncapType()); + } + + for (int direction : DIRECTIONS) { + IpSecAlgorithm crypt = config.getEncryption(direction); + IpSecAlgorithm auth = config.getAuthentication(direction); + if (crypt == null && auth == null) { + throw new IllegalArgumentException("Encryption and Authentication are both null"); + } + + if (mSpiRecords.getAndCheckOwner(config.getSpiResourceId(direction)) == null) { + throw new IllegalStateException("No SPI for specified Resource Id"); + } + } + } + + /** * Create a transport mode transform, which represent two security associations (one in each * direction) in the kernel. The transform will be cached by the system server and must be freed * when no longer needed. It is possible to free one, deleting the SA from underneath sockets @@ -801,17 +902,19 @@ public class IpSecService extends IIpSecService.Stub { @Override public synchronized IpSecTransformResponse createTransportModeTransform( IpSecConfig c, IBinder binder) throws RemoteException { + checkIpSecConfig(c); + checkNotNull(binder, "Null Binder passed to createTransportModeTransform"); int resourceId = mNextResourceId.getAndIncrement(); if (!mUserQuotaTracker.getUserRecord(Binder.getCallingUid()).transform.isAvailable()) { return new IpSecTransformResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE); } SpiRecord[] spis = new SpiRecord[DIRECTIONS.length]; - // TODO: Basic input validation here since it's coming over the Binder + int encapType, encapLocalPort = 0, encapRemotePort = 0; UdpSocketRecord socketRecord = null; encapType = c.getEncapType(); if (encapType != IpSecTransform.ENCAP_NONE) { - socketRecord = mUdpSocketRecords.get(c.getEncapLocalResourceId()); + socketRecord = mUdpSocketRecords.getAndCheckOwner(c.getEncapSocketResourceId()); encapLocalPort = socketRecord.getPort(); encapRemotePort = c.getEncapRemotePort(); } @@ -820,23 +923,18 @@ public class IpSecService extends IIpSecService.Stub { IpSecAlgorithm auth = c.getAuthentication(direction); IpSecAlgorithm crypt = c.getEncryption(direction); - spis[direction] = mSpiRecords.get(c.getSpiResourceId(direction)); + spis[direction] = mSpiRecords.getAndCheckOwner(c.getSpiResourceId(direction)); int spi = spis[direction].getSpi(); try { - mSrvConfig.getNetdInstance() + mSrvConfig + .getNetdInstance() .ipSecAddSecurityAssociation( resourceId, c.getMode(), direction, - (c.getLocalAddress() != null) - ? c.getLocalAddress().getHostAddress() - : "", - (c.getRemoteAddress() != null) - ? c.getRemoteAddress().getHostAddress() - : "", - (c.getNetwork() != null) - ? c.getNetwork().getNetworkHandle() - : 0, + c.getLocalAddress(), + c.getRemoteAddress(), + (c.getNetwork() != null) ? c.getNetwork().getNetworkHandle() : 0, spi, (auth != null) ? auth.getName() : "", (auth != null) ? auth.getKey() : null, @@ -879,7 +977,7 @@ public class IpSecService extends IIpSecService.Stub { // Synchronize liberally here because we are using ManagedResources in this block TransformRecord info; // FIXME: this code should be factored out into a security check + getter - info = mTransformRecords.get(resourceId); + info = mTransformRecords.getAndCheckOwner(resourceId); if (info == null) { throw new IllegalArgumentException("Transform " + resourceId + " is not active"); @@ -899,12 +997,8 @@ public class IpSecService extends IIpSecService.Stub { socket.getFileDescriptor(), resourceId, direction, - (c.getLocalAddress() != null) - ? c.getLocalAddress().getHostAddress() - : "", - (c.getRemoteAddress() != null) - ? c.getRemoteAddress().getHostAddress() - : "", + c.getLocalAddress(), + c.getRemoteAddress(), info.getSpiRecord(direction).getSpi()); } } catch (ServiceSpecificException e) { diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index caa2d5112bf0..355e94956e6e 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1140,17 +1140,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub } @Override - public void setInterfaceIpv6NdOffload(String iface, boolean enable) { - mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - try { - mConnector.execute( - "interface", "ipv6ndoffload", iface, (enable ? "enable" : "disable")); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); - } - } - - @Override public void addRoute(int netId, RouteInfo route) { modifyRoute("add", "" + netId, route); } @@ -1991,8 +1980,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub final String[] domainStrs = domains == null ? new String[0] : domains.split(" "); final int[] params = { sampleValidity, successThreshold, minSamples, maxSamples }; + final boolean useTls = false; + final String tlsHostname = ""; + final String[] tlsFingerprints = new String[0]; try { - mNetdService.setResolverConfiguration(netId, servers, domainStrs, params); + mNetdService.setResolverConfiguration(netId, servers, domainStrs, params, + useTls, tlsHostname, tlsFingerprints); } catch (RemoteException e) { throw new RuntimeException(e); } diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index f0b1b3baee17..d6a010fc01b3 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -2954,9 +2954,13 @@ public class AccountManagerService * have users launching arbitrary activities by tricking users to * interact with malicious notifications. */ - checkKeyIntent( + if (!checkKeyIntent( Binder.getCallingUid(), - intent); + intent)) { + onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, + "invalid intent in bundle returned"); + return; + } doNotification( mAccounts, account, @@ -3351,9 +3355,13 @@ public class AccountManagerService Intent intent = null; if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { - checkKeyIntent( + if (!checkKeyIntent( Binder.getCallingUid(), - intent); + intent)) { + onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, + "invalid intent in bundle returned"); + return; + } } IAccountManagerResponse response; if (mExpectActivityLaunch && result != null @@ -4700,13 +4708,14 @@ public class AccountManagerService * into launching arbitrary intents on the device via by tricking to click authenticator * supplied entries in the system Settings app. */ - protected void checkKeyIntent( - int authUid, - Intent intent) throws SecurityException { + protected boolean checkKeyIntent(int authUid, Intent intent) { long bid = Binder.clearCallingIdentity(); try { PackageManager pm = mContext.getPackageManager(); ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId); + if (resolveInfo == null) { + return false; + } ActivityInfo targetActivityInfo = resolveInfo.activityInfo; int targetUid = targetActivityInfo.applicationInfo.uid; if (!isExportedSystemActivity(targetActivityInfo) @@ -4716,9 +4725,10 @@ public class AccountManagerService String activityName = targetActivityInfo.name; String tmpl = "KEY_INTENT resolved to an Activity (%s) in a package (%s) that " + "does not share a signature with the supplying authenticator (%s)."; - throw new SecurityException( - String.format(tmpl, activityName, pkgName, mAccountType)); + Log.e(TAG, String.format(tmpl, activityName, pkgName, mAccountType)); + return false; } + return true; } finally { Binder.restoreCallingIdentity(bid); } @@ -4868,9 +4878,13 @@ public class AccountManagerService } if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { - checkKeyIntent( + if (!checkKeyIntent( Binder.getCallingUid(), - intent); + intent)) { + onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, + "invalid intent in bundle returned"); + return; + } } if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java index fbbdf0051266..fceacba4239c 100644 --- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java +++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java @@ -152,7 +152,6 @@ public class Nat464Xlat extends BaseNetworkObserver { * turn ND offload off if on WiFi. */ private void enterRunningState() { - maybeSetIpv6NdOffload(mBaseIface, false); mState = State.RUNNING; } @@ -160,10 +159,6 @@ public class Nat464Xlat extends BaseNetworkObserver { * Stop clatd, and turn ND offload on if it had been turned off. */ private void enterStoppingState() { - if (isRunning()) { - maybeSetIpv6NdOffload(mBaseIface, true); - } - try { mNMService.stopClatd(mBaseIface); } catch(RemoteException|IllegalStateException e) { @@ -279,19 +274,6 @@ public class Nat464Xlat extends BaseNetworkObserver { } } - private void maybeSetIpv6NdOffload(String iface, boolean on) { - // TODO: migrate to NetworkCapabilities.TRANSPORT_*. - if (mNetwork.networkInfo.getType() != ConnectivityManager.TYPE_WIFI) { - return; - } - try { - Slog.d(TAG, (on ? "En" : "Dis") + "abling ND offload on " + iface); - mNMService.setInterfaceIpv6NdOffload(iface, on); - } catch(RemoteException|IllegalStateException e) { - Slog.w(TAG, "Changing IPv6 ND offload on " + iface + "failed: " + e); - } - } - /** * Adds stacked link on base link and transitions to RUNNING state. */ diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 5583e86cde70..d7cd81ff3c5f 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -1371,6 +1371,7 @@ public class Tethering extends BaseNetworkObserver { sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS); } } + mUpstreamNetworkMonitor.setCurrentUpstream((ns != null) ? ns.network : null); setUpstreamNetwork(ns); } diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java index 057704a56c4c..cff216c70aef 100644 --- a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java +++ b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java @@ -596,9 +596,10 @@ public class OffloadController { } mNatUpdateCallbacksReceived++; + final String natDescription = String.format("%s (%s, %s) -> (%s, %s)", + protoName, srcAddr, srcPort, dstAddr, dstPort); if (DBG) { - mLog.log(String.format("NAT timeout update: %s (%s, %s) -> (%s, %s)", - protoName, srcAddr, srcPort, dstAddr, dstPort)); + mLog.log("NAT timeout update: " + natDescription); } final int timeoutSec = connectionTimeoutUpdateSecondsFor(proto); @@ -609,7 +610,7 @@ public class OffloadController { NetlinkSocket.sendOneShotKernelMessage(OsConstants.NETLINK_NETFILTER, msg); } catch (ErrnoException e) { mNatUpdateNetlinkErrors++; - mLog.e("Error updating NAT conntrack entry: " + e + mLog.e("Error updating NAT conntrack entry >" + natDescription + "<: " + e + ", msg: " + NetlinkConstants.hexify(msg)); mLog.log("NAT timeout update callbacks received: " + mNatUpdateCallbacksReceived); mLog.log("NAT timeout update netlink errors: " + mNatUpdateNetlinkErrors); diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java index c5f752807cb7..b35ed75106b3 100644 --- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java @@ -95,7 +95,10 @@ public class UpstreamNetworkMonitor { private NetworkCallback mDefaultNetworkCallback; private NetworkCallback mMobileNetworkCallback; private boolean mDunRequired; - private Network mCurrentDefault; + // The current system default network (not really used yet). + private Network mDefaultInternetNetwork; + // The current upstream network used for tethering. + private Network mTetheringUpstreamNetwork; public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, SharedLog log, int what) { mContext = ctx; @@ -130,10 +133,12 @@ public class UpstreamNetworkMonitor { releaseCallback(mDefaultNetworkCallback); mDefaultNetworkCallback = null; + mDefaultInternetNetwork = null; releaseCallback(mListenAllCallback); mListenAllCallback = null; + mTetheringUpstreamNetwork = null; mNetworkMap.clear(); } @@ -207,7 +212,7 @@ public class UpstreamNetworkMonitor { break; default: /* If we've found an active upstream connection that's not DUN/HIPRI - * we should stop any outstanding DUN/HIPRI start requests. + * we should stop any outstanding DUN/HIPRI requests. * * If we found NONE we don't want to do this as we want any previous * requests to keep trying to bring up something we can use. @@ -219,6 +224,10 @@ public class UpstreamNetworkMonitor { return typeStatePair.ns; } + public void setCurrentUpstream(Network upstream) { + mTetheringUpstreamNetwork = upstream; + } + public Set<IpPrefix> getLocalPrefixes() { return (Set<IpPrefix>) mLocalPrefixes.clone(); } @@ -250,7 +259,7 @@ public class UpstreamNetworkMonitor { // These request*() calls can be deleted post oag/339444. return; } - mCurrentDefault = network; + mDefaultInternetNetwork = network; break; case CALLBACK_MOBILE_REQUEST: @@ -302,6 +311,13 @@ public class UpstreamNetworkMonitor { network, newNc)); } + // Log changes in upstream network signal strength, if available. + if (network.equals(mTetheringUpstreamNetwork) && newNc.hasSignalStrength()) { + final int newSignal = newNc.getSignalStrength(); + final String prevSignal = getSignalStrength(prev.networkCapabilities); + mLog.logf("upstream network signal strength: %s -> %s", prevSignal, newSignal); + } + mNetworkMap.put(network, new NetworkState( null, prev.linkProperties, newNc, network, null, null)); // TODO: If sufficient information is available to select a more @@ -330,9 +346,21 @@ public class UpstreamNetworkMonitor { notifyTarget(EVENT_ON_LINKPROPERTIES, network); } + private void handleSuspended(int callbackType, Network network) { + if (callbackType != CALLBACK_LISTEN_ALL) return; + if (!network.equals(mTetheringUpstreamNetwork)) return; + mLog.log("SUSPENDED current upstream: " + network); + } + + private void handleResumed(int callbackType, Network network) { + if (callbackType != CALLBACK_LISTEN_ALL) return; + if (!network.equals(mTetheringUpstreamNetwork)) return; + mLog.log("RESUMED current upstream: " + network); + } + private void handleLost(int callbackType, Network network) { if (callbackType == CALLBACK_TRACK_DEFAULT) { - mCurrentDefault = null; + mDefaultInternetNetwork = null; // Receiving onLost() for a default network does not necessarily // mean the network is gone. We wait for a separate notification // on either the LISTEN_ALL or MOBILE_REQUEST callbacks before @@ -401,8 +429,15 @@ public class UpstreamNetworkMonitor { recomputeLocalPrefixes(); } - // TODO: Handle onNetworkSuspended(); - // TODO: Handle onNetworkResumed(); + @Override + public void onNetworkSuspended(Network network) { + handleSuspended(mCallbackType, network); + } + + @Override + public void onNetworkResumed(Network network) { + handleResumed(mCallbackType, network); + } @Override public void onLost(Network network) { @@ -467,4 +502,9 @@ public class UpstreamNetworkMonitor { return prefixSet; } + + private static String getSignalStrength(NetworkCapabilities nc) { + if (nc == null || !nc.hasSignalStrength()) return "unknown"; + return Integer.toString(nc.getSignalStrength()); + } } diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index b8fe88439c2d..108cd3250633 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -500,11 +500,12 @@ public final class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { Slog.d(TAG, "Receieved: " + action); } + final String pkgName = getPackageName(intent); + final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1); + if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { // Purge the app's jobs if the whole package was just disabled. When this is // the case the component name will be a bare package name. - final String pkgName = getPackageName(intent); - final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1); if (pkgName != null && pkgUid != -1) { final String[] changedComponents = intent.getStringArrayExtra( Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); @@ -524,7 +525,8 @@ public final class JobSchedulerService extends com.android.server.SystemService Slog.d(TAG, "Removing jobs for package " + pkgName + " in user " + userId); } - cancelJobsForUid(pkgUid, "app package state changed"); + cancelJobsForPackageAndUid(pkgName, pkgUid, + "app disabled"); } } catch (RemoteException|IllegalArgumentException e) { /* @@ -553,7 +555,7 @@ public final class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { Slog.d(TAG, "Removing jobs for uid: " + uidRemoved); } - cancelJobsForUid(uidRemoved, "app uninstalled"); + cancelJobsForPackageAndUid(pkgName, uidRemoved, "app uninstalled"); } } else if (Intent.ACTION_USER_REMOVED.equals(action)) { final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); @@ -564,8 +566,6 @@ public final class JobSchedulerService extends com.android.server.SystemService } else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) { // Has this package scheduled any jobs, such that we will take action // if it were to be force-stopped? - final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1); - final String pkgName = intent.getData().getSchemeSpecificPart(); if (pkgUid != -1) { List<JobStatus> jobsForUid; synchronized (mLock) { @@ -584,13 +584,11 @@ public final class JobSchedulerService extends com.android.server.SystemService } } else if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) { // possible force-stop - final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1); - final String pkgName = intent.getData().getSchemeSpecificPart(); if (pkgUid != -1) { if (DEBUG) { Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid); } - cancelJobsForPackageAndUid(pkgName, pkgUid); + cancelJobsForPackageAndUid(pkgName, pkgUid, "app force stopped"); } } } @@ -759,13 +757,17 @@ public final class JobSchedulerService extends com.android.server.SystemService } } - void cancelJobsForPackageAndUid(String pkgName, int uid) { + void cancelJobsForPackageAndUid(String pkgName, int uid, String reason) { + if ("android".equals(pkgName)) { + Slog.wtfStack(TAG, "Can't cancel all jobs for system package"); + return; + } synchronized (mLock) { final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid); for (int i = jobsForUid.size() - 1; i >= 0; i--) { final JobStatus job = jobsForUid.get(i); if (job.getSourcePackageName().equals(pkgName)) { - cancelJobImplLocked(job, null, "app force stopped"); + cancelJobImplLocked(job, null, reason); } } } @@ -779,6 +781,10 @@ public final class JobSchedulerService extends com.android.server.SystemService * */ public void cancelJobsForUid(int uid, String reason) { + if (uid == Process.SYSTEM_UID) { + Slog.wtfStack(TAG, "Can't cancel all jobs for system uid"); + return; + } synchronized (mLock) { final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid); for (int i=0; i<jobsForUid.size(); i++) { diff --git a/services/net/java/android/net/ip/ConnectivityPacketTracker.java b/services/net/java/android/net/ip/ConnectivityPacketTracker.java index 884a8a754266..1925c39e5211 100644 --- a/services/net/java/android/net/ip/ConnectivityPacketTracker.java +++ b/services/net/java/android/net/ip/ConnectivityPacketTracker.java @@ -25,6 +25,7 @@ import android.os.Handler; import android.system.ErrnoException; import android.system.Os; import android.system.PacketSocketAddress; +import android.text.TextUtils; import android.util.Log; import android.util.LocalLog; @@ -59,13 +60,16 @@ public class ConnectivityPacketTracker { private static final boolean DBG = false; private static final String MARK_START = "--- START ---"; private static final String MARK_STOP = "--- STOP ---"; + private static final String MARK_NAMED_START = "--- START (%s) ---"; + private static final String MARK_NAMED_STOP = "--- STOP (%s) ---"; private final String mTag; - private final Handler mHandler; private final LocalLog mLog; private final BlockingSocketReader mPacketListener; + private boolean mRunning; + private String mDisplayName; - public ConnectivityPacketTracker(NetworkInterface netif, LocalLog log) { + public ConnectivityPacketTracker(Handler h, NetworkInterface netif, LocalLog log) { final String ifname; final int ifindex; final byte[] hwaddr; @@ -81,44 +85,42 @@ public class ConnectivityPacketTracker { } mTag = TAG + "." + ifname; - mHandler = new Handler(); mLog = log; - mPacketListener = new PacketListener(ifindex, hwaddr, mtu); + mPacketListener = new PacketListener(h, ifindex, hwaddr, mtu); } - public void start() { - mLog.log(MARK_START); + public void start(String displayName) { + mRunning = true; + mDisplayName = displayName; mPacketListener.start(); } public void stop() { mPacketListener.stop(); - mLog.log(MARK_STOP); + mRunning = false; + mDisplayName = null; } private final class PacketListener extends BlockingSocketReader { private final int mIfIndex; private final byte mHwAddr[]; - PacketListener(int ifindex, byte[] hwaddr, int mtu) { - super(mtu); + PacketListener(Handler h, int ifindex, byte[] hwaddr, int mtu) { + super(h, mtu); mIfIndex = ifindex; mHwAddr = hwaddr; } @Override - protected FileDescriptor createSocket() { + protected FileDescriptor createFd() { FileDescriptor s = null; try { - // TODO: Evaluate switching to SOCK_DGRAM and changing the - // BlockingSocketReader's read() to recvfrom(), so that this - // might work on non-ethernet-like links (via SLL). s = Os.socket(AF_PACKET, SOCK_RAW, 0); NetworkUtils.attachControlPacketFilter(s, ARPHRD_ETHER); Os.bind(s, new PacketSocketAddress((short) ETH_P_ALL, mIfIndex)); } catch (ErrnoException | IOException e) { logError("Failed to create packet tracking socket: ", e); - closeSocket(s); + closeFd(s); return null; } return s; @@ -136,13 +138,30 @@ public class ConnectivityPacketTracker { } @Override + protected void onStart() { + final String msg = TextUtils.isEmpty(mDisplayName) + ? MARK_START + : String.format(MARK_NAMED_START, mDisplayName); + mLog.log(msg); + } + + @Override + protected void onStop() { + String msg = TextUtils.isEmpty(mDisplayName) + ? MARK_STOP + : String.format(MARK_NAMED_STOP, mDisplayName); + if (!mRunning) msg += " (packet listener stopped unexpectedly)"; + mLog.log(msg); + } + + @Override protected void logError(String msg, Exception e) { Log.e(mTag, msg, e); addLogEntry(msg + e); } private void addLogEntry(String entry) { - mHandler.post(() -> mLog.log(entry)); + mLog.log(entry); } } } diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java index b1eb0854e334..e33f6c99aea8 100644 --- a/services/net/java/android/net/ip/IpManager.java +++ b/services/net/java/android/net/ip/IpManager.java @@ -26,6 +26,7 @@ import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties.ProvisioningChange; import android.net.LinkProperties; +import android.net.Network; import android.net.ProxyInfo; import android.net.RouteInfo; import android.net.StaticIpConfiguration; @@ -348,6 +349,16 @@ public class IpManager extends StateMachine { return this; } + public Builder withNetwork(Network network) { + mConfig.mNetwork = network; + return this; + } + + public Builder withDisplayName(String displayName) { + mConfig.mDisplayName = displayName; + return this; + } + public ProvisioningConfiguration build() { return new ProvisioningConfiguration(mConfig); } @@ -362,6 +373,8 @@ public class IpManager extends StateMachine { /* package */ ApfCapabilities mApfCapabilities; /* package */ int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS; /* package */ int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY; + /* package */ Network mNetwork = null; + /* package */ String mDisplayName = null; public ProvisioningConfiguration() {} // used by Builder @@ -374,6 +387,9 @@ public class IpManager extends StateMachine { mStaticIpConfig = other.mStaticIpConfig; mApfCapabilities = other.mApfCapabilities; mProvisioningTimeoutMs = other.mProvisioningTimeoutMs; + mIPv6AddrGenMode = other.mIPv6AddrGenMode; + mNetwork = other.mNetwork; + mDisplayName = other.mDisplayName; } @Override @@ -388,6 +404,8 @@ public class IpManager extends StateMachine { .add("mApfCapabilities: " + mApfCapabilities) .add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs) .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode) + .add("mNetwork: " + mNetwork) + .add("mDisplayName: " + mDisplayName) .toString(); } @@ -1441,10 +1459,10 @@ public class IpManager extends StateMachine { @Override public void enter() { // Get the Configuration for ApfFilter from Context - boolean filter802_3Frames = + final boolean filter802_3Frames = mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames); - int[] ethTypeBlackList = mContext.getResources().getIntArray( + final int[] ethTypeBlackList = mContext.getResources().getIntArray( R.array.config_apfEthTypeBlackList); mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface, @@ -1456,7 +1474,7 @@ public class IpManager extends StateMachine { } mPacketTracker = createPacketTracker(); - if (mPacketTracker != null) mPacketTracker.start(); + if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName); if (mConfiguration.mEnableIPv6 && !startIPv6()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); @@ -1470,7 +1488,7 @@ public class IpManager extends StateMachine { return; } - InitialConfiguration config = mConfiguration.mInitialConfig; + final InitialConfiguration config = mConfiguration.mInitialConfig; if ((config != null) && !applyInitialConfig(config)) { // TODO introduce a new IpManagerEvent constant to distinguish this error case. doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); @@ -1515,7 +1533,8 @@ public class IpManager extends StateMachine { private ConnectivityPacketTracker createPacketTracker() { try { - return new ConnectivityPacketTracker(mNetworkInterface, mConnectivityPacketLog); + return new ConnectivityPacketTracker( + getHandler(), mNetworkInterface, mConnectivityPacketLog); } catch (IllegalArgumentException e) { return null; } diff --git a/services/net/java/android/net/util/BlockingSocketReader.java b/services/net/java/android/net/util/BlockingSocketReader.java index 12fa1e57653a..99bf46952b4e 100644 --- a/services/net/java/android/net/util/BlockingSocketReader.java +++ b/services/net/java/android/net/util/BlockingSocketReader.java @@ -16,81 +16,106 @@ package android.net.util; +import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; +import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; + import android.annotation.Nullable; +import android.os.Handler; +import android.os.Looper; +import android.os.MessageQueue; +import android.os.MessageQueue.OnFileDescriptorEventListener; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; -import libcore.io.IoBridge; +import libcore.io.IoUtils; import java.io.FileDescriptor; -import java.io.InterruptedIOException; import java.io.IOException; /** - * A thread that reads from a socket and passes the received packets to a - * subclass's handlePacket() method. The packet receive buffer is recycled - * on every read call, so subclasses should make any copies they would like - * inside their handlePacket() implementation. + * This class encapsulates the mechanics of registering a file descriptor + * with a thread's Looper and handling read events (and errors). + * + * Subclasses MUST implement createFd() and SHOULD override handlePacket(). + + * Subclasses can expect a call life-cycle like the following: + * + * [1] start() calls createFd() and (if all goes well) onStart() + * + * [2] yield, waiting for read event or error notification: + * + * [a] readPacket() && handlePacket() * - * All public methods may be called from any thread. + * [b] if (no error): + * goto 2 + * else: + * goto 3 + * + * [3] stop() calls onStop() if not previously stopped + * + * The packet receive buffer is recycled on every read call, so subclasses + * should make any copies they would like inside their handlePacket() + * implementation. + * + * All public methods MUST only be called from the same thread with which + * the Handler constructor argument is associated. + * + * TODO: rename this class to something more correctly descriptive (something + * like [or less horrible than] FdReadEventsHandler?). * * @hide */ public abstract class BlockingSocketReader { + private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR; + private static final int UNREGISTER_THIS_FD = 0; + public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024; + private final Handler mHandler; + private final MessageQueue mQueue; private final byte[] mPacket; - private final Thread mThread; - private volatile FileDescriptor mSocket; - private volatile boolean mRunning; - private volatile long mPacketsReceived; - - // Make it slightly easier for subclasses to properly close a socket - // without having to know this incantation. - public static final void closeSocket(@Nullable FileDescriptor fd) { - try { - IoBridge.closeAndSignalBlockedThreads(fd); - } catch (IOException ignored) {} - } + private FileDescriptor mFd; + private long mPacketsReceived; - protected BlockingSocketReader() { - this(DEFAULT_RECV_BUF_SIZE); + protected static void closeFd(FileDescriptor fd) { + IoUtils.closeQuietly(fd); } - protected BlockingSocketReader(int recvbufsize) { - if (recvbufsize < DEFAULT_RECV_BUF_SIZE) { - recvbufsize = DEFAULT_RECV_BUF_SIZE; - } - mPacket = new byte[recvbufsize]; - mThread = new Thread(() -> { mainLoop(); }); + protected BlockingSocketReader(Handler h) { + this(h, DEFAULT_RECV_BUF_SIZE); } - public final boolean start() { - if (mSocket != null) return false; + protected BlockingSocketReader(Handler h, int recvbufsize) { + mHandler = h; + mQueue = mHandler.getLooper().getQueue(); + mPacket = new byte[Math.max(recvbufsize, DEFAULT_RECV_BUF_SIZE)]; + } - try { - mSocket = createSocket(); - } catch (Exception e) { - logError("Failed to create socket: ", e); - return false; + public final void start() { + if (onCorrectThread()) { + createAndRegisterFd(); + } else { + mHandler.post(() -> { + logError("start() called from off-thread", null); + createAndRegisterFd(); + }); } - - if (mSocket == null) return false; - - mRunning = true; - mThread.start(); - return true; } public final void stop() { - mRunning = false; - closeSocket(mSocket); - mSocket = null; + if (onCorrectThread()) { + unregisterAndDestroyFd(); + } else { + mHandler.post(() -> { + logError("stop() called from off-thread", null); + unregisterAndDestroyFd(); + }); + } } - public final boolean isRunning() { return mRunning; } + public final int recvBufSize() { return mPacket.length; } public final long numPacketsReceived() { return mPacketsReceived; } @@ -98,11 +123,21 @@ public abstract class BlockingSocketReader { * Subclasses MUST create the listening socket here, including setting * all desired socket options, interface or address/port binding, etc. */ - protected abstract FileDescriptor createSocket(); + protected abstract FileDescriptor createFd(); + + /** + * Subclasses MAY override this to change the default read() implementation + * in favour of, say, recvfrom(). + * + * Implementations MUST return the bytes read or throw an Exception. + */ + protected int readPacket(FileDescriptor fd, byte[] packetBuffer) throws Exception { + return Os.read(fd, packetBuffer, 0, packetBuffer.length); + } /** * Called by the main loop for every packet. Any desired copies of - * |recvbuf| should be made in here, and the underlying byte array is + * |recvbuf| should be made in here, as the underlying byte array is * reused across all reads. */ protected void handlePacket(byte[] recvbuf, int length) {} @@ -113,43 +148,102 @@ public abstract class BlockingSocketReader { protected void logError(String msg, Exception e) {} /** - * Called by the main loop just prior to exiting. + * Called by start(), if successful, just prior to returning. + */ + protected void onStart() {} + + /** + * Called by stop() just prior to returning. */ - protected void onExit() {} + protected void onStop() {} + + private void createAndRegisterFd() { + if (mFd != null) return; + + try { + mFd = createFd(); + if (mFd != null) { + // Force the socket to be non-blocking. + IoUtils.setBlocking(mFd, false); + } + } catch (Exception e) { + logError("Failed to create socket: ", e); + closeFd(mFd); + mFd = null; + return; + } + + if (mFd == null) return; + + mQueue.addOnFileDescriptorEventListener( + mFd, + FD_EVENTS, + new OnFileDescriptorEventListener() { + @Override + public int onFileDescriptorEvents(FileDescriptor fd, int events) { + // Always call handleInput() so read/recvfrom are given + // a proper chance to encounter a meaningful errno and + // perhaps log a useful error message. + if (!isRunning() || !handleInput()) { + unregisterAndDestroyFd(); + return UNREGISTER_THIS_FD; + } + return FD_EVENTS; + } + }); + onStart(); + } - private final void mainLoop() { + private boolean isRunning() { return (mFd != null) && mFd.valid(); } + + // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error. + private boolean handleInput() { while (isRunning()) { final int bytesRead; try { - // Blocking read. - // TODO: See if this can be converted to recvfrom. - bytesRead = Os.read(mSocket, mPacket, 0, mPacket.length); + bytesRead = readPacket(mFd, mPacket); if (bytesRead < 1) { if (isRunning()) logError("Socket closed, exiting", null); break; } mPacketsReceived++; } catch (ErrnoException e) { - if (e.errno != OsConstants.EINTR) { - if (isRunning()) logError("read error: ", e); + if (e.errno == OsConstants.EAGAIN) { + // We've read everything there is to read this time around. + return true; + } else if (e.errno == OsConstants.EINTR) { + continue; + } else { + if (isRunning()) logError("readPacket error: ", e); break; } - continue; - } catch (IOException ioe) { - if (isRunning()) logError("read error: ", ioe); - continue; + } catch (Exception e) { + if (isRunning()) logError("readPacket error: ", e); + break; } try { handlePacket(mPacket, bytesRead); } catch (Exception e) { - logError("Unexpected exception: ", e); + logError("handlePacket error: ", e); break; } } - stop(); - onExit(); + return false; + } + + private void unregisterAndDestroyFd() { + if (mFd == null) return; + + mQueue.removeOnFileDescriptorEventListener(mFd); + closeFd(mFd); + mFd = null; + onStop(); + } + + private boolean onCorrectThread() { + return (mHandler.getLooper() == Looper.myLooper()); } } diff --git a/services/net/java/android/net/util/NetworkConstants.java b/services/net/java/android/net/util/NetworkConstants.java index 606526816368..5a3a8be923af 100644 --- a/services/net/java/android/net/util/NetworkConstants.java +++ b/services/net/java/android/net/util/NetworkConstants.java @@ -107,6 +107,20 @@ public final class NetworkConstants { public static final int RFC6177_MIN_PREFIX_LENGTH = 48; /** + * ICMP common (v4/v6) constants. + * + * See also: + * - https://tools.ietf.org/html/rfc792 + * - https://tools.ietf.org/html/rfc4443 + */ + public static final int ICMP_HEADER_TYPE_OFFSET = 0; + public static final int ICMP_HEADER_CODE_OFFSET = 1; + public static final int ICMP_HEADER_CHECKSUM_OFFSET = 2; + public static final int ICMP_ECHO_IDENTIFIER_OFFSET = 4; + public static final int ICMP_ECHO_SEQUENCE_NUMBER_OFFSET = 6; + public static final int ICMP_ECHO_DATA_OFFSET = 8; + + /** * ICMPv6 constants. * * See also: diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java index 343d237f8cd9..bbd3d13efbd6 100644 --- a/services/net/java/android/net/util/SharedLog.java +++ b/services/net/java/android/net/util/SharedLog.java @@ -106,6 +106,10 @@ public class SharedLog { record(Category.NONE, msg); } + public void logf(String fmt, Object... args) { + log(String.format(fmt, args)); + } + public void mark(String msg) { record(Category.MARK, msg); } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 386a3a37fb24..7a6fbf3488bb 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1523,6 +1523,13 @@ public class CarrierConfigManager { public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool"; + /** + * The flag to disable the popup dialog which warns the user of data charges. + * @hide + */ + public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL = + "disable_charge_indication_bool"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -1777,6 +1784,7 @@ public class CarrierConfigManager { sDefaults.putInt(IMSI_KEY_EXPIRATION_DAYS_TIME_INT, IMSI_ENCRYPTION_DAYS_TIME_DISABLED); sDefaults.putString(IMSI_KEY_DOWNLOAD_URL_STRING, null); sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false); + sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false); } /** diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java index ebac0419785c..9a9877a88517 100644 --- a/telephony/java/android/telephony/MbmsDownloadSession.java +++ b/telephony/java/android/telephony/MbmsDownloadSession.java @@ -77,8 +77,9 @@ public class MbmsDownloadSession implements AutoCloseable { * Integer extra that Android will attach to the intent supplied via * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)} * Indicates the result code of the download. One of - * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, {@link #RESULT_CANCELLED}, or - * {@link #RESULT_IO_ERROR}. + * {@link #RESULT_SUCCESSFUL}, {@link #RESULT_EXPIRED}, {@link #RESULT_CANCELLED}, + * {@link #RESULT_IO_ERROR}, {@link #RESULT_DOWNLOAD_FAILURE}, {@link #RESULT_OUT_OF_STORAGE}, + * {@link #RESULT_SERVICE_ID_NOT_DEFINED}, or {@link #RESULT_FILE_ROOT_UNREACHABLE}. * * This extra may also be used by the middleware when it is sending intents to the app. */ @@ -142,11 +143,41 @@ public class MbmsDownloadSession implements AutoCloseable { /** * Indicates that the download will not be completed due to an I/O error incurred while - * writing to temp files. This commonly indicates that the device is out of storage space, - * but may indicate other conditions as well (such as an SD card being removed). + * writing to temp files. + * + * This is likely a transient error and another {@link DownloadRequest} should be sent to try + * the download again. */ public static final int RESULT_IO_ERROR = 4; - // TODO - more results! + + /** + * Indicates that the Service ID specified in the {@link DownloadRequest} is incorrect due to + * the Id being incorrect, stale, expired, or similar. + */ + public static final int RESULT_SERVICE_ID_NOT_DEFINED = 5; + + /** + * Indicates that there was an error while processing downloaded files, such as a file repair or + * file decoding error and is not due to a file I/O error. + * + * This is likely a transient error and another {@link DownloadRequest} should be sent to try + * the download again. + */ + public static final int RESULT_DOWNLOAD_FAILURE = 6; + + /** + * Indicates that the file system is full and the {@link DownloadRequest} can not complete. + * Either space must be made on the current file system or the temp file root location must be + * changed to a location that is not full to download the temp files. + */ + public static final int RESULT_OUT_OF_STORAGE = 7; + + /** + * Indicates that the file root that was set is currently unreachable. This can happen if the + * temp files are set to be stored on external storage and the SD card was removed, for example. + * The temp file root should be changed before sending another DownloadRequest. + */ + public static final int RESULT_FILE_ROOT_UNREACHABLE = 8; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -522,8 +553,7 @@ public class MbmsDownloadSession implements AutoCloseable { * @param handler The {@link Handler} on which calls to {@code callback} should be enqueued on. */ public void registerStateCallback(@NonNull DownloadRequest request, - @NonNull DownloadStateCallback callback, - @NonNull Handler handler) { + @NonNull DownloadStateCallback callback, @NonNull Handler handler) { IMbmsDownloadService downloadService = mService.get(); if (downloadService == null) { throw new IllegalStateException("Middleware not yet bound"); @@ -533,7 +563,8 @@ public class MbmsDownloadSession implements AutoCloseable { new InternalDownloadStateCallback(callback, handler); try { - int result = downloadService.registerStateCallback(request, internalCallback); + int result = downloadService.registerStateCallback(request, internalCallback, + callback.getCallbackFilterFlags()); if (result != MbmsErrors.SUCCESS) { if (result == MbmsErrors.DownloadErrors.ERROR_UNKNOWN_DOWNLOAD_REQUEST) { throw new IllegalArgumentException("Unknown download request."); diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java index 5a57f3221d3a..f0d60b68eb94 100644 --- a/telephony/java/android/telephony/mbms/DownloadRequest.java +++ b/telephony/java/android/telephony/mbms/DownloadRequest.java @@ -16,6 +16,7 @@ package android.telephony.mbms; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.content.Intent; import android.net.Uri; @@ -26,7 +27,6 @@ import android.util.Log; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -71,6 +71,19 @@ public final class DownloadRequest implements Parcelable { private String appIntent; private int version = CURRENT_VERSION; + + /** + * Builds a new DownloadRequest. + * @param sourceUri the source URI for the DownloadRequest to be built. This URI should + * never be null. + */ + public Builder(@NonNull Uri sourceUri) { + if (sourceUri == null) { + throw new IllegalArgumentException("Source URI must be non-null."); + } + source = sourceUri; + } + /** * Sets the service from which the download request to be built will download from. * @param serviceInfo @@ -92,15 +105,6 @@ public final class DownloadRequest implements Parcelable { } /** - * Sets the source URI for the download request to be built. - * @param source - */ - public Builder setSource(Uri source) { - this.source = source; - return this; - } - - /** * Set the subscription ID on which the file(s) should be downloaded. * @param subscriptionId */ @@ -316,9 +320,11 @@ public final class DownloadRequest implements Parcelable { throw new RuntimeException("Could not get sha256 hash object"); } if (version >= 1) { - // Hash the source URI, destination URI, and the app intent + // Hash the source URI and the app intent digest.update(sourceUri.toString().getBytes(StandardCharsets.UTF_8)); - digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8)); + if (serializedResultIntentForApp != null) { + digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8)); + } } // Add updates for future versions here return Base64.encodeToString(digest.digest(), Base64.URL_SAFE | Base64.NO_WRAP); diff --git a/telephony/java/android/telephony/mbms/DownloadStateCallback.java b/telephony/java/android/telephony/mbms/DownloadStateCallback.java index 86920bd3b205..892fbf078ea1 100644 --- a/telephony/java/android/telephony/mbms/DownloadStateCallback.java +++ b/telephony/java/android/telephony/mbms/DownloadStateCallback.java @@ -16,8 +16,12 @@ package android.telephony.mbms; +import android.annotation.IntDef; import android.telephony.MbmsDownloadSession; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * A optional listener class used by download clients to track progress. Apps should extend this * class and pass an instance into @@ -29,6 +33,71 @@ import android.telephony.MbmsDownloadSession; public class DownloadStateCallback { /** + * Bitmask flags used for filtering out callback methods. Used when constructing the + * DownloadStateCallback as an optional parameter. + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ALL_UPDATES, PROGRESS_UPDATES, STATE_UPDATES}) + public @interface FilterFlag {} + + /** + * Receive all callbacks. + * Default value. + */ + public static final int ALL_UPDATES = 0x00; + /** + * Receive callbacks for {@link #onProgressUpdated}. + */ + public static final int PROGRESS_UPDATES = 0x01; + /** + * Receive callbacks for {@link #onStateUpdated}. + */ + public static final int STATE_UPDATES = 0x02; + + private final int mCallbackFilterFlags; + + /** + * Creates a DownloadStateCallback that will receive all callbacks. + */ + public DownloadStateCallback() { + mCallbackFilterFlags = ALL_UPDATES; + } + + /** + * Creates a DownloadStateCallback that will only receive callbacks for the methods specified + * via the filterFlags parameter. + * @param filterFlags A bitmask of filter flags that will specify which callback this instance + * is interested in. + */ + public DownloadStateCallback(int filterFlags) { + mCallbackFilterFlags = filterFlags; + } + + /** + * Return the currently set filter flags. + * @return An integer containing the bitmask of flags that this instance is interested in. + * @hide + */ + public int getCallbackFilterFlags() { + return mCallbackFilterFlags; + } + + /** + * Returns true if a filter flag is set for a particular callback method. If the flag is set, + * the callback will be delivered to the listening process. + * @param flag A filter flag specifying whether or not a callback method is registered to + * receive callbacks. + * @return true if registered to receive callbacks in the listening process, false if not. + */ + public final boolean isFilterFlagSet(@FilterFlag int flag) { + if (mCallbackFilterFlags == ALL_UPDATES) { + return true; + } + return (mCallbackFilterFlags & flag) > 0; + } + + /** * Called when the middleware wants to report progress for a file in a {@link DownloadRequest}. * * @param request a {@link DownloadRequest}, indicating which download is being referenced. diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java index 61415b50b2d2..9af1eb9e14d7 100644 --- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java +++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java @@ -165,6 +165,12 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { Log.w(LOG_TAG, "Download result did not include a result code. Ignoring."); return false; } + // We do not need to verify below extras if the result is not success. + if (MbmsDownloadSession.RESULT_SUCCESSFUL != + intent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, + MbmsDownloadSession.RESULT_CANCELLED)) { + return true; + } if (!intent.hasExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST)) { Log.w(LOG_TAG, "Download result did not include the associated request. Ignoring."); return false; @@ -281,7 +287,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { return; } - List<Uri> tempFiles = intent.getParcelableExtra(VendorUtils.EXTRA_TEMP_LIST); + List<Uri> tempFiles = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_LIST); if (tempFiles == null) { return; } @@ -303,7 +309,7 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { return; } int fdCount = intent.getIntExtra(VendorUtils.EXTRA_FD_COUNT, 0); - List<Uri> pausedList = intent.getParcelableExtra(VendorUtils.EXTRA_PAUSED_LIST); + List<Uri> pausedList = intent.getParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST); if (fdCount == 0 && (pausedList == null || pausedList.size() == 0)) { Log.i(LOG_TAG, "No temp files actually requested. Ending."); @@ -486,9 +492,14 @@ public class MbmsDownloadReceiver extends BroadcastReceiver { } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException("Package manager couldn't find " + context.getPackageName()); } + if (appInfo.metaData == null) { + throw new RuntimeException("App must declare the file provider authority as metadata " + + "in the manifest."); + } String authority = appInfo.metaData.getString(MBMS_FILE_PROVIDER_META_DATA_KEY); if (authority == null) { - throw new RuntimeException("Must declare the file provider authority as meta data"); + throw new RuntimeException("App must declare the file provider authority as metadata " + + "in the manifest."); } return authority; } diff --git a/telephony/java/android/telephony/mbms/ServiceInfo.java b/telephony/java/android/telephony/mbms/ServiceInfo.java index 9a01ed00e0cd..8529f525e06f 100644 --- a/telephony/java/android/telephony/mbms/ServiceInfo.java +++ b/telephony/java/android/telephony/mbms/ServiceInfo.java @@ -23,6 +23,7 @@ import android.os.Parcelable; import android.text.TextUtils; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -62,12 +63,6 @@ public class ServiceInfo { throw new RuntimeException("bad locales length " + newLocales.size()); } - for (Locale l : newLocales) { - if (!newNames.containsKey(l)) { - throw new IllegalArgumentException("A name must be provided for each locale"); - } - } - names = new HashMap(newNames.size()); names.putAll(newNames); className = newClassName; @@ -127,7 +122,7 @@ public class ServiceInfo { * Get the user-displayable name for this cell-broadcast service corresponding to the * provided {@link Locale}. * @param locale The {@link Locale} in which you want the name of the service. This must be a - * value from the list returned by {@link #getLocales()} -- an + * value from the set returned by {@link #getNamedContentLocales()} -- an * {@link java.util.NoSuchElementException} may be thrown otherwise. * @return The {@link CharSequence} providing the name of the service in the given * {@link Locale} @@ -140,6 +135,17 @@ public class ServiceInfo { } /** + * Return an unmodifiable set of the current {@link Locale}s that have a user-displayable name + * associated with them. The user-displayable name associated with any {@link Locale} in this + * set can be retrieved with {@link #getNameForLocale(Locale)}. + * @return An unmodifiable set of {@link Locale} objects corresponding to a user-displayable + * content name in that locale. + */ + public @NonNull Set<Locale> getNamedContentLocales() { + return Collections.unmodifiableSet(names.keySet()); + } + + /** * The class name for this service - used to categorize and filter */ public String getServiceClassName() { diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl index ed5e8268fc77..cb93542ff168 100755 --- a/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl +++ b/telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl @@ -36,7 +36,8 @@ interface IMbmsDownloadService int download(in DownloadRequest downloadRequest); - int registerStateCallback(in DownloadRequest downloadRequest, IDownloadStateCallback listener); + int registerStateCallback(in DownloadRequest downloadRequest, IDownloadStateCallback listener, + int flags); int unregisterStateCallback(in DownloadRequest downloadRequest, IDownloadStateCallback listener); diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java index d845a57b946a..2f85a1df8a22 100644 --- a/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java +++ b/telephony/java/android/telephony/mbms/vendor/MbmsDownloadServiceBase.java @@ -46,6 +46,47 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub { private final Map<IBinder, DownloadStateCallback> mDownloadCallbackBinderMap = new HashMap<>(); private final Map<IBinder, DeathRecipient> mDownloadCallbackDeathRecipients = new HashMap<>(); + + // Filters the DownloadStateCallbacks by its configuration from the app. + private abstract static class FilteredDownloadStateCallback extends DownloadStateCallback { + + private final IDownloadStateCallback mCallback; + public FilteredDownloadStateCallback(IDownloadStateCallback callback, int callbackFlags) { + super(callbackFlags); + mCallback = callback; + } + + @Override + public void onProgressUpdated(DownloadRequest request, FileInfo fileInfo, + int currentDownloadSize, int fullDownloadSize, int currentDecodedSize, + int fullDecodedSize) { + if (!isFilterFlagSet(PROGRESS_UPDATES)) { + return; + } + try { + mCallback.onProgressUpdated(request, fileInfo, currentDownloadSize, + fullDownloadSize, currentDecodedSize, fullDecodedSize); + } catch (RemoteException e) { + onRemoteException(e); + } + } + + @Override + public void onStateUpdated(DownloadRequest request, FileInfo fileInfo, + @MbmsDownloadSession.DownloadStatus int state) { + if (!isFilterFlagSet(STATE_UPDATES)) { + return; + } + try { + mCallback.onStateUpdated(request, fileInfo, state); + } catch (RemoteException e) { + onRemoteException(e); + } + } + + protected abstract void onRemoteException(RemoteException e); + } + /** * Initialize the download service for this app and subId, registering the listener. * @@ -196,9 +237,8 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub { * @hide */ @Override - public final int registerStateCallback( - final DownloadRequest downloadRequest, final IDownloadStateCallback callback) - throws RemoteException { + public final int registerStateCallback(final DownloadRequest downloadRequest, + final IDownloadStateCallback callback, int flags) throws RemoteException { final int uid = Binder.getCallingUid(); DeathRecipient deathRecipient = new DeathRecipient() { @Override @@ -211,28 +251,10 @@ public class MbmsDownloadServiceBase extends IMbmsDownloadService.Stub { mDownloadCallbackDeathRecipients.put(callback.asBinder(), deathRecipient); callback.asBinder().linkToDeath(deathRecipient, 0); - DownloadStateCallback exposedCallback = new DownloadStateCallback() { + DownloadStateCallback exposedCallback = new FilteredDownloadStateCallback(callback, flags) { @Override - public void onProgressUpdated(DownloadRequest request, FileInfo fileInfo, int - currentDownloadSize, int fullDownloadSize, int currentDecodedSize, int - fullDecodedSize) { - try { - callback.onProgressUpdated(request, fileInfo, currentDownloadSize, - fullDownloadSize, - currentDecodedSize, fullDecodedSize); - } catch (RemoteException e) { - onAppCallbackDied(uid, downloadRequest.getSubscriptionId()); - } - } - - @Override - public void onStateUpdated(DownloadRequest request, FileInfo fileInfo, - @MbmsDownloadSession.DownloadStatus int state) { - try { - callback.onStateUpdated(request, fileInfo, state); - } catch (RemoteException e) { - onAppCallbackDied(uid, downloadRequest.getSubscriptionId()); - } + protected void onRemoteException(RemoteException e) { + onAppCallbackDied(uid, downloadRequest.getSubscriptionId()); } }; diff --git a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java index 8fb27b2953e6..a43f12244168 100644 --- a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java +++ b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java @@ -38,8 +38,9 @@ public class VendorUtils { /** * The MBMS middleware should send this when a download of single file has completed or - * failed. Mandatory extras are + * failed. The only mandatory extra is * {@link MbmsDownloadSession#EXTRA_MBMS_DOWNLOAD_RESULT} + * and the following are required when the download has completed: * {@link MbmsDownloadSession#EXTRA_MBMS_FILE_INFO} * {@link MbmsDownloadSession#EXTRA_MBMS_DOWNLOAD_REQUEST} * {@link #EXTRA_TEMP_LIST} diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java new file mode 100644 index 000000000000..1b4bef5d2f43 --- /dev/null +++ b/tests/net/java/android/net/IpSecConfigTest.java @@ -0,0 +1,98 @@ +/* + * 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.net; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; +import android.support.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link IpSecConfig}. */ +@SmallTest +@RunWith(JUnit4.class) +public class IpSecConfigTest { + + @Test + public void testDefaults() throws Exception { + IpSecConfig c = new IpSecConfig(); + assertEquals(IpSecTransform.MODE_TRANSPORT, c.getMode()); + assertEquals("", c.getLocalAddress()); + assertEquals("", c.getRemoteAddress()); + assertNull(c.getNetwork()); + assertEquals(IpSecTransform.ENCAP_NONE, c.getEncapType()); + assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getEncapSocketResourceId()); + assertEquals(0, c.getEncapRemotePort()); + assertEquals(0, c.getNattKeepaliveInterval()); + for (int direction : + new int[] {IpSecTransform.DIRECTION_OUT, IpSecTransform.DIRECTION_IN}) { + assertNull(c.getEncryption(direction)); + assertNull(c.getAuthentication(direction)); + assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getSpiResourceId(direction)); + } + } + + @Test + public void testParcelUnparcel() throws Exception { + assertParcelingIsLossless(new IpSecConfig()); + + IpSecConfig c = new IpSecConfig(); + c.setMode(IpSecTransform.MODE_TUNNEL); + c.setLocalAddress("0.0.0.0"); + c.setRemoteAddress("1.2.3.4"); + c.setEncapType(android.system.OsConstants.UDP_ENCAP_ESPINUDP); + c.setEncapSocketResourceId(7); + c.setEncapRemotePort(22); + c.setNattKeepaliveInterval(42); + c.setEncryption( + IpSecTransform.DIRECTION_OUT, + new IpSecAlgorithm( + IpSecAlgorithm.CRYPT_AES_CBC, + new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF})); + c.setAuthentication( + IpSecTransform.DIRECTION_OUT, + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA1, + new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0})); + c.setSpiResourceId(IpSecTransform.DIRECTION_OUT, 1984); + c.setEncryption( + IpSecTransform.DIRECTION_IN, + new IpSecAlgorithm( + IpSecAlgorithm.CRYPT_AES_CBC, + new byte[] {2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF})); + c.setAuthentication( + IpSecTransform.DIRECTION_IN, + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA1, + new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 1})); + c.setSpiResourceId(IpSecTransform.DIRECTION_IN, 99); + assertParcelingIsLossless(c); + } + + private void assertParcelingIsLossless(IpSecConfig ci) throws Exception { + Parcel p = Parcel.obtain(); + ci.writeToParcel(p, 0); + p.setDataPosition(0); + IpSecConfig co = IpSecConfig.CREATOR.createFromParcel(p); + assertTrue(IpSecConfig.equals(co, ci)); + } +} diff --git a/tests/net/java/android/net/IpSecManagerTest.java b/tests/net/java/android/net/IpSecManagerTest.java index 9f31d27508b2..ccb0f3b07d0f 100644 --- a/tests/net/java/android/net/IpSecManagerTest.java +++ b/tests/net/java/android/net/IpSecManagerTest.java @@ -31,19 +31,21 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; import android.system.Os; -import android.test.AndroidTestCase; + import com.android.server.IpSecService; + import java.net.InetAddress; import java.net.UnknownHostException; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; /** Unit tests for {@link IpSecManager}. */ @SmallTest -@RunWith(JUnit4.class) +@RunWith(AndroidJUnit4.class) public class IpSecManagerTest { private static final int TEST_UDP_ENCAP_PORT = 34567; diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/tests/net/java/android/net/LinkPropertiesTest.java index 1cb0ecdba7f3..52da79a18c6e 100644 --- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java +++ b/tests/net/java/android/net/LinkPropertiesTest.java @@ -16,19 +16,22 @@ package android.net; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.LinkProperties.CompareResult; import android.net.LinkProperties.ProvisioningChange; import android.net.RouteInfo; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; import android.system.OsConstants; -import android.test.suitebuilder.annotation.SmallTest; -import android.test.suitebuilder.annotation.Suppress; import android.util.ArraySet; -import junit.framework.TestCase; - import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; @@ -37,8 +40,12 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import org.junit.Test; +import org.junit.runner.RunWith; -public class LinkPropertiesTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LinkPropertiesTest { private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1"); private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress( "2001:0db8:85a3:0000:0000:8a2e:0370:7334"); @@ -92,7 +99,7 @@ public class LinkPropertiesTest extends TestCase { assertEquals(source.hashCode(), target.hashCode()); } - @SmallTest + @Test public void testEqualsNull() { LinkProperties source = new LinkProperties(); LinkProperties target = new LinkProperties(); @@ -101,155 +108,141 @@ public class LinkPropertiesTest extends TestCase { assertLinkPropertiesEqual(source, target); } - @SmallTest - public void testEqualsSameOrder() { - try { - LinkProperties source = new LinkProperties(); - source.setInterfaceName(NAME); - // set 2 link addresses - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV6); - // set 2 dnses - source.addDnsServer(DNS1); - source.addDnsServer(DNS2); - // set 2 gateways - source.addRoute(new RouteInfo(GATEWAY1)); - source.addRoute(new RouteInfo(GATEWAY2)); - source.setMtu(MTU); - - LinkProperties target = new LinkProperties(); - - // All fields are same - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - - assertLinkPropertiesEqual(source, target); - - target.clear(); - // change Interface Name - target.setInterfaceName("qmi1"); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - // change link addresses - target.addLinkAddress(new LinkAddress( - NetworkUtils.numericToInetAddress("75.208.6.2"), 32)); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - // change dnses - target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2")); - target.addDnsServer(DNS2); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - // change gateway - target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2"))); - target.addRoute(new RouteInfo(GATEWAY2)); - target.setMtu(MTU); - assertFalse(source.equals(target)); - - target.clear(); - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addDnsServer(DNS1); - target.addDnsServer(DNS2); - target.addRoute(new RouteInfo(GATEWAY1)); - target.addRoute(new RouteInfo(GATEWAY2)); - // change mtu - target.setMtu(1440); - assertFalse(source.equals(target)); - - } catch (Exception e) { - throw new RuntimeException(e.toString()); - //fail(); - } + @Test + public void testEqualsSameOrder() throws Exception { + LinkProperties source = new LinkProperties(); + source.setInterfaceName(NAME); + // set 2 link addresses + source.addLinkAddress(LINKADDRV4); + source.addLinkAddress(LINKADDRV6); + // set 2 dnses + source.addDnsServer(DNS1); + source.addDnsServer(DNS2); + // set 2 gateways + source.addRoute(new RouteInfo(GATEWAY1)); + source.addRoute(new RouteInfo(GATEWAY2)); + source.setMtu(MTU); + + LinkProperties target = new LinkProperties(); + + // All fields are same + target.setInterfaceName(NAME); + target.addLinkAddress(LINKADDRV4); + target.addLinkAddress(LINKADDRV6); + target.addDnsServer(DNS1); + target.addDnsServer(DNS2); + target.addRoute(new RouteInfo(GATEWAY1)); + target.addRoute(new RouteInfo(GATEWAY2)); + target.setMtu(MTU); + + assertLinkPropertiesEqual(source, target); + + target.clear(); + // change Interface Name + target.setInterfaceName("qmi1"); + target.addLinkAddress(LINKADDRV4); + target.addLinkAddress(LINKADDRV6); + target.addDnsServer(DNS1); + target.addDnsServer(DNS2); + target.addRoute(new RouteInfo(GATEWAY1)); + target.addRoute(new RouteInfo(GATEWAY2)); + target.setMtu(MTU); + assertFalse(source.equals(target)); + + target.clear(); + target.setInterfaceName(NAME); + // change link addresses + target.addLinkAddress(new LinkAddress( + NetworkUtils.numericToInetAddress("75.208.6.2"), 32)); + target.addLinkAddress(LINKADDRV6); + target.addDnsServer(DNS1); + target.addDnsServer(DNS2); + target.addRoute(new RouteInfo(GATEWAY1)); + target.addRoute(new RouteInfo(GATEWAY2)); + target.setMtu(MTU); + assertFalse(source.equals(target)); + + target.clear(); + target.setInterfaceName(NAME); + target.addLinkAddress(LINKADDRV4); + target.addLinkAddress(LINKADDRV6); + // change dnses + target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2")); + target.addDnsServer(DNS2); + target.addRoute(new RouteInfo(GATEWAY1)); + target.addRoute(new RouteInfo(GATEWAY2)); + target.setMtu(MTU); + assertFalse(source.equals(target)); + + target.clear(); + target.setInterfaceName(NAME); + target.addLinkAddress(LINKADDRV4); + target.addLinkAddress(LINKADDRV6); + target.addDnsServer(DNS1); + target.addDnsServer(DNS2); + // change gateway + target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2"))); + target.addRoute(new RouteInfo(GATEWAY2)); + target.setMtu(MTU); + assertFalse(source.equals(target)); + + target.clear(); + target.setInterfaceName(NAME); + target.addLinkAddress(LINKADDRV4); + target.addLinkAddress(LINKADDRV6); + target.addDnsServer(DNS1); + target.addDnsServer(DNS2); + target.addRoute(new RouteInfo(GATEWAY1)); + target.addRoute(new RouteInfo(GATEWAY2)); + // change mtu + target.setMtu(1440); + assertFalse(source.equals(target)); } - @SmallTest - public void testEqualsDifferentOrder() { - try { - LinkProperties source = new LinkProperties(); - source.setInterfaceName(NAME); - // set 2 link addresses - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV6); - // set 2 dnses - source.addDnsServer(DNS1); - source.addDnsServer(DNS2); - // set 2 gateways - source.addRoute(new RouteInfo(GATEWAY1)); - source.addRoute(new RouteInfo(GATEWAY2)); - source.setMtu(MTU); - - LinkProperties target = new LinkProperties(); - // Exchange order - target.setInterfaceName(NAME); - target.addLinkAddress(LINKADDRV6); - target.addLinkAddress(LINKADDRV4); - target.addDnsServer(DNS2); - target.addDnsServer(DNS1); - target.addRoute(new RouteInfo(GATEWAY2)); - target.addRoute(new RouteInfo(GATEWAY1)); - target.setMtu(MTU); - - assertLinkPropertiesEqual(source, target); - } catch (Exception e) { - fail(); - } + @Test + public void testEqualsDifferentOrder() throws Exception { + LinkProperties source = new LinkProperties(); + source.setInterfaceName(NAME); + // set 2 link addresses + source.addLinkAddress(LINKADDRV4); + source.addLinkAddress(LINKADDRV6); + // set 2 dnses + source.addDnsServer(DNS1); + source.addDnsServer(DNS2); + // set 2 gateways + source.addRoute(new RouteInfo(GATEWAY1)); + source.addRoute(new RouteInfo(GATEWAY2)); + source.setMtu(MTU); + + LinkProperties target = new LinkProperties(); + // Exchange order + target.setInterfaceName(NAME); + target.addLinkAddress(LINKADDRV6); + target.addLinkAddress(LINKADDRV4); + target.addDnsServer(DNS2); + target.addDnsServer(DNS1); + target.addRoute(new RouteInfo(GATEWAY2)); + target.addRoute(new RouteInfo(GATEWAY1)); + target.setMtu(MTU); + + assertLinkPropertiesEqual(source, target); } - @SmallTest - public void testEqualsDuplicated() { - try { - LinkProperties source = new LinkProperties(); - // set 3 link addresses, eg, [A, A, B] - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV4); - source.addLinkAddress(LINKADDRV6); - - LinkProperties target = new LinkProperties(); - // set 3 link addresses, eg, [A, B, B] - target.addLinkAddress(LINKADDRV4); - target.addLinkAddress(LINKADDRV6); - target.addLinkAddress(LINKADDRV6); - - assertLinkPropertiesEqual(source, target); - } catch (Exception e) { - fail(); - } + @Test + public void testEqualsDuplicated() throws Exception { + LinkProperties source = new LinkProperties(); + // set 3 link addresses, eg, [A, A, B] + source.addLinkAddress(LINKADDRV4); + source.addLinkAddress(LINKADDRV4); + source.addLinkAddress(LINKADDRV6); + + LinkProperties target = new LinkProperties(); + // set 3 link addresses, eg, [A, B, B] + target.addLinkAddress(LINKADDRV4); + target.addLinkAddress(LINKADDRV6); + target.addLinkAddress(LINKADDRV6); + + assertLinkPropertiesEqual(source, target); } private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) { @@ -258,7 +251,7 @@ public class LinkPropertiesTest extends TestCase { } } - @SmallTest + @Test public void testRouteInterfaces() { LinkAddress prefix = new LinkAddress( NetworkUtils.numericToInetAddress("2001:db8::"), 32); @@ -317,7 +310,7 @@ public class LinkPropertiesTest extends TestCase { assertEquals(3, lp.compareAllRoutes(lp2).removed.size()); } - @SmallTest + @Test public void testStackedInterfaces() { LinkProperties rmnet0 = new LinkProperties(); rmnet0.setInterfaceName("rmnet0"); @@ -373,7 +366,7 @@ public class LinkPropertiesTest extends TestCase { return lp.getLinkAddresses().iterator().next(); } - @SmallTest + @Test public void testAddressMethods() { LinkProperties lp = new LinkProperties(); @@ -460,7 +453,7 @@ public class LinkPropertiesTest extends TestCase { assertEquals(0, lp.getLinkAddresses().size()); } - @SmallTest + @Test public void testSetLinkAddresses() { LinkProperties lp = new LinkProperties(); lp.addLinkAddress(LINKADDRV4); @@ -475,7 +468,7 @@ public class LinkPropertiesTest extends TestCase { assertTrue(lp.equals(lp)); } - @SmallTest + @Test public void testIsProvisioned() { LinkProperties lp4 = new LinkProperties(); assertFalse("v4only:empty", lp4.isProvisioned()); @@ -529,7 +522,7 @@ public class LinkPropertiesTest extends TestCase { assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned()); } - @SmallTest + @Test public void testCompareProvisioning() { LinkProperties v4lp = new LinkProperties(); v4lp.addLinkAddress(LINKADDRV4); @@ -589,8 +582,7 @@ public class LinkPropertiesTest extends TestCase { LinkProperties.compareProvisioning(v6lp, v6lp2)); } - @SmallTest - @Suppress // Failing. + @Test public void testIsReachable() { final LinkProperties v4lp = new LinkProperties(); assertFalse(v4lp.isReachable(DNS1)); @@ -687,7 +679,7 @@ public class LinkPropertiesTest extends TestCase { assertTrue(v6lp.isReachable(DNS1)); } - @SmallTest + @Test public void testLinkPropertiesEnsureDirectlyConnectedRoutes() { // IPv4 case: no route added initially LinkProperties rmnet0 = new LinkProperties(); @@ -750,25 +742,25 @@ public class LinkPropertiesTest extends TestCase { } - @SmallTest + @Test public void testCompareResult() { // Either adding or removing items - testCompareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1), + compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1), Arrays.asList(2, 3, 4), new ArrayList<>()); - testCompareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4), + compareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4), new ArrayList<>(), Arrays.asList(3, 4)); // adding and removing items at the same time - testCompareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5), + compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5), Arrays.asList(1), Arrays.asList(5)); - testCompareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), + compareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6)); // null cases - testCompareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>()); - testCompareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3)); - testCompareResult(null, null, new ArrayList<>(), new ArrayList<>()); + compareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>()); + compareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3)); + compareResult(null, null, new ArrayList<>(), new ArrayList<>()); } private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) { @@ -780,7 +772,7 @@ public class LinkPropertiesTest extends TestCase { assertEquals(expectedSet, actualSet); } - private <T> void testCompareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved, + private <T> void compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved, List<T> expectAdded) { CompareResult<T> result = new CompareResult<>(oldItems, newItems); assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added)); diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java index eb85eb445cbc..25289ba92e24 100644 --- a/tests/net/java/android/net/NetworkStatsTest.java +++ b/tests/net/java/android/net/NetworkStatsTest.java @@ -30,23 +30,30 @@ import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; -import android.test.suitebuilder.annotation.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import com.google.android.collect.Sets; -import junit.framework.TestCase; - import java.util.HashSet; +import org.junit.runner.RunWith; +import org.junit.Test; + +@RunWith(AndroidJUnit4.class) @SmallTest -public class NetworkStatsTest extends TestCase { +public class NetworkStatsTest { private static final String TEST_IFACE = "test0"; private static final String TEST_IFACE2 = "test2"; private static final int TEST_UID = 1001; private static final long TEST_START = 1194220800000L; + @Test public void testFindIndex() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 5) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L, @@ -74,6 +81,7 @@ public class NetworkStatsTest extends TestCase { ROAMING_NO)); } + @Test public void testFindIndexHinted() { final NetworkStats stats = new NetworkStats(TEST_START, 3) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L, @@ -116,6 +124,7 @@ public class NetworkStatsTest extends TestCase { } } + @Test public void testAddEntryGrow() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 4); @@ -168,6 +177,7 @@ public class NetworkStatsTest extends TestCase { ROAMING_YES, 7L, 70L, 5L, 50L, 11); } + @Test public void testCombineExisting() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 10); @@ -190,6 +200,7 @@ public class NetworkStatsTest extends TestCase { 256L, 2L, 256L, 2L, 6); } + @Test public void testSubtractIdenticalData() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) @@ -208,6 +219,7 @@ public class NetworkStatsTest extends TestCase { 0L, 0L, 0L, 0); } + @Test public void testSubtractIdenticalRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) @@ -226,6 +238,7 @@ public class NetworkStatsTest extends TestCase { 1L, 4L, 1L, 8); } + @Test public void testSubtractNewRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) @@ -247,6 +260,7 @@ public class NetworkStatsTest extends TestCase { 1024L, 8L, 1024L, 8L, 20); } + @Test public void testSubtractMissingRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0) @@ -264,6 +278,7 @@ public class NetworkStatsTest extends TestCase { assertEquals(4L, result.getTotalBytes()); } + @Test public void testTotalBytes() throws Exception { final NetworkStats iface = new NetworkStats(TEST_START, 2) .addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L) @@ -304,6 +319,7 @@ public class NetworkStatsTest extends TestCase { assertEquals(96L, uidRoaming.getTotalBytes()); } + @Test public void testGroupedByIfaceEmpty() throws Exception { final NetworkStats uidStats = new NetworkStats(TEST_START, 3); final NetworkStats grouped = uidStats.groupedByIface(); @@ -312,6 +328,7 @@ public class NetworkStatsTest extends TestCase { assertEquals(0, grouped.size()); } + @Test public void testGroupedByIfaceAll() throws Exception { final NetworkStats uidStats = new NetworkStats(TEST_START, 3) .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, 0L, @@ -329,6 +346,7 @@ public class NetworkStatsTest extends TestCase { 384L, 24L, 0L, 6L, 0L); } + @Test public void testGroupedByIface() throws Exception { final NetworkStats uidStats = new NetworkStats(TEST_START, 7) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, @@ -357,6 +375,7 @@ public class NetworkStatsTest extends TestCase { 1024L, 64L, 0L, 0L, 0L); } + @Test public void testAddAllValues() { final NetworkStats first = new NetworkStats(TEST_START, 5) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L, @@ -387,6 +406,7 @@ public class NetworkStatsTest extends TestCase { 32L, 0L, 0L, 0L, 0L); } + @Test public void testGetTotal() { final NetworkStats stats = new NetworkStats(TEST_START, 7) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, @@ -415,6 +435,7 @@ public class NetworkStatsTest extends TestCase { assertValues(stats.getTotal(null, ifaces), 1024L, 64L, 0L, 0L, 0L); } + @Test public void testWithoutUid() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 3) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) @@ -433,6 +454,7 @@ public class NetworkStatsTest extends TestCase { 8L, 0L, 0L, 0L); } + @Test public void testClone() throws Exception { final NetworkStats original = new NetworkStats(TEST_START, 5) .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L) @@ -449,6 +471,7 @@ public class NetworkStatsTest extends TestCase { assertEquals(128L + 512L, clone.getTotalBytes()); } + @Test public void testAddWhenEmpty() throws Exception { final NetworkStats red = new NetworkStats(TEST_START, -1); final NetworkStats blue = new NetworkStats(TEST_START, 5) @@ -459,6 +482,7 @@ public class NetworkStatsTest extends TestCase { red.combineAllValues(blue); } + @Test public void testMigrateTun() throws Exception { final int tunUid = 10030; final String tunIface = "tun0"; @@ -556,6 +580,7 @@ public class NetworkStatsTest extends TestCase { // interface by the vpn app before it's sent out of the underlying interface. The VPN app should // not be charged for the echoed data but it should still be charged for any extra data it sends // via the underlying interface. + @Test public void testMigrateTun_VpnAsLoopback() { final int tunUid = 10030; final String tunIface = "tun0"; diff --git a/core/tests/coretests/src/android/net/NetworkTest.java b/tests/net/java/android/net/NetworkTest.java index 74b6d982b0dc..bacf986b3627 100644 --- a/core/tests/coretests/src/android/net/NetworkTest.java +++ b/tests/net/java/android/net/NetworkTest.java @@ -16,13 +16,17 @@ package android.net; -import static android.test.MoreAsserts.assertNotEqual; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.Network; -import android.test.suitebuilder.annotation.SmallTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; import java.io.File; import java.io.FileDescriptor; @@ -32,13 +36,17 @@ import java.net.DatagramSocket; import java.net.InetAddress; import java.net.Inet6Address; import java.net.SocketException; +import java.util.Objects; -import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; -public class NetworkTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class NetworkTest { final Network mNetwork = new Network(99); - @SmallTest + @Test public void testBindSocketOfInvalidFdThrows() throws Exception { final FileDescriptor fd = new FileDescriptor(); @@ -50,7 +58,7 @@ public class NetworkTest extends TestCase { } catch (SocketException expected) {} } - @SmallTest + @Test public void testBindSocketOfNonSocketFdThrows() throws Exception { final File devNull = new File("/dev/null"); assertTrue(devNull.canRead()); @@ -65,7 +73,7 @@ public class NetworkTest extends TestCase { } catch (SocketException expected) {} } - @SmallTest + @Test public void testBindSocketOfConnectedDatagramSocketThrows() throws Exception { final DatagramSocket mDgramSocket = new DatagramSocket(0, (InetAddress) Inet6Address.ANY); mDgramSocket.connect((InetAddress) Inet6Address.LOOPBACK, 53); @@ -77,7 +85,7 @@ public class NetworkTest extends TestCase { } catch (SocketException expected) {} } - @SmallTest + @Test public void testBindSocketOfLocalSocketThrows() throws Exception { final LocalSocket mLocalClient = new LocalSocket(); mLocalClient.bind(new LocalSocketAddress("testClient")); @@ -98,7 +106,7 @@ public class NetworkTest extends TestCase { } catch (SocketException expected) {} } - @SmallTest + @Test public void testZeroIsObviousForDebugging() { Network zero = new Network(0); assertEquals(0, zero.hashCode()); @@ -106,7 +114,7 @@ public class NetworkTest extends TestCase { assertEquals("0", zero.toString()); } - @SmallTest + @Test public void testGetNetworkHandle() { Network one = new Network(1); Network two = new Network(2); @@ -143,4 +151,8 @@ public class NetworkTest extends TestCase { assertEquals(8606370526L, two.getNetworkHandle()); assertEquals(12901337822L, three.getNetworkHandle()); } + + private static <T> void assertNotEqual(T t1, T t2) { + assertFalse(Objects.equals(t1, t2)); + } } diff --git a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java b/tests/net/java/android/net/StaticIpConfigurationTest.java index 59f780fefb8b..5bb573455358 100644 --- a/core/tests/coretests/src/android/net/StaticIpConfigurationTest.java +++ b/tests/net/java/android/net/StaticIpConfigurationTest.java @@ -16,22 +16,26 @@ package android.net; -import android.net.IpPrefix; -import android.net.LinkAddress; -import android.net.RouteInfo; -import android.net.StaticIpConfiguration; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import android.os.Parcel; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; import java.net.InetAddress; import java.util.HashSet; +import java.util.Objects; -import junit.framework.TestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import static org.junit.Assert.*; +import org.junit.Test; +import org.junit.runner.RunWith; - -public class StaticIpConfigurationTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class StaticIpConfigurationTest { private static final String ADDRSTR = "192.0.2.2/25"; private static final LinkAddress ADDR = new LinkAddress(ADDRSTR); @@ -53,16 +57,8 @@ public class StaticIpConfigurationTest extends TestCase { assertEquals(0, s.dnsServers.size()); } - private boolean isEqual(StaticIpConfiguration s1, StaticIpConfiguration s2) { - return s1.equals(s2); - } - - private void assertEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) { - assertTrue(isEqual(s1, s2)); - } - - private void assertNotEquals(StaticIpConfiguration s1, StaticIpConfiguration s2) { - assertFalse(isEqual(s1, s2)); + private static <T> void assertNotEquals(T t1, T t2) { + assertFalse(Objects.equals(t1, t2)); } private StaticIpConfiguration makeTestObject() { @@ -76,13 +72,13 @@ public class StaticIpConfigurationTest extends TestCase { return s; } - @SmallTest + @Test public void testConstructor() { StaticIpConfiguration s = new StaticIpConfiguration(); checkEmpty(s); } - @SmallTest + @Test public void testCopyAndClear() { StaticIpConfiguration empty = new StaticIpConfiguration((StaticIpConfiguration) null); checkEmpty(empty); @@ -94,7 +90,7 @@ public class StaticIpConfigurationTest extends TestCase { assertEquals(empty, s2); } - @SmallTest + @Test public void testHashCodeAndEquals() { HashSet<Integer> hashCodes = new HashSet(); hashCodes.add(0); @@ -143,7 +139,7 @@ public class StaticIpConfigurationTest extends TestCase { assertNotEquals(s, s2); } - @SmallTest + @Test public void testToLinkProperties() { LinkProperties expected = new LinkProperties(); expected.setInterfaceName(IFACE); @@ -215,11 +211,10 @@ public class StaticIpConfigurationTest extends TestCase { return s2; } - @SmallTest + @Test public void testParceling() { StaticIpConfiguration s = makeTestObject(); StaticIpConfiguration s2 = passThroughParcel(s); assertEquals(s, s2); } } - diff --git a/tests/net/java/android/net/UidRangeTest.java b/tests/net/java/android/net/UidRangeTest.java index 0a56e1be6cae..1d1013e79219 100644 --- a/tests/net/java/android/net/UidRangeTest.java +++ b/tests/net/java/android/net/UidRangeTest.java @@ -16,14 +16,20 @@ package android.net; -import android.os.Parcel; -import android.test.suitebuilder.annotation.SmallTest; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; -import junit.framework.TestCase; +import android.os.Parcel; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; -import static org.junit.Assert.assertArrayEquals; +import org.junit.runner.RunWith; +import org.junit.Test; -public class UidRangeTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class UidRangeTest { static { System.loadLibrary("frameworksnettestsjni"); @@ -33,7 +39,7 @@ public class UidRangeTest extends TestCase { private static native int getStart(byte[] inParcel); private static native int getStop(byte[] inParcel); - @SmallTest + @Test public void testNativeParcelUnparcel() { UidRange original = new UidRange(1234, Integer.MAX_VALUE); @@ -45,7 +51,7 @@ public class UidRangeTest extends TestCase { assertArrayEquals(inParcel, outParcel); } - @SmallTest + @Test public void testIndividualNativeFields() { UidRange original = new UidRange(0x11115678, 0x22224321); byte[] originalBytes = marshall(original); @@ -54,14 +60,14 @@ public class UidRangeTest extends TestCase { assertEquals(original.stop, getStop(originalBytes)); } - @SmallTest + @Test public void testSingleItemUidRangeAllowed() { new UidRange(123, 123); new UidRange(0, 0); new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE); } - @SmallTest + @Test public void testNegativeUidsDisallowed() { try { new UidRange(-2, 100); @@ -76,7 +82,7 @@ public class UidRangeTest extends TestCase { } } - @SmallTest + @Test public void testStopLessThanStartDisallowed() { final int x = 4195000; try { diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java index 5008a4188905..99a2ad942003 100644 --- a/tests/net/java/android/net/apf/ApfTest.java +++ b/tests/net/java/android/net/apf/ApfTest.java @@ -16,6 +16,16 @@ package android.net.apf; +import static android.system.OsConstants.*; +import static com.android.internal.util.BitUtils.bytesToBEInt; +import static com.android.internal.util.BitUtils.put; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.verify; + import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkUtils; @@ -30,23 +40,22 @@ import android.net.metrics.RaEvent; import android.os.ConditionVariable; import android.os.Parcelable; import android.os.SystemClock; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.system.ErrnoException; import android.system.Os; -import android.test.AndroidTestCase; import android.text.format.DateUtils; -import android.test.suitebuilder.annotation.SmallTest; -import static android.system.OsConstants.*; import com.android.frameworks.tests.net.R; import com.android.internal.util.HexDump; -import static com.android.internal.util.BitUtils.bytesToBEInt; -import static com.android.internal.util.BitUtils.put; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.verify; import java.io.File; import java.io.FileDescriptor; @@ -69,14 +78,15 @@ import libcore.io.Streams; * Build, install and run with: * runtest frameworks-net -c android.net.apf.ApfTest */ -public class ApfTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ApfTest { private static final int TIMEOUT_MS = 500; @Mock IpConnectivityLog mLog; - @Override + @Before public void setUp() throws Exception { - super.setUp(); MockitoAnnotations.initMocks(this); // Load up native shared library containing APF interpreter exposed via JNI. System.loadLibrary("frameworksnettestsjni"); @@ -161,7 +171,7 @@ public class ApfTest extends AndroidTestCase { * generating bytecode for that program and running it through the * interpreter to verify it functions correctly. */ - @SmallTest + @Test public void testApfInstructions() throws IllegalInstructionException { // Empty program should pass because having the program counter reach the // location immediately after the program indicates the packet should be @@ -569,7 +579,7 @@ public class ApfTest extends AndroidTestCase { * Generate some BPF programs, translate them to APF, then run APF and BPF programs * over packet traces and verify both programs filter out the same packets. */ - @SmallTest + @Test public void testApfAgainstBpf() throws Exception { String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53", "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24", @@ -739,7 +749,7 @@ public class ApfTest extends AndroidTestCase { private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2}; private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0}; - @SmallTest + @Test public void testApfFilterIPv4() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); @@ -796,7 +806,7 @@ public class ApfTest extends AndroidTestCase { apfFilter.shutdown(); } - @SmallTest + @Test public void testApfFilterIPv6() throws Exception { final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); @@ -830,7 +840,7 @@ public class ApfTest extends AndroidTestCase { apfFilter.shutdown(); } - @SmallTest + @Test public void testApfFilterMulticast() throws Exception { final byte[] unicastIpv4Addr = {(byte)192,0,2,63}; final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255}; @@ -922,7 +932,7 @@ public class ApfTest extends AndroidTestCase { apfFilter.shutdown(); } - @SmallTest + @Test public void testApfFilter802_3() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); @@ -973,7 +983,7 @@ public class ApfTest extends AndroidTestCase { apfFilter.shutdown(); } - @SmallTest + @Test public void testApfFilterEthTypeBL() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); @@ -1058,7 +1068,7 @@ public class ApfTest extends AndroidTestCase { assertDrop(program, garpReply()); } - @SmallTest + @Test public void testApfFilterArp() throws Exception { final int[] ethTypeBlackList = {}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); @@ -1136,7 +1146,7 @@ public class ApfTest extends AndroidTestCase { // Test that when ApfFilter is shown the given packet, it generates a program to filter it // for the given lifetime. - private void testRaLifetime(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback, + private void verifyRaLifetime(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback, ByteBuffer packet, int lifetime) throws IOException, ErrnoException { // Verify new program generated if ApfFilter witnesses RA ipManagerCallback.resetApfProgramWait(); @@ -1181,7 +1191,7 @@ public class ApfTest extends AndroidTestCase { ipManagerCallback.assertNoProgramUpdate(); } - @SmallTest + @Test public void testApfFilterRa() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); final int[] ethTypeBlackList = {}; @@ -1212,7 +1222,7 @@ public class ApfTest extends AndroidTestCase { basePacket.put(IPV6_ALL_NODES_ADDRESS); assertPass(program, basePacket.array()); - testRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME); + verifyRaLifetime(apfFilter, ipManagerCallback, basePacket, ROUTER_LIFETIME); verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1)); ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]); @@ -1247,7 +1257,8 @@ public class ApfTest extends AndroidTestCase { prefixOptionPacket.putInt( ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET, PREFIX_VALID_LIFETIME); - testRaLifetime(apfFilter, ipManagerCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME); + verifyRaLifetime( + apfFilter, ipManagerCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME); verifyRaEvent(new RaEvent( ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1)); @@ -1259,7 +1270,7 @@ public class ApfTest extends AndroidTestCase { rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8)); rdnssOptionPacket.putInt( ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME); - testRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, RDNSS_LIFETIME); + verifyRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, RDNSS_LIFETIME); verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1)); ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap( @@ -1270,7 +1281,7 @@ public class ApfTest extends AndroidTestCase { routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8)); routeInfoOptionPacket.putInt( ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME); - testRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, ROUTE_LIFETIME); + verifyRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, ROUTE_LIFETIME); verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1)); ByteBuffer dnsslOptionPacket = ByteBuffer.wrap( @@ -1281,7 +1292,7 @@ public class ApfTest extends AndroidTestCase { dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8)); dnsslOptionPacket.putInt( ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME); - testRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, ROUTER_LIFETIME); + verifyRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, ROUTER_LIFETIME); verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME)); // Verify that current program filters all five RAs: @@ -1301,12 +1312,12 @@ public class ApfTest extends AndroidTestCase { * copy that resource into the app's data directory and return the path to it. */ private String stageFile(int rawId) throws Exception { - File file = new File(getContext().getFilesDir(), "staged_file"); + File file = new File(InstrumentationRegistry.getContext().getFilesDir(), "staged_file"); new File(file.getParent()).mkdirs(); InputStream in = null; OutputStream out = null; try { - in = getContext().getResources().openRawResource(rawId); + in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId); out = new FileOutputStream(file); Streams.copy(in, out); } finally { @@ -1323,7 +1334,7 @@ public class ApfTest extends AndroidTestCase { buffer.position(original); } - @SmallTest + @Test public void testRaParsing() throws Exception { final int maxRandomPacketSize = 512; final Random r = new Random(); @@ -1343,7 +1354,7 @@ public class ApfTest extends AndroidTestCase { } } - @SmallTest + @Test public void testRaProcessing() throws Exception { final int maxRandomPacketSize = 512; final Random r = new Random(); @@ -1383,7 +1394,7 @@ public class ApfTest extends AndroidTestCase { private native static boolean compareBpfApf(String filter, String pcap_filename, byte[] apf_program); - @SmallTest + @Test public void testBroadcastAddress() throws Exception { assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0)); assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32)); diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/tests/net/java/android/net/dhcp/DhcpPacketTest.java index d79c312a9edd..050183c1ac1f 100644 --- a/tests/net/java/android/net/dhcp/DhcpPacketTest.java +++ b/tests/net/java/android/net/dhcp/DhcpPacketTest.java @@ -16,23 +16,36 @@ package android.net.dhcp; +import static android.net.dhcp.DhcpPacket.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import android.net.DhcpResults; import android.net.LinkAddress; import android.net.NetworkUtils; import android.net.metrics.DhcpErrorEvent; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.system.OsConstants; -import android.test.suitebuilder.annotation.SmallTest; + import com.android.internal.util.HexDump; + import java.net.Inet4Address; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; -import junit.framework.TestCase; -import static android.net.dhcp.DhcpPacket.*; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; -public class DhcpPacketTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class DhcpPacketTest { private static Inet4Address SERVER_ADDR = v4Address("192.0.2.1"); private static Inet4Address CLIENT_ADDR = v4Address("192.0.2.234"); @@ -46,6 +59,7 @@ public class DhcpPacketTest extends TestCase { return (Inet4Address) NetworkUtils.numericToInetAddress(addrString); } + @Before public void setUp() { DhcpPacket.testOverrideVendorId = "android-dhcp-???"; DhcpPacket.testOverrideHostname = "android-01234567890abcde"; @@ -131,7 +145,7 @@ public class DhcpPacketTest extends TestCase { assertEquals(expectedVendorInfo, offerPacket.mVendorInfo); } - @SmallTest + @Test public void testDomainName() throws Exception { byte[] nullByte = new byte[] { 0x00 }; byte[] twoNullBytes = new byte[] { 0x00, 0x00 }; @@ -186,7 +200,7 @@ public class DhcpPacketTest extends TestCase { assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis()); } - @SmallTest + @Test public void testLeaseTime() throws Exception { byte[] noLease = null; byte[] tooShortLease = new byte[] { 0x00, 0x00 }; @@ -234,7 +248,7 @@ public class DhcpPacketTest extends TestCase { } } - @SmallTest + @Test public void testIpAddress() throws Exception { byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 }; byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 }; @@ -278,11 +292,11 @@ public class DhcpPacketTest extends TestCase { assertEquals(mtu, dhcpResults.mtu); } - @SmallTest + @Test public void testOffer1() throws Exception { - // TODO: Turn all of these into golden files. This will probably require modifying - // Android.mk appropriately, making this into an AndroidTestCase, and adding code to read - // the golden files from the test APK's assets via mContext.getAssets(). + // TODO: Turn all of these into golden files. This will probably require using + // android.support.test.InstrumentationRegistry for obtaining a Context object + // to read such golden files, along with an appropriate Android.mk. final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // IP header. "451001480000000080118849c0a89003c0a89ff7" + @@ -311,7 +325,7 @@ public class DhcpPacketTest extends TestCase { null, "192.168.144.3", null, 7200, false, 0, dhcpResults); } - @SmallTest + @Test public void testOffer2() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // IP header. @@ -343,7 +357,7 @@ public class DhcpPacketTest extends TestCase { assertTrue(dhcpResults.hasMeteredHint()); } - @SmallTest + @Test public void testBadIpPacket() throws Exception { final byte[] packet = HexDump.hexStringToByteArray( // IP header. @@ -358,7 +372,7 @@ public class DhcpPacketTest extends TestCase { fail("Dhcp packet parsing should have failed"); } - @SmallTest + @Test public void testBadDhcpPacket() throws Exception { final byte[] packet = HexDump.hexStringToByteArray( // IP header. @@ -377,7 +391,7 @@ public class DhcpPacketTest extends TestCase { fail("Dhcp packet parsing should have failed"); } - @SmallTest + @Test public void testBadTruncatedOffer() throws Exception { final byte[] packet = HexDump.hexStringToByteArray( // IP header. @@ -406,7 +420,7 @@ public class DhcpPacketTest extends TestCase { fail("Dhcp packet parsing should have failed"); } - @SmallTest + @Test public void testBadOfferWithoutACookie() throws Exception { final byte[] packet = HexDump.hexStringToByteArray( // IP header. @@ -437,7 +451,7 @@ public class DhcpPacketTest extends TestCase { fail("Dhcp packet parsing should have failed"); } - @SmallTest + @Test public void testOfferWithBadCookie() throws Exception { final byte[] packet = HexDump.hexStringToByteArray( // IP header. @@ -473,7 +487,7 @@ public class DhcpPacketTest extends TestCase { assertEquals(Integer.toHexString(expected), Integer.toHexString(got)); } - @SmallTest + @Test public void testTruncatedOfferPackets() throws Exception { final byte[] packet = HexDump.hexStringToByteArray( // IP header. @@ -507,7 +521,7 @@ public class DhcpPacketTest extends TestCase { } } - @SmallTest + @Test public void testRandomPackets() throws Exception { final int maxRandomPacketSize = 512; final Random r = new Random(); @@ -547,7 +561,7 @@ public class DhcpPacketTest extends TestCase { null, "192.168.144.3", null, 7200, false, expectedMtu, dhcpResults); } - @SmallTest + @Test public void testMtu() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // IP header. @@ -583,7 +597,7 @@ public class DhcpPacketTest extends TestCase { checkMtu(packet, 0, mtuBytes(-1)); } - @SmallTest + @Test public void testBadHwaddrLength() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // IP header. @@ -652,7 +666,7 @@ public class DhcpPacketTest extends TestCase { assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac())); } - @SmallTest + @Test public void testPadAndOverloadedOptionsOffer() throws Exception { // A packet observed in the real world that is interesting for two reasons: // @@ -691,7 +705,7 @@ public class DhcpPacketTest extends TestCase { null, "1.1.1.1", null, 43200, false, 0, dhcpResults); } - @SmallTest + @Test public void testBug2111() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // IP header. @@ -721,7 +735,7 @@ public class DhcpPacketTest extends TestCase { "domain123.co.uk", "192.0.2.254", null, 49094, false, 0, dhcpResults); } - @SmallTest + @Test public void testBug2136() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // Ethernet header. @@ -754,7 +768,7 @@ public class DhcpPacketTest extends TestCase { "lancs.ac.uk", "10.32.255.128", null, 7200, false, 0, dhcpResults); } - @SmallTest + @Test public void testUdpServerAnySourcePort() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // Ethernet header. @@ -789,7 +803,7 @@ public class DhcpPacketTest extends TestCase { "wvm.edu", "10.1.105.252", null, 86400, false, 0, dhcpResults); } - @SmallTest + @Test public void testUdpInvalidDstPort() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // Ethernet header. @@ -821,7 +835,7 @@ public class DhcpPacketTest extends TestCase { } catch (ParseException expected) {} } - @SmallTest + @Test public void testMultipleRouters() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray( // Ethernet header. @@ -854,7 +868,7 @@ public class DhcpPacketTest extends TestCase { null, "192.171.189.2", null, 28800, false, 0, dhcpResults); } - @SmallTest + @Test public void testDiscoverPacket() throws Exception { short secs = 7; int transactionId = 0xdeadbeef; diff --git a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java index 5deba27d80dc..6647760f2ea9 100644 --- a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java +++ b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java @@ -19,20 +19,30 @@ package android.net.netlink; import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST; import static android.net.netlink.StructNlMsgHdr.NLM_F_ACK; import static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import android.net.netlink.NetlinkConstants; import android.net.netlink.NetlinkErrorMessage; import android.net.netlink.NetlinkMessage; import android.net.netlink.StructNlMsgErr; -import android.test.suitebuilder.annotation.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.util.Log; + import java.nio.ByteBuffer; import java.nio.ByteOrder; -import junit.framework.TestCase; + +import org.junit.runner.RunWith; +import org.junit.Test; + import libcore.util.HexEncoding; -public class NetlinkErrorMessageTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class NetlinkErrorMessageTest { private final String TAG = "NetlinkErrorMessageTest"; // Hexadecimal representation of packet capture. @@ -54,7 +64,7 @@ public class NetlinkErrorMessageTest extends TestCase { public static final byte[] NLM_ERROR_OK = HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false); - @SmallTest + @Test public void testParseNlmErrorOk() { final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. diff --git a/tests/net/java/android/net/netlink/NetlinkSocketTest.java b/tests/net/java/android/net/netlink/NetlinkSocketTest.java index 78b3b704e786..bd36bac8d5e2 100644 --- a/tests/net/java/android/net/netlink/NetlinkSocketTest.java +++ b/tests/net/java/android/net/netlink/NetlinkSocketTest.java @@ -16,25 +16,35 @@ package android.net.netlink; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import android.net.netlink.NetlinkSocket; import android.net.netlink.RtNetlinkNeighborMessage; import android.net.netlink.StructNdMsg; import android.net.netlink.StructNlMsgHdr; -import android.test.suitebuilder.annotation.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.system.ErrnoException; import android.system.NetlinkSocketAddress; import android.system.OsConstants; import android.util.Log; + import java.io.InterruptedIOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import junit.framework.TestCase; + +import org.junit.runner.RunWith; +import org.junit.Test; -public class NetlinkSocketTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class NetlinkSocketTest { private final String TAG = "NetlinkSocketTest"; - @SmallTest + @Test public void testBasicWorkingGetNeighborsQuery() throws Exception { NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE); assertNotNull(s); @@ -93,7 +103,7 @@ public class NetlinkSocketTest extends TestCase { s.close(); } - @SmallTest + @Test public void testRepeatedCloseCallsAreQuiet() throws Exception { // Create a working NetlinkSocket. NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE); diff --git a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java index 029758eb6e5b..c9fd74fcddd9 100644 --- a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java +++ b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java @@ -16,15 +16,19 @@ package android.net.netlink; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import android.net.netlink.NetlinkConstants; import android.net.netlink.NetlinkMessage; import android.net.netlink.RtNetlinkNeighborMessage; import android.net.netlink.StructNdMsg; import android.net.netlink.StructNlMsgHdr; -import android.test.suitebuilder.annotation.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.system.OsConstants; import android.util.Log; -import libcore.util.HexEncoding; import java.net.Inet4Address; import java.net.InetAddress; @@ -32,10 +36,15 @@ import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; -import junit.framework.TestCase; +import org.junit.runner.RunWith; +import org.junit.Test; + +import libcore.util.HexEncoding; -public class RtNetlinkNeighborMessageTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class RtNetlinkNeighborMessageTest { private final String TAG = "RtNetlinkNeighborMessageTest"; // Hexadecimal representation of packet capture. @@ -136,7 +145,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase { public static final byte[] RTM_GETNEIGH_RESPONSE = HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false); - @SmallTest + @Test public void testParseRtmDelNeigh() { final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. @@ -163,7 +172,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase { assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination); } - @SmallTest + @Test public void testParseRtmNewNeigh() { final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. @@ -190,7 +199,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase { assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination); } - @SmallTest + @Test public void testParseRtmGetNeighResponse() { final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. @@ -215,7 +224,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase { assertEquals(14, messageCount); } - @SmallTest + @Test public void testCreateRtmNewNeighMessage() { final int seqNo = 2635; final int ifIndex = 14; diff --git a/tests/net/java/android/net/util/BlockingSocketReaderTest.java b/tests/net/java/android/net/util/BlockingSocketReaderTest.java index e03350f29f95..29dfa4c3d1e1 100644 --- a/tests/net/java/android/net/util/BlockingSocketReaderTest.java +++ b/tests/net/java/android/net/util/BlockingSocketReaderTest.java @@ -16,17 +16,25 @@ package android.net.util; +import static android.net.util.BlockingSocketReader.DEFAULT_RECV_BUF_SIZE; import static android.system.OsConstants.*; - +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.os.Handler; +import android.os.HandlerThread; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; import android.system.ErrnoException; import android.system.Os; import android.system.StructTimeval; -import libcore.io.IoBridge; - import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.Inet6Address; @@ -37,15 +45,21 @@ import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import junit.framework.TestCase; +import org.junit.runner.RunWith; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import libcore.io.IoBridge; /** * Tests for BlockingSocketReader. * * @hide */ -public class BlockingSocketReaderTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class BlockingSocketReaderTest { static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress(); static final StructTimeval TIMEO = StructTimeval.fromMillis(500); @@ -53,61 +67,83 @@ public class BlockingSocketReaderTest extends TestCase { protected FileDescriptor mLocalSocket; protected InetSocketAddress mLocalSockName; protected byte[] mLastRecvBuf; - protected boolean mExited; + protected boolean mStopped; + protected HandlerThread mHandlerThread; protected BlockingSocketReader mReceiver; - @Override + class UdpLoopbackReader extends BlockingSocketReader { + public UdpLoopbackReader(Handler h) { + super(h); + } + + @Override + protected FileDescriptor createFd() { + FileDescriptor s = null; + try { + s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + Os.bind(s, LOOPBACK6, 0); + mLocalSockName = (InetSocketAddress) Os.getsockname(s); + Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO); + } catch (ErrnoException|SocketException e) { + closeFd(s); + fail(); + return null; + } + + mLocalSocket = s; + return s; + } + + @Override + protected void handlePacket(byte[] recvbuf, int length) { + mLastRecvBuf = Arrays.copyOf(recvbuf, length); + mLatch.countDown(); + } + + @Override + protected void onStart() { + mStopped = false; + mLatch.countDown(); + } + + @Override + protected void onStop() { + mStopped = true; + mLatch.countDown(); + } + }; + + @Before public void setUp() { resetLatch(); mLocalSocket = null; mLocalSockName = null; mLastRecvBuf = null; - mExited = false; - - mReceiver = new BlockingSocketReader() { - @Override - protected FileDescriptor createSocket() { - FileDescriptor s = null; - try { - s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - Os.bind(s, LOOPBACK6, 0); - mLocalSockName = (InetSocketAddress) Os.getsockname(s); - Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO); - } catch (ErrnoException|SocketException e) { - closeSocket(s); - fail(); - return null; - } - - mLocalSocket = s; - return s; - } + mStopped = false; - @Override - protected void handlePacket(byte[] recvbuf, int length) { - mLastRecvBuf = Arrays.copyOf(recvbuf, length); - mLatch.countDown(); - } - - @Override - protected void onExit() { - mExited = true; - mLatch.countDown(); - } - }; + mHandlerThread = new HandlerThread(BlockingSocketReaderTest.class.getSimpleName()); + mHandlerThread.start(); } - @Override - public void tearDown() { - if (mReceiver != null) mReceiver.stop(); + @After + public void tearDown() throws Exception { + if (mReceiver != null) { + mHandlerThread.getThreadHandler().post(() -> { mReceiver.stop(); }); + waitForActivity(); + } mReceiver = null; + mHandlerThread.quit(); + mHandlerThread = null; } void resetLatch() { mLatch = new CountDownLatch(1); } void waitForActivity() throws Exception { - assertTrue(mLatch.await(500, TimeUnit.MILLISECONDS)); - resetLatch(); + try { + mLatch.await(1000, TimeUnit.MILLISECONDS); + } finally { + resetLatch(); + } } void sendPacket(byte[] contents) throws Exception { @@ -117,32 +153,57 @@ public class BlockingSocketReaderTest extends TestCase { sender.close(); } + @Test public void testBasicWorking() throws Exception { - assertTrue(mReceiver.start()); + final Handler h = mHandlerThread.getThreadHandler(); + mReceiver = new UdpLoopbackReader(h); + + h.post(() -> { mReceiver.start(); }); + waitForActivity(); assertTrue(mLocalSockName != null); assertEquals(LOOPBACK6, mLocalSockName.getAddress()); assertTrue(0 < mLocalSockName.getPort()); assertTrue(mLocalSocket != null); - assertFalse(mExited); + assertFalse(mStopped); final byte[] one = "one 1".getBytes("UTF-8"); sendPacket(one); waitForActivity(); assertEquals(1, mReceiver.numPacketsReceived()); assertTrue(Arrays.equals(one, mLastRecvBuf)); - assertFalse(mExited); + assertFalse(mStopped); final byte[] two = "two 2".getBytes("UTF-8"); sendPacket(two); waitForActivity(); assertEquals(2, mReceiver.numPacketsReceived()); assertTrue(Arrays.equals(two, mLastRecvBuf)); - assertFalse(mExited); + assertFalse(mStopped); mReceiver.stop(); waitForActivity(); assertEquals(2, mReceiver.numPacketsReceived()); assertTrue(Arrays.equals(two, mLastRecvBuf)); - assertTrue(mExited); + assertTrue(mStopped); + mReceiver = null; + } + + class NullBlockingSocketReader extends BlockingSocketReader { + public NullBlockingSocketReader(Handler h, int recvbufsize) { + super(h, recvbufsize); + } + + @Override + public FileDescriptor createFd() { return null; } + } + + @Test + public void testMinimalRecvBufSize() throws Exception { + final Handler h = mHandlerThread.getThreadHandler(); + + for (int i : new int[]{-1, 0, 1, DEFAULT_RECV_BUF_SIZE-1}) { + final BlockingSocketReader b = new NullBlockingSocketReader(h, i); + assertEquals(DEFAULT_RECV_BUF_SIZE, b.recvBufSize()); + } } } diff --git a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java index dd679bc20090..38d3d74e64cf 100644 --- a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java +++ b/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java @@ -17,18 +17,25 @@ package android.net.util; import static android.net.util.NetworkConstants.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -import libcore.util.HexEncoding; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; -import junit.framework.TestCase; +import org.junit.runner.RunWith; +import org.junit.Test; +import libcore.util.HexEncoding; /** * Tests for ConnectivityPacketSummary. * * @hide */ -public class ConnectivityPacketSummaryTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ConnectivityPacketSummaryTest { private static final byte[] MYHWADDR = { asByte(0x80), asByte(0x7a), asByte(0xbf), asByte(0x6f), asByte(0x48), asByte(0xf3) }; @@ -39,6 +46,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { return ConnectivityPacketSummary.summarize(MYHWADDR, bytes); } + @Test public void testParseICMPv6DADProbe() { final String packet = // Ethernet @@ -60,6 +68,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testParseICMPv6RS() { final String packet = // Ethernet @@ -81,6 +90,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testParseICMPv6RA() { final String packet = // Ethernet @@ -113,6 +123,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testParseICMPv6NS() { final String packet = // Ethernet @@ -135,6 +146,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testInvalidICMPv6NDLength() { final String packet = // Ethernet @@ -159,6 +171,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testParseICMPv6NA() { final String packet = // Ethernet @@ -179,6 +192,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testParseARPRequest() { final String packet = // Ethernet @@ -197,6 +211,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testParseARPReply() { final String packet = // Ethernet @@ -217,6 +232,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertEquals(expected, getSummary(packet)); } + @Test public void testParseDHCPv4Discover() { final String packet = // Ethernet @@ -262,6 +278,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertTrue(getSummary(packet).startsWith(expectedPrefix)); } + @Test public void testParseDHCPv4Offer() { final String packet = // Ethernet @@ -307,6 +324,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertTrue(getSummary(packet).startsWith(expectedPrefix)); } + @Test public void testParseDHCPv4Request() { final String packet = // Ethernet @@ -354,6 +372,7 @@ public class ConnectivityPacketSummaryTest extends TestCase { assertTrue(getSummary(packet).startsWith(expectedPrefix)); } + @Test public void testParseDHCPv4Ack() { final String packet = // Ethernet diff --git a/tests/net/java/android/net/util/IpUtilsTest.java b/tests/net/java/android/net/util/IpUtilsTest.java index c2d1608c461c..8903bf923fbf 100644 --- a/tests/net/java/android/net/util/IpUtilsTest.java +++ b/tests/net/java/android/net/util/IpUtilsTest.java @@ -16,15 +16,19 @@ package android.net.util; -import android.net.util.IpUtils; -import android.test.suitebuilder.annotation.SmallTest; +import static org.junit.Assert.assertEquals; -import java.nio.ByteBuffer; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; -import junit.framework.TestCase; +import java.nio.ByteBuffer; +import org.junit.runner.RunWith; +import org.junit.Test; -public class IpUtilsTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class IpUtilsTest { private static final int IPV4_HEADER_LENGTH = 20; private static final int IPV6_HEADER_LENGTH = 40; @@ -67,7 +71,7 @@ public class IpUtilsTest extends TestCase { // "hello") // print JavaPacketDefinition(str(packet)) - @SmallTest + @Test public void testIpv6TcpChecksum() throws Exception { // packet = (scapy.IPv6(src="2001:db8::1", dst="2001:db8::2", tc=0x80) / // scapy.TCP(sport=12345, dport=7, @@ -115,7 +119,7 @@ public class IpUtilsTest extends TestCase { assertEquals(0, IpUtils.tcpChecksum(packet, 0, IPV6_HEADER_LENGTH, transportLen)); } - @SmallTest + @Test public void testIpv4UdpChecksum() { // packet = (scapy.IP(src="192.0.2.1", dst="192.0.2.2", tos=0x40) / // scapy.UDP(sport=32012, dport=4500) / diff --git a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java index a423c2a55b3d..fb2bd79fed3a 100644 --- a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java +++ b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java @@ -24,12 +24,15 @@ import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static com.android.server.NetworkManagementSocketTagger.kernelToTag; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import android.content.res.Resources; import android.net.NetworkStats; import android.net.TrafficStats; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; -import android.test.AndroidTestCase; +import android.support.test.runner.AndroidJUnit4; import com.android.frameworks.tests.net.R; @@ -42,19 +45,23 @@ import java.io.OutputStream; import libcore.io.IoUtils; import libcore.io.Streams; +import org.junit.runner.RunWith; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + /** * Tests for {@link NetworkStatsFactory}. */ +@RunWith(AndroidJUnit4.class) @SmallTest -public class NetworkStatsFactoryTest extends AndroidTestCase { +public class NetworkStatsFactoryTest { private File mTestProc; private NetworkStatsFactory mFactory; - @Override + @Before public void setUp() throws Exception { - super.setUp(); - - mTestProc = new File(getContext().getFilesDir(), "proc"); + mTestProc = new File(InstrumentationRegistry.getContext().getFilesDir(), "proc"); if (mTestProc.exists()) { IoUtils.deleteContents(mTestProc); } @@ -62,17 +69,16 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { mFactory = new NetworkStatsFactory(mTestProc); } - @Override + @After public void tearDown() throws Exception { mFactory = null; if (mTestProc.exists()) { IoUtils.deleteContents(mTestProc); } - - super.tearDown(); } + @Test public void testNetworkStatsDetail() throws Exception { final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical); @@ -84,6 +90,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L); } + @Test public void testKernelTags() throws Exception { assertEquals(0, kernelToTag("0x0000000000000000")); assertEquals(0x32, kernelToTag("0x0000003200000000")); @@ -98,6 +105,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000")); } + @Test public void testNetworkStatsWithSet() throws Exception { final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical); assertEquals(70, stats.size()); @@ -106,6 +114,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L); } + @Test public void testNetworkStatsSingle() throws Exception { stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all")); @@ -116,6 +125,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { assertStatsEntry(stats, "test2", UID_ALL, SET_ALL, TAG_NONE, 1L, 2L, 3L, 4L); } + @Test public void testNetworkStatsXt() throws Exception { stageFile(R.raw.xt_qtaguid_iface_fmt_typical, file("net/xt_qtaguid/iface_stat_fmt")); @@ -127,6 +137,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L); } + @Test public void testDoubleClatAccounting() throws Exception { NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0"); @@ -161,6 +172,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { NetworkStatsFactory.noteStackedIface("v4-wlan0", null); } + @Test public void testDoubleClatAccounting100MBDownload() throws Exception { // Downloading 100mb from an ipv4 only destination in a foreground activity @@ -197,7 +209,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { InputStream in = null; OutputStream out = null; try { - in = getContext().getResources().openRawResource(rawId); + in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId); out = new FileOutputStream(file); Streams.copy(in, out); } finally { @@ -251,5 +263,4 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { assertEquals("unexpected txBytes", txBytes, entry.txBytes); assertEquals("unexpected txPackets", txPackets, entry.txPackets); } - } diff --git a/tests/net/java/com/android/internal/util/BitUtilsTest.java b/tests/net/java/com/android/internal/util/BitUtilsTest.java index 0ad8a21f7712..f4dc12ab8348 100644 --- a/tests/net/java/com/android/internal/util/BitUtilsTest.java +++ b/tests/net/java/com/android/internal/util/BitUtilsTest.java @@ -56,6 +56,25 @@ public class BitUtilsTest { } @Test + public void testUnsignedShortComposition() { + byte b0 = 0; + byte b1 = 1; + byte b2 = 2; + byte b10 = 10; + byte b16 = 16; + byte b128 = -128; + byte b224 = -32; + byte b255 = -1; + assertEquals(0x0000, uint16(b0, b0)); + assertEquals(0xffff, uint16(b255, b255)); + assertEquals(0x0a01, uint16(b10, b1)); + assertEquals(0x8002, uint16(b128, b2)); + assertEquals(0x01ff, uint16(b1, b255)); + assertEquals(0x80ff, uint16(b128, b255)); + assertEquals(0xe010, uint16(b224, b16)); + } + + @Test public void testUnsignedIntWideningConversions() { assertEquals(0, uint32(0)); assertEquals(1, uint32(1)); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index a8147380386f..c2cb66d5e60a 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -19,13 +19,20 @@ package com.android.server; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; +import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; import static android.net.ConnectivityManager.TYPE_NONE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.NetworkCapabilities.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import static com.android.internal.util.TestUtils.waitForIdleHandler; - import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; @@ -85,9 +92,10 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; -import android.test.AndroidTestCase; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; import android.test.mock.MockContentResolver; -import android.test.suitebuilder.annotation.SmallTest; import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; @@ -103,7 +111,11 @@ import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult; import com.android.server.net.NetworkPinner; import com.android.server.net.NetworkPolicyManagerInternal; +import org.junit.After; +import org.junit.Before; import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @@ -119,16 +131,18 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BooleanSupplier; import java.util.function.Predicate; + /** * Tests for {@link ConnectivityService}. * * Build, install and run with: * runtest frameworks-net -c com.android.server.ConnectivityServiceTest */ -public class ConnectivityServiceTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ConnectivityServiceTest { private static final String TAG = "ConnectivityServiceTest"; private static final int TIMEOUT_MS = 500; @@ -140,6 +154,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { private MockNetworkAgent mWiFiNetworkAgent; private MockNetworkAgent mCellNetworkAgent; private MockNetworkAgent mEthernetNetworkAgent; + private Context mContext; // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods // do not go through ConnectivityService but talk to netd directly, so they don't automatically @@ -241,7 +256,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { waitForIdle(TIMEOUT_MS); } - @SmallTest + @Test public void testWaitForIdle() { final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. @@ -742,7 +757,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Don't overlap test NetIDs with real NetIDs as binding sockets to real networks // can have odd side-effects, like network validations succeeding. - final Network[] networks = ConnectivityManager.from(getContext()).getAllNetworks(); + Context context = InstrumentationRegistry.getContext(); + final Network[] networks = ConnectivityManager.from(context).getAllNetworks(); boolean overlaps = false; for (Network network : networks) { if (netId == network.netId) { @@ -782,6 +798,13 @@ public class ConnectivityServiceTest extends AndroidTestCase { return new FakeWakeupMessage(context, handler, cmdName, cmd, 0, 0, obj); } + @Override + public boolean hasService(String name) { + // Currenty, the only relevant service that ConnectivityService checks for is + // ETHERNET_SERVICE. + return Context.ETHERNET_SERVICE.equals(name); + } + public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() { return mLastCreatedNetworkMonitor; } @@ -806,9 +829,9 @@ public class ConnectivityServiceTest extends AndroidTestCase { fail("ConditionVariable was blocked for more than " + TIMEOUT_MS + "ms"); } - @Override + @Before public void setUp() throws Exception { - super.setUp(); + mContext = InstrumentationRegistry.getContext(); // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not. // http://b/25897652 . @@ -816,7 +839,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { Looper.prepare(); } - mServiceContext = new MockContext(getContext()); + mServiceContext = new MockContext(InstrumentationRegistry.getContext()); LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); LocalServices.addService( NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class)); @@ -827,7 +850,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mock(IpConnectivityLog.class)); mService.systemReady(); - mCm = new WrappedConnectivityManager(getContext(), mService); + mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); mCm.bindProcessToNetwork(null); // Ensure that the default setting for Captive Portals is used for most tests @@ -835,6 +858,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { setMobileDataAlwaysOn(false); } + @After public void tearDown() throws Exception { setMobileDataAlwaysOn(false); if (mCellNetworkAgent != null) { @@ -849,7 +873,6 @@ public class ConnectivityServiceTest extends AndroidTestCase { mEthernetNetworkAgent.disconnect(); mEthernetNetworkAgent = null; } - super.tearDown(); } private static int transportToLegacyType(int transport) { @@ -923,15 +946,23 @@ public class ConnectivityServiceTest extends AndroidTestCase { return cv; } + @Test public void testNetworkTypes() { // Ensure that our mocks for the networkAttributes config variable work as expected. If they // don't, then tests that depend on CONNECTIVITY_ACTION broadcasts for these network types // will fail. Failing here is much easier to debug. assertTrue(mCm.isNetworkSupported(TYPE_WIFI)); assertTrue(mCm.isNetworkSupported(TYPE_MOBILE)); + assertTrue(mCm.isNetworkSupported(TYPE_MOBILE_MMS)); + assertFalse(mCm.isNetworkSupported(TYPE_MOBILE_FOTA)); + + // Check that TYPE_ETHERNET is supported. Unlike the asserts above, which only validate our + // mocks, this assert exercises the ConnectivityService code path that ensures that + // TYPE_ETHERNET is supported if the ethernet service is running. + assertTrue(mCm.isNetworkSupported(TYPE_ETHERNET)); } - @SmallTest + @Test public void testLingering() throws Exception { verifyNoNetwork(); mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); @@ -972,7 +1003,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyNoNetwork(); } - @SmallTest + @Test public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { // Test bringing up unvalidated WiFi mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); @@ -1007,7 +1038,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyNoNetwork(); } - @SmallTest + @Test public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { // Test bringing up unvalidated cellular. mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); @@ -1033,7 +1064,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyNoNetwork(); } - @SmallTest + @Test public void testUnlingeringDoesNotValidate() throws Exception { // Test bringing up unvalidated WiFi. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); @@ -1061,7 +1092,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { NET_CAPABILITY_VALIDATED)); } - @SmallTest + @Test public void testCellularOutscoresWeakWifi() throws Exception { // Test bringing up validated cellular. mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); @@ -1087,7 +1118,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyActiveNetwork(TRANSPORT_WIFI); } - @SmallTest + @Test public void testReapingNetwork() throws Exception { // Test bringing up WiFi without NET_CAPABILITY_INTERNET. // Expect it to be torn down immediately because it satisfies no requests. @@ -1120,7 +1151,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { waitFor(cv); } - @SmallTest + @Test public void testCellularFallback() throws Exception { // Test bringing up validated cellular. mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); @@ -1158,7 +1189,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyActiveNetwork(TRANSPORT_WIFI); } - @SmallTest + @Test public void testWiFiFallback() throws Exception { // Test bringing up unvalidated WiFi. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); @@ -1372,7 +1403,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } - @SmallTest + @Test public void testStateChangeNetworkCallbacks() throws Exception { final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); @@ -1462,7 +1493,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); } - @SmallTest + @Test public void testMultipleLingering() { NetworkRequest request = new NetworkRequest.Builder() .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED) @@ -1690,7 +1721,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.unregisterNetworkCallback(trackDefaultCallback); } - @SmallTest + @Test public void testExplicitlySelected() { NetworkRequest request = new NetworkRequest.Builder() .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) @@ -1857,7 +1888,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { handlerThread.quit(); } - @SmallTest + @Test public void testNetworkFactoryRequests() throws Exception { tryNetworkFactoryRequests(NET_CAPABILITY_MMS); tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); @@ -1877,7 +1908,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. } - @SmallTest + @Test public void testNoMutableNetworkRequests() throws Exception { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0); NetworkRequest request1 = new NetworkRequest.Builder() @@ -1894,7 +1925,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertException(() -> { mCm.requestNetwork(request2, pendingIntent); }, expected); } - @SmallTest + @Test public void testMMSonWiFi() throws Exception { // Test bringing up cellular without MMS NetworkRequest gets reaped mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); @@ -1933,7 +1964,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyActiveNetwork(TRANSPORT_WIFI); } - @SmallTest + @Test public void testMMSonCell() throws Exception { // Test bringing up cellular without MMS mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); @@ -1962,7 +1993,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyActiveNetwork(TRANSPORT_CELLULAR); } - @SmallTest + @Test public void testCaptivePortal() { final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() @@ -2013,7 +2044,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); } - @SmallTest + @Test public void testCaptivePortalApp() { final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() @@ -2059,7 +2090,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.unregisterNetworkCallback(captivePortalCallback); } - @SmallTest + @Test public void testAvoidOrIgnoreCaptivePortals() { final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() @@ -2104,7 +2135,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); } - @SmallTest + @Test public void testNetworkSpecifier() { NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); @@ -2165,7 +2196,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cFoo, cBar); } - @SmallTest + @Test public void testInvalidNetworkSpecifier() { try { NetworkRequest.Builder builder = new NetworkRequest.Builder(); @@ -2226,7 +2257,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } - @SmallTest + @Test public void testNetworkSpecifierUidSpoofSecurityException() { class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable { @Override @@ -2260,7 +2291,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } - @SmallTest + @Test public void testRegisterDefaultNetworkCallback() throws Exception { final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); mCm.registerDefaultNetworkCallback(defaultNetworkCallback); @@ -2309,7 +2340,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent); } - @SmallTest + @Test public void testAdditionalStateCallbacks() throws Exception { // File a network request for mobile. final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); @@ -2370,7 +2401,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { return nc.hasCapability(NET_CAPABILITY_FOREGROUND); } - @SmallTest + @Test public void testBackgroundNetworks() throws Exception { // Create a background request. We can't do this ourselves because ConnectivityService // doesn't have an API for it. So just turn on mobile data always on. @@ -2539,7 +2570,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { return false; } - @SmallTest + @Test public void testMobileDataAlwaysOn() throws Exception { final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback(); final NetworkRequest cellRequest = new NetworkRequest.Builder() @@ -2604,7 +2635,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { handlerThread.quit(); } - @SmallTest + @Test public void testAvoidBadWifiSetting() throws Exception { final ContentResolver cr = mServiceContext.getContentResolver(); final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker(); @@ -2642,7 +2673,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertTrue(tracker.shouldNotifyWifiUnvalidated()); } - @SmallTest + @Test public void testAvoidBadWifi() throws Exception { final ContentResolver cr = mServiceContext.getContentResolver(); final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker(); @@ -2769,7 +2800,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.unregisterNetworkCallback(defaultCallback); } - @SmallTest + @Test public void testMeteredMultipathPreferenceSetting() throws Exception { final ContentResolver cr = mServiceContext.getContentResolver(); final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker(); @@ -2793,7 +2824,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { * Validate that a satisfied network request does not trigger onUnavailable() once the * time-out period expires. */ - @SmallTest + @Test public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() { NetworkRequest nr = new NetworkRequest.Builder().addTransportType( NetworkCapabilities.TRANSPORT_WIFI).build(); @@ -2813,7 +2844,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { * Validate that a satisfied network request followed by a disconnected (lost) network does * not trigger onUnavailable() once the time-out period expires. */ - @SmallTest + @Test public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() { NetworkRequest nr = new NetworkRequest.Builder().addTransportType( NetworkCapabilities.TRANSPORT_WIFI).build(); @@ -2837,7 +2868,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { * callback is called when time-out expires. Then validate that if network request is * (somehow) satisfied - the callback isn't called later. */ - @SmallTest + @Test public void testTimedoutNetworkRequest() { NetworkRequest nr = new NetworkRequest.Builder().addTransportType( NetworkCapabilities.TRANSPORT_WIFI).build(); @@ -2858,7 +2889,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { * Validate that when a network request is unregistered (cancelled), no posterior event can * trigger the callback. */ - @SmallTest + @Test public void testNoCallbackAfterUnregisteredNetworkRequest() { NetworkRequest nr = new NetworkRequest.Builder().addTransportType( NetworkCapabilities.TRANSPORT_WIFI).build(); @@ -2966,7 +2997,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { return mWiFiNetworkAgent.getNetwork(); } - @SmallTest + @Test public void testPacketKeepalives() throws Exception { InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); @@ -3090,7 +3121,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { callback3.expectStopped(); } - @SmallTest + @Test public void testGetCaptivePortalServerUrl() throws Exception { String url = mCm.getCaptivePortalServerUrl(); assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); @@ -3135,7 +3166,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); } - @SmallTest + @Test public void testNetworkPinner() { NetworkRequest wifiRequest = new NetworkRequest.Builder() .addTransportType(TRANSPORT_WIFI) @@ -3195,69 +3226,69 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertPinnedToWifiWithCellDefault(); } - @SmallTest - public void testNetworkRequestMaximum() { + @Test + public void testNetworkCallbackMaximum() { final int MAX_REQUESTS = 100; - // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. + final int CALLBACKS = 90; + final int INTENTS = 10; + assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS); + NetworkRequest networkRequest = new NetworkRequest.Builder().build(); - ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>(); - try { - for (int i = 0; i < MAX_REQUESTS; i++) { - NetworkCallback networkCallback = new NetworkCallback(); - mCm.requestNetwork(networkRequest, networkCallback); - networkCallbacks.add(networkCallback); - } - fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception"); - } catch (TooManyRequestsException expected) {} - for (NetworkCallback networkCallback : networkCallbacks) { - mCm.unregisterNetworkCallback(networkCallback); + ArrayList<Object> registered = new ArrayList<>(); + + int j = 0; + while (j++ < CALLBACKS / 2) { + NetworkCallback cb = new NetworkCallback(); + mCm.requestNetwork(networkRequest, cb); + registered.add(cb); + } + while (j++ < CALLBACKS) { + NetworkCallback cb = new NetworkCallback(); + mCm.registerNetworkCallback(networkRequest, cb); + registered.add(cb); + } + j = 0; + while (j++ < INTENTS / 2) { + PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + j), 0); + mCm.requestNetwork(networkRequest, pi); + registered.add(pi); + } + while (j++ < INTENTS) { + PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + j), 0); + mCm.registerNetworkCallback(networkRequest, pi); + registered.add(pi); } - networkCallbacks.clear(); + // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added. try { - for (int i = 0; i < MAX_REQUESTS; i++) { - NetworkCallback networkCallback = new NetworkCallback(); - mCm.registerNetworkCallback(networkRequest, networkCallback); - networkCallbacks.add(networkCallback); - } - fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception"); + mCm.requestNetwork(networkRequest, new NetworkCallback()); + fail("Registering " + MAX_REQUESTS + " network requests did not throw exception"); } catch (TooManyRequestsException expected) {} - for (NetworkCallback networkCallback : networkCallbacks) { - mCm.unregisterNetworkCallback(networkCallback); - } - networkCallbacks.clear(); - - ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>(); try { - for (int i = 0; i < MAX_REQUESTS + 1; i++) { - PendingIntent pendingIntent = - PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0); - mCm.requestNetwork(networkRequest, pendingIntent); - pendingIntents.add(pendingIntent); - } - fail("Registering " + MAX_REQUESTS + - " PendingIntent NetworkRequests did not throw exception"); + mCm.registerNetworkCallback(networkRequest, new NetworkCallback()); + fail("Registering " + MAX_REQUESTS + " network callbacks did not throw exception"); } catch (TooManyRequestsException expected) {} - for (PendingIntent pendingIntent : pendingIntents) { - mCm.unregisterNetworkCallback(pendingIntent); - } - pendingIntents.clear(); - try { - for (int i = 0; i < MAX_REQUESTS + 1; i++) { - PendingIntent pendingIntent = - PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0); - mCm.registerNetworkCallback(networkRequest, pendingIntent); - pendingIntents.add(pendingIntent); - } - fail("Registering " + MAX_REQUESTS + - " PendingIntent NetworkCallbacks did not throw exception"); + mCm.requestNetwork(networkRequest, + PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0)); + fail("Registering " + MAX_REQUESTS + " PendingIntent requests did not throw exception"); } catch (TooManyRequestsException expected) {} - for (PendingIntent pendingIntent : pendingIntents) { - mCm.unregisterNetworkCallback(pendingIntent); + try { + mCm.registerNetworkCallback(networkRequest, + PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0)); + fail("Registering " + MAX_REQUESTS + + " PendingIntent callbacks did not throw exception"); + } catch (TooManyRequestsException expected) {} + + for (Object o : registered) { + if (o instanceof NetworkCallback) { + mCm.unregisterNetworkCallback((NetworkCallback)o); + } + if (o instanceof PendingIntent) { + mCm.unregisterNetworkCallback((PendingIntent)o); + } } - pendingIntents.clear(); - waitForIdle(5000); + waitForIdle(); // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. for (int i = 0; i < MAX_REQUESTS; i++) { @@ -3266,28 +3297,31 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.unregisterNetworkCallback(networkCallback); } waitForIdle(); + for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.registerNetworkCallback(networkRequest, networkCallback); mCm.unregisterNetworkCallback(networkCallback); } waitForIdle(); + for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = - PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0); + PendingIntent.getBroadcast(mContext, 0, new Intent("e" + i), 0); mCm.requestNetwork(networkRequest, pendingIntent); mCm.unregisterNetworkCallback(pendingIntent); } waitForIdle(); + for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = - PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0); + PendingIntent.getBroadcast(mContext, 0, new Intent("f" + i), 0); mCm.registerNetworkCallback(networkRequest, pendingIntent); mCm.unregisterNetworkCallback(pendingIntent); } } - @SmallTest + @Test public void testNetworkInfoOfTypeNone() { ConditionVariable broadcastCV = waitForConnectivityBroadcasts(1); @@ -3327,7 +3361,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } - @SmallTest + @Test public void testDeprecatedAndUnsupportedOperations() throws Exception { final int TYPE_NONE = ConnectivityManager.TYPE_NONE; assertNull(mCm.getNetworkInfo(TYPE_NONE)); @@ -3348,7 +3382,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertException(() -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); }, unsupported); } - @SmallTest + @Test public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() { final NetworkRequest networkRequest = new NetworkRequest.Builder() .addTransportType(TRANSPORT_WIFI).build(); diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java new file mode 100644 index 000000000000..9057a108dec4 --- /dev/null +++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.net.INetd; +import android.net.IpSecAlgorithm; +import android.net.IpSecConfig; +import android.net.IpSecManager; +import android.net.IpSecSpiResponse; +import android.net.IpSecTransform; +import android.net.IpSecTransformResponse; +import android.net.NetworkUtils; +import android.os.Binder; +import android.os.ParcelFileDescriptor; +import android.support.test.filters.SmallTest; +import android.system.OsConstants; + +import java.net.Socket; +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +/** Unit tests for {@link IpSecService}. */ +@SmallTest +@RunWith(Parameterized.class) +public class IpSecServiceParameterizedTest { + + private static final int DROID_SPI = 0xD1201D; + private static final int DROID_SPI2 = DROID_SPI + 1; + + private final String mRemoteAddr; + + @Parameterized.Parameters + public static Collection ipSecConfigs() { + return Arrays.asList(new Object[][] {{"8.8.4.4"}, {"2601::10"}}); + } + + private static final byte[] CRYPT_KEY = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F + }; + private static final byte[] AUTH_KEY = { + 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F + }; + + Context mMockContext; + INetd mMockNetd; + IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; + IpSecService mIpSecService; + + public IpSecServiceParameterizedTest(String remoteAddr) { + mRemoteAddr = remoteAddr; + } + + @Before + public void setUp() throws Exception { + mMockContext = mock(Context.class); + mMockNetd = mock(INetd.class); + mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class); + mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig); + + // Injecting mock netd + when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd); + } + + @Test + public void testIpSecServiceReserveSpi() throws Exception { + when(mMockNetd.ipSecAllocateSpi( + anyInt(), + eq(IpSecTransform.DIRECTION_OUT), + anyString(), + eq(mRemoteAddr), + eq(DROID_SPI))) + .thenReturn(DROID_SPI); + + IpSecSpiResponse spiResp = + mIpSecService.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, mRemoteAddr, DROID_SPI, new Binder()); + assertEquals(IpSecManager.Status.OK, spiResp.status); + assertEquals(DROID_SPI, spiResp.spi); + } + + @Test + public void testReleaseSecurityParameterIndex() throws Exception { + when(mMockNetd.ipSecAllocateSpi( + anyInt(), + eq(IpSecTransform.DIRECTION_OUT), + anyString(), + eq(mRemoteAddr), + eq(DROID_SPI))) + .thenReturn(DROID_SPI); + + IpSecSpiResponse spiResp = + mIpSecService.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, mRemoteAddr, DROID_SPI, new Binder()); + + mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId); + + verify(mMockNetd) + .ipSecDeleteSecurityAssociation( + eq(spiResp.resourceId), anyInt(), anyString(), anyString(), eq(DROID_SPI)); + } + + IpSecConfig buildIpSecConfig() throws Exception { + IpSecManager ipSecManager = new IpSecManager(mIpSecService); + + // Mocking the netd to allocate SPI + when(mMockNetd.ipSecAllocateSpi(anyInt(), anyInt(), anyString(), anyString(), anyInt())) + .thenReturn(DROID_SPI) + .thenReturn(DROID_SPI2); + + IpSecAlgorithm encryptAlgo = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); + IpSecAlgorithm authAlgo = + new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 8); + + /** Allocate and add SPI records in the IpSecService through IpSecManager interface. */ + IpSecManager.SecurityParameterIndex outSpi = + ipSecManager.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, + NetworkUtils.numericToInetAddress(mRemoteAddr)); + IpSecManager.SecurityParameterIndex inSpi = + ipSecManager.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_IN, + NetworkUtils.numericToInetAddress(mRemoteAddr)); + + IpSecConfig config = new IpSecConfig(); + config.setSpiResourceId(IpSecTransform.DIRECTION_IN, inSpi.getResourceId()); + config.setSpiResourceId(IpSecTransform.DIRECTION_OUT, outSpi.getResourceId()); + config.setEncryption(IpSecTransform.DIRECTION_OUT, encryptAlgo); + config.setAuthentication(IpSecTransform.DIRECTION_OUT, authAlgo); + config.setEncryption(IpSecTransform.DIRECTION_IN, encryptAlgo); + config.setAuthentication(IpSecTransform.DIRECTION_IN, authAlgo); + config.setRemoteAddress(mRemoteAddr); + return config; + } + + @Test + public void testCreateTransportModeTransform() throws Exception { + IpSecConfig ipSecConfig = buildIpSecConfig(); + + IpSecTransformResponse createTransformResp = + mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); + assertEquals(IpSecManager.Status.OK, createTransformResp.status); + + verify(mMockNetd) + .ipSecAddSecurityAssociation( + eq(createTransformResp.resourceId), + anyInt(), + eq(IpSecTransform.DIRECTION_OUT), + anyString(), + anyString(), + anyLong(), + eq(DROID_SPI), + eq(IpSecAlgorithm.AUTH_HMAC_SHA256), + eq(AUTH_KEY), + anyInt(), + eq(IpSecAlgorithm.CRYPT_AES_CBC), + eq(CRYPT_KEY), + anyInt(), + anyInt(), + anyInt(), + anyInt()); + verify(mMockNetd) + .ipSecAddSecurityAssociation( + eq(createTransformResp.resourceId), + anyInt(), + eq(IpSecTransform.DIRECTION_IN), + anyString(), + anyString(), + anyLong(), + eq(DROID_SPI2), + eq(IpSecAlgorithm.AUTH_HMAC_SHA256), + eq(AUTH_KEY), + anyInt(), + eq(IpSecAlgorithm.CRYPT_AES_CBC), + eq(CRYPT_KEY), + anyInt(), + anyInt(), + anyInt(), + anyInt()); + } + + @Test + public void testDeleteTransportModeTransform() throws Exception { + IpSecConfig ipSecConfig = buildIpSecConfig(); + + IpSecTransformResponse createTransformResp = + mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); + mIpSecService.deleteTransportModeTransform(createTransformResp.resourceId); + + verify(mMockNetd) + .ipSecDeleteSecurityAssociation( + eq(createTransformResp.resourceId), + eq(IpSecTransform.DIRECTION_OUT), + anyString(), + anyString(), + eq(DROID_SPI)); + verify(mMockNetd) + .ipSecDeleteSecurityAssociation( + eq(createTransformResp.resourceId), + eq(IpSecTransform.DIRECTION_IN), + anyString(), + anyString(), + eq(DROID_SPI2)); + } + + @Test + public void testApplyTransportModeTransform() throws Exception { + IpSecConfig ipSecConfig = buildIpSecConfig(); + + IpSecTransformResponse createTransformResp = + mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); + ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket()); + + int resourceId = createTransformResp.resourceId; + mIpSecService.applyTransportModeTransform(pfd, resourceId); + + verify(mMockNetd) + .ipSecApplyTransportModeTransform( + eq(pfd.getFileDescriptor()), + eq(resourceId), + eq(IpSecTransform.DIRECTION_OUT), + anyString(), + anyString(), + eq(DROID_SPI)); + verify(mMockNetd) + .ipSecApplyTransportModeTransform( + eq(pfd.getFileDescriptor()), + eq(resourceId), + eq(IpSecTransform.DIRECTION_IN), + anyString(), + anyString(), + eq(DROID_SPI2)); + } + + @Test + public void testRemoveTransportModeTransform() throws Exception { + ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket()); + mIpSecService.removeTransportModeTransform(pfd, 1); + + verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor()); + } +} diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java index 23fee286b8e7..83ee361aa2e3 100644 --- a/tests/net/java/com/android/server/IpSecServiceTest.java +++ b/tests/net/java/com/android/server/IpSecServiceTest.java @@ -23,52 +23,41 @@ import static android.system.OsConstants.SOCK_DGRAM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.net.INetd; -import android.net.IpSecAlgorithm; -import android.net.IpSecConfig; import android.net.IpSecManager; import android.net.IpSecSpiResponse; import android.net.IpSecTransform; -import android.net.IpSecTransformResponse; import android.net.IpSecUdpEncapResponse; import android.os.Binder; import android.os.ParcelFileDescriptor; import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; import android.system.ErrnoException; import android.system.Os; + import java.io.FileDescriptor; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; /** Unit tests for {@link IpSecService}. */ @SmallTest -@RunWith(JUnit4.class) +@RunWith(AndroidJUnit4.class) public class IpSecServiceTest { private static final int DROID_SPI = 0xD1201D; - private static final int DROID_SPI2 = DROID_SPI + 1; private static final int TEST_UDP_ENCAP_INVALID_PORT = 100; private static final int TEST_UDP_ENCAP_PORT_OUT_RANGE = 100000; - private static final int TEST_UDP_ENCAP_PORT = 34567; - - private static final String IPV4_LOOPBACK = "127.0.0.1"; - private static final String IPV4_ADDR = "192.168.0.2"; private static final InetAddress INADDR_ANY; @@ -80,21 +69,6 @@ public class IpSecServiceTest { } } - private static final int[] DIRECTIONS = - new int[] {IpSecTransform.DIRECTION_OUT, IpSecTransform.DIRECTION_IN}; - private static final byte[] CRYPT_KEY = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F - }; - private static final byte[] AUTH_KEY = { - 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, - 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F - }; - Context mMockContext; INetd mMockNetd; IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; @@ -118,44 +92,6 @@ public class IpSecServiceTest { } @Test - public void testIpSecServiceReserveSpi() throws Exception { - when(mMockNetd.ipSecAllocateSpi( - anyInt(), - eq(IpSecTransform.DIRECTION_OUT), - anyString(), - eq(IPV4_LOOPBACK), - eq(DROID_SPI))) - .thenReturn(DROID_SPI); - - IpSecSpiResponse spiResp = - mIpSecService.reserveSecurityParameterIndex( - IpSecTransform.DIRECTION_OUT, IPV4_LOOPBACK, DROID_SPI, new Binder()); - assertEquals(IpSecManager.Status.OK, spiResp.status); - assertEquals(DROID_SPI, spiResp.spi); - } - - @Test - public void testReleaseSecurityParameterIndex() throws Exception { - when(mMockNetd.ipSecAllocateSpi( - anyInt(), - eq(IpSecTransform.DIRECTION_OUT), - anyString(), - eq(IPV4_LOOPBACK), - eq(DROID_SPI))) - .thenReturn(DROID_SPI); - - IpSecSpiResponse spiResp = - mIpSecService.reserveSecurityParameterIndex( - IpSecTransform.DIRECTION_OUT, IPV4_LOOPBACK, DROID_SPI, new Binder()); - - mIpSecService.releaseSecurityParameterIndex(spiResp.resourceId); - - verify(mMockNetd) - .ipSecDeleteSecurityAssociation( - eq(spiResp.resourceId), anyInt(), anyString(), anyString(), eq(DROID_SPI)); - } - - @Test public void testReleaseInvalidSecurityParameterIndex() throws Exception { try { mIpSecService.releaseSecurityParameterIndex(1); @@ -285,108 +221,6 @@ public class IpSecServiceTest { } } - IpSecConfig buildIpSecConfig() throws Exception { - IpSecManager ipSecManager = new IpSecManager(mIpSecService); - - // Mocking the netd to allocate SPI - when(mMockNetd.ipSecAllocateSpi(anyInt(), anyInt(), anyString(), anyString(), anyInt())) - .thenReturn(DROID_SPI) - .thenReturn(DROID_SPI2); - - IpSecAlgorithm encryptAlgo = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); - IpSecAlgorithm authAlgo = - new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 8); - - InetAddress localAddr = InetAddress.getByAddress(new byte[] {127, 0, 0, 1}); - - /** Allocate and add SPI records in the IpSecService through IpSecManager interface. */ - IpSecManager.SecurityParameterIndex outSpi = - ipSecManager.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_OUT, localAddr); - IpSecManager.SecurityParameterIndex inSpi = - ipSecManager.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_IN, localAddr); - - IpSecConfig ipSecConfig = - new IpSecTransform.Builder(mMockContext) - .setSpi(IpSecTransform.DIRECTION_OUT, outSpi) - .setSpi(IpSecTransform.DIRECTION_IN, inSpi) - .setEncryption(IpSecTransform.DIRECTION_OUT, encryptAlgo) - .setAuthentication(IpSecTransform.DIRECTION_OUT, authAlgo) - .setEncryption(IpSecTransform.DIRECTION_IN, encryptAlgo) - .setAuthentication(IpSecTransform.DIRECTION_IN, authAlgo) - .getIpSecConfig(); - return ipSecConfig; - } - - @Test - public void testCreateTransportModeTransform() throws Exception { - IpSecConfig ipSecConfig = buildIpSecConfig(); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); - assertEquals(IpSecManager.Status.OK, createTransformResp.status); - - verify(mMockNetd) - .ipSecAddSecurityAssociation( - eq(createTransformResp.resourceId), - anyInt(), - eq(IpSecTransform.DIRECTION_OUT), - anyString(), - anyString(), - anyLong(), - eq(DROID_SPI), - eq(IpSecAlgorithm.AUTH_HMAC_SHA256), - eq(AUTH_KEY), - anyInt(), - eq(IpSecAlgorithm.CRYPT_AES_CBC), - eq(CRYPT_KEY), - anyInt(), - anyInt(), - anyInt(), - anyInt()); - verify(mMockNetd) - .ipSecAddSecurityAssociation( - eq(createTransformResp.resourceId), - anyInt(), - eq(IpSecTransform.DIRECTION_IN), - anyString(), - anyString(), - anyLong(), - eq(DROID_SPI2), - eq(IpSecAlgorithm.AUTH_HMAC_SHA256), - eq(AUTH_KEY), - anyInt(), - eq(IpSecAlgorithm.CRYPT_AES_CBC), - eq(CRYPT_KEY), - anyInt(), - anyInt(), - anyInt(), - anyInt()); - } - - @Test - public void testDeleteTransportModeTransform() throws Exception { - IpSecConfig ipSecConfig = buildIpSecConfig(); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); - mIpSecService.deleteTransportModeTransform(createTransformResp.resourceId); - - verify(mMockNetd) - .ipSecDeleteSecurityAssociation( - eq(createTransformResp.resourceId), - eq(IpSecTransform.DIRECTION_OUT), - anyString(), - anyString(), - eq(DROID_SPI)); - verify(mMockNetd) - .ipSecDeleteSecurityAssociation( - eq(createTransformResp.resourceId), - eq(IpSecTransform.DIRECTION_IN), - anyString(), - anyString(), - eq(DROID_SPI2)); - } - @Test public void testDeleteInvalidTransportModeTransform() throws Exception { try { @@ -397,39 +231,31 @@ public class IpSecServiceTest { } @Test - public void testApplyTransportModeTransform() throws Exception { - IpSecConfig ipSecConfig = buildIpSecConfig(); - - IpSecTransformResponse createTransformResp = - mIpSecService.createTransportModeTransform(ipSecConfig, new Binder()); - ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket()); - - int resourceId = createTransformResp.resourceId; - mIpSecService.applyTransportModeTransform(pfd, resourceId); - - verify(mMockNetd) - .ipSecApplyTransportModeTransform( - eq(pfd.getFileDescriptor()), - eq(resourceId), - eq(IpSecTransform.DIRECTION_OUT), - anyString(), - anyString(), - eq(DROID_SPI)); - verify(mMockNetd) - .ipSecApplyTransportModeTransform( - eq(pfd.getFileDescriptor()), - eq(resourceId), - eq(IpSecTransform.DIRECTION_IN), - anyString(), - anyString(), - eq(DROID_SPI2)); - } - - @Test public void testRemoveTransportModeTransform() throws Exception { ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket()); mIpSecService.removeTransportModeTransform(pfd, 1); verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor()); } + + @Test + public void testValidateIpAddresses() throws Exception { + String[] invalidAddresses = + new String[] {"www.google.com", "::", "2001::/64", "0.0.0.0", ""}; + for (String address : invalidAddresses) { + try { + IpSecSpiResponse spiResp = + mIpSecService.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, address, DROID_SPI, new Binder()); + fail("Invalid address was passed through IpSecService validation: " + address); + } catch (IllegalArgumentException e) { + } catch (Exception e) { + fail( + "Invalid InetAddress was not caught in validation: " + + address + + ", Exception: " + + e); + } + } + } } diff --git a/tests/net/java/com/android/server/NsdServiceTest.java b/tests/net/java/com/android/server/NsdServiceTest.java index 2e49c98ca9b6..b88c784bed5d 100644 --- a/tests/net/java/com/android/server/NsdServiceTest.java +++ b/tests/net/java/com/android/server/NsdServiceTest.java @@ -77,7 +77,10 @@ public class NsdServiceTest { @After public void tearDown() throws Exception { - mThread.quit(); + if (mThread != null) { + mThread.quit(); + mThread = null; + } } @Test diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 77956be66c9e..354cf2f2239e 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -16,6 +16,18 @@ package com.android.server.connectivity; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.reset; + import android.app.PendingIntent; import android.content.Context; import android.content.res.Resources; @@ -24,27 +36,24 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkMisc; -import android.test.suitebuilder.annotation.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.text.format.DateUtils; + import com.android.internal.R; import com.android.server.ConnectivityService; import com.android.server.connectivity.NetworkNotificationManager; import com.android.server.connectivity.NetworkNotificationManager.NotificationType; -import junit.framework.TestCase; + +import org.junit.runner.RunWith; +import org.junit.Before; +import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.reset; - -public class LingerMonitorTest extends TestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class LingerMonitorTest { static final String CELLULAR = "CELLULAR"; static final String WIFI = "WIFI"; @@ -62,6 +71,7 @@ public class LingerMonitorTest extends TestCase { @Mock NetworkNotificationManager mNotifier; @Mock Resources mResources; + @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mCtx.getResources()).thenReturn(mResources); @@ -71,7 +81,7 @@ public class LingerMonitorTest extends TestCase { mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT); } - @SmallTest + @Test public void testTransitions() { setNotificationSwitch(transition(WIFI, CELLULAR)); NetworkAgentInfo nai1 = wifiNai(100); @@ -81,7 +91,7 @@ public class LingerMonitorTest extends TestCase { assertFalse(mMonitor.isNotificationEnabled(nai2, nai1)); } - @SmallTest + @Test public void testNotificationOnLinger() { setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); @@ -92,7 +102,7 @@ public class LingerMonitorTest extends TestCase { verifyNotification(from, to); } - @SmallTest + @Test public void testToastOnLinger() { setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); @@ -103,7 +113,7 @@ public class LingerMonitorTest extends TestCase { verifyToast(from, to); } - @SmallTest + @Test public void testNotificationClearedAfterDisconnect() { setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); @@ -117,7 +127,7 @@ public class LingerMonitorTest extends TestCase { verify(mNotifier, times(1)).clearNotification(100); } - @SmallTest + @Test public void testNotificationClearedAfterSwitchingBack() { setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); @@ -131,7 +141,7 @@ public class LingerMonitorTest extends TestCase { verify(mNotifier, times(1)).clearNotification(100); } - @SmallTest + @Test public void testUniqueToast() { setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); @@ -149,7 +159,7 @@ public class LingerMonitorTest extends TestCase { verifyNoNotifications(); } - @SmallTest + @Test public void testMultipleNotifications() { setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); @@ -168,7 +178,7 @@ public class LingerMonitorTest extends TestCase { verifyNotification(wifi2, cell); } - @SmallTest + @Test public void testRateLimiting() throws InterruptedException { mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT); @@ -194,7 +204,7 @@ public class LingerMonitorTest extends TestCase { verifyNoNotifications(); } - @SmallTest + @Test public void testDailyLimiting() throws InterruptedException { mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT); @@ -221,7 +231,7 @@ public class LingerMonitorTest extends TestCase { verifyNoNotifications(); } - @SmallTest + @Test public void testUniqueNotification() { setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); @@ -238,7 +248,7 @@ public class LingerMonitorTest extends TestCase { verifyNotification(from, to); } - @SmallTest + @Test public void testIgnoreNeverValidatedNetworks() { setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationSwitch(transition(WIFI, CELLULAR)); @@ -250,7 +260,7 @@ public class LingerMonitorTest extends TestCase { verifyNoNotifications(); } - @SmallTest + @Test public void testIgnoreCurrentlyValidatedNetworks() { setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationSwitch(transition(WIFI, CELLULAR)); @@ -262,7 +272,7 @@ public class LingerMonitorTest extends TestCase { verifyNoNotifications(); } - @SmallTest + @Test public void testNoNotificationType() { setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationSwitch(); @@ -273,7 +283,7 @@ public class LingerMonitorTest extends TestCase { verifyNoNotifications(); } - @SmallTest + @Test public void testNoTransitionToNotify() { setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE); setNotificationSwitch(transition(WIFI, CELLULAR)); @@ -284,7 +294,7 @@ public class LingerMonitorTest extends TestCase { verifyNoNotifications(); } - @SmallTest + @Test public void testDifferentTransitionToNotify() { setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationSwitch(transition(CELLULAR, WIFI)); diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java index de28de6b3185..dfe31bde4ecf 100644 --- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java +++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java @@ -126,7 +126,6 @@ public class Nat464XlatTest { mLooper.dispatchNext(); verify(mNms).getInterfaceConfig(eq(STACKED_IFACE)); - verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(false)); verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); assertFalse(c.getValue().getStackedLinks().isEmpty()); assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); @@ -136,7 +135,6 @@ public class Nat464XlatTest { nat.stop(); verify(mNms).stopClatd(eq(BASE_IFACE)); - verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(true)); // Stacked interface removed notification arrives. nat.interfaceRemoved(STACKED_IFACE); @@ -167,7 +165,6 @@ public class Nat464XlatTest { mLooper.dispatchNext(); verify(mNms).getInterfaceConfig(eq(STACKED_IFACE)); - verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(false)); verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); assertFalse(c.getValue().getStackedLinks().isEmpty()); assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); @@ -179,7 +176,6 @@ public class Nat464XlatTest { verify(mNms).unregisterObserver(eq(nat)); verify(mNms).stopClatd(eq(BASE_IFACE)); - verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(true)); verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); assertTrue(c.getValue().getStackedLinks().isEmpty()); assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java index 911347c13478..125fe7258e94 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java @@ -34,20 +34,29 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.NetworkCapabilities; import android.net.NetworkInfo; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.telephony.TelephonyManager; -import android.test.suitebuilder.annotation.SmallTest; + import com.android.server.connectivity.NetworkNotificationManager.NotificationType; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import junit.framework.TestCase; + +import org.junit.runner.RunWith; +import org.junit.Before; +import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -public class NetworkNotificationManagerTest extends TestCase { + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class NetworkNotificationManagerTest { static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities(); static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities(); @@ -71,6 +80,7 @@ public class NetworkNotificationManagerTest extends TestCase { NetworkNotificationManager mManager; + @Before public void setUp() { MockitoAnnotations.initMocks(this); mCaptor = ArgumentCaptor.forClass(Notification.class); @@ -87,7 +97,7 @@ public class NetworkNotificationManagerTest extends TestCase { mManager = new NetworkNotificationManager(mCtx, mTelephonyManager, mNotificationManager); } - @SmallTest + @Test public void testNotificationsShownAndCleared() { final int NETWORK_ID_BASE = 100; List<NotificationType> types = Arrays.asList(NotificationType.values()); @@ -117,7 +127,7 @@ public class NetworkNotificationManagerTest extends TestCase { } } - @SmallTest + @Test public void testNoInternetNotificationsNotShownForCellular() { mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false); mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false); @@ -131,7 +141,7 @@ public class NetworkNotificationManagerTest extends TestCase { verify(mNotificationManager, times(1)).notifyAsUser(eq(tag), eq(eventId), any(), any()); } - @SmallTest + @Test public void testNotificationsNotShownIfNoInternetCapability() { mWifiNai.networkCapabilities = new NetworkCapabilities(); mWifiNai.networkCapabilities .addTransportType(NetworkCapabilities.TRANSPORT_WIFI); @@ -142,7 +152,7 @@ public class NetworkNotificationManagerTest extends TestCase { verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any()); } - @SmallTest + @Test public void testDuplicatedNotificationsNoInternetThenSignIn() { final int id = 101; final String tag = NetworkNotificationManager.tagFor(id); @@ -164,7 +174,7 @@ public class NetworkNotificationManagerTest extends TestCase { verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any()); } - @SmallTest + @Test public void testDuplicatedNotificationsSignInThenNoInternet() { final int id = 101; final String tag = NetworkNotificationManager.tagFor(id); diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index 4f18da7056ef..fe396c3a5c40 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -20,6 +20,9 @@ import static android.content.pm.UserInfo.FLAG_ADMIN; import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; import static android.content.pm.UserInfo.FLAG_PRIMARY; import static android.content.pm.UserInfo.FLAG_RESTRICTED; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalMatchers.*; import static org.mockito.Mockito.*; @@ -42,14 +45,17 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.UserHandle; import android.os.UserManager; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; import android.util.ArrayMap; import android.util.ArraySet; import com.android.internal.R; import com.android.internal.net.VpnConfig; +import org.junit.runner.RunWith; +import org.junit.Before; +import org.junit.Test; import org.mockito.Answers; import org.mockito.InOrder; import org.mockito.Mock; @@ -61,13 +67,16 @@ import java.util.Collections; import java.util.Map; import java.util.Set; + /** * Tests for {@link Vpn}. * * Build, install and run with: - * runtest --path java/com/android/server/connectivity/VpnTest.java + * runtest frameworks-net -c com.android.server.connectivity.VpnTest */ -public class VpnTest extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +@SmallTest +public class VpnTest { private static final String TAG = "VpnTest"; // Mock users @@ -106,7 +115,7 @@ public class VpnTest extends AndroidTestCase { @Mock private NotificationManager mNotificationManager; @Mock private Vpn.SystemServices mSystemServices; - @Override + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -130,7 +139,7 @@ public class VpnTest extends AndroidTestCase { doNothing().when(mNetService).registerObserver(any()); } - @SmallTest + @Test public void testRestrictedProfilesAreAddedToVpn() { setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB); @@ -144,7 +153,7 @@ public class VpnTest extends AndroidTestCase { })), ranges); } - @SmallTest + @Test public void testManagedProfilesAreNotAddedToVpn() { setMockedUsers(primaryUser, managedProfileA); @@ -157,7 +166,7 @@ public class VpnTest extends AndroidTestCase { })), ranges); } - @SmallTest + @Test public void testAddUserToVpnOnlyAddsOneUser() { setMockedUsers(primaryUser, restrictedProfileA, managedProfileA); @@ -170,7 +179,7 @@ public class VpnTest extends AndroidTestCase { })), ranges); } - @SmallTest + @Test public void testUidWhiteAndBlacklist() throws Exception { final Vpn vpn = createVpn(primaryUser.id); final UidRange user = UidRange.createForUser(primaryUser.id); @@ -195,7 +204,7 @@ public class VpnTest extends AndroidTestCase { })), disallow); } - @SmallTest + @Test public void testLockdownChangingPackage() throws Exception { final Vpn vpn = createVpn(primaryUser.id); final UidRange user = UidRange.createForUser(primaryUser.id); @@ -230,7 +239,7 @@ public class VpnTest extends AndroidTestCase { assertUnblocked(vpn, user.start + PKG_UIDS[3]); } - @SmallTest + @Test public void testLockdownAddingAProfile() throws Exception { final Vpn vpn = createVpn(primaryUser.id); setMockedUsers(primaryUser); @@ -270,7 +279,7 @@ public class VpnTest extends AndroidTestCase { })); } - @SmallTest + @Test public void testLockdownRuleRepeatability() throws Exception { final Vpn vpn = createVpn(primaryUser.id); @@ -293,7 +302,7 @@ public class VpnTest extends AndroidTestCase { verify(mNetService, times(2)).setAllowOnlyVpnForUids(anyBoolean(), any(UidRange[].class)); } - @SmallTest + @Test public void testLockdownRuleReversibility() throws Exception { final Vpn vpn = createVpn(primaryUser.id); @@ -322,7 +331,7 @@ public class VpnTest extends AndroidTestCase { order.verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(entireUser)); } - @SmallTest + @Test public void testIsAlwaysOnPackageSupported() throws Exception { final Vpn vpn = createVpn(primaryUser.id); @@ -356,7 +365,7 @@ public class VpnTest extends AndroidTestCase { assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); } - @SmallTest + @Test public void testNotificationShownForAlwaysOnApp() { final UserHandle userHandle = UserHandle.of(primaryUser.id); final Vpn vpn = createVpn(primaryUser.id); diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp index 5f586a15eeb8..627a231de5c8 100644 --- a/tools/aapt/Images.cpp +++ b/tools/aapt/Images.cpp @@ -1246,7 +1246,7 @@ static void write_png(const char* imageName, if (kIsDebug) { printf("Adding 9-patch info...\n"); } - strcpy((char*)unknowns[p_index].name, "npTc"); + memcpy((char*)unknowns[p_index].name, "npTc", 5); unknowns[p_index].data = (png_byte*)imageInfo.serialize9patch(); unknowns[p_index].size = imageInfo.info9Patch.serializedSize(); // TODO: remove the check below when everything works @@ -1254,7 +1254,7 @@ static void write_png(const char* imageName, // automatically generated 9 patch outline data int chunk_size = sizeof(png_uint_32) * 6; - strcpy((char*)unknowns[o_index].name, "npOl"); + memcpy((char*)unknowns[o_index].name, "npOl", 5); unknowns[o_index].data = (png_byte*) calloc(chunk_size, 1); png_byte outputData[chunk_size]; memcpy(&outputData, &imageInfo.outlineInsetsLeft, 4 * sizeof(png_uint_32)); @@ -1266,7 +1266,7 @@ static void write_png(const char* imageName, // optional optical inset / layout bounds data if (imageInfo.haveLayoutBounds) { int chunk_size = sizeof(png_uint_32) * 4; - strcpy((char*)unknowns[b_index].name, "npLb"); + memcpy((char*)unknowns[b_index].name, "npLb", 5); unknowns[b_index].data = (png_byte*) calloc(chunk_size, 1); memcpy(unknowns[b_index].data, &imageInfo.layoutBoundsLeft, chunk_size); unknowns[b_index].size = chunk_size; diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp index 6d6147d8c97a..33122dccb7de 100644 --- a/tools/aapt2/compile/Png.cpp +++ b/tools/aapt2/compile/Png.cpp @@ -538,7 +538,7 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr, if (kDebug) { diag->Note(DiagMessage() << "adding 9-patch info.."); } - strcpy((char*)unknowns[pIndex].name, "npTc"); + memcpy((char*)unknowns[pIndex].name, "npTc", 5); unknowns[pIndex].data = (png_byte*)info->serialize9Patch(); unknowns[pIndex].size = info->info9Patch.serializedSize(); // TODO: remove the check below when everything works @@ -546,7 +546,7 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr, // automatically generated 9 patch outline data int chunkSize = sizeof(png_uint_32) * 6; - strcpy((char*)unknowns[oIndex].name, "npOl"); + memcpy((char*)unknowns[oIndex].name, "npOl", 5); unknowns[oIndex].data = (png_byte*)calloc(chunkSize, 1); png_byte outputData[chunkSize]; memcpy(&outputData, &info->outlineInsetsLeft, 4 * sizeof(png_uint_32)); @@ -558,7 +558,7 @@ static bool writePng(IDiagnostics* diag, png_structp writePtr, // optional optical inset / layout bounds data if (info->haveLayoutBounds) { int chunkSize = sizeof(png_uint_32) * 4; - strcpy((char*)unknowns[bIndex].name, "npLb"); + memcpy((char*)unknowns[bIndex].name, "npLb", 5); unknowns[bIndex].data = (png_byte*)calloc(chunkSize, 1); memcpy(unknowns[bIndex].data, &info->layoutBoundsLeft, chunkSize); unknowns[bIndex].size = chunkSize; diff --git a/tools/incident_report/Android.bp b/tools/incident_report/Android.bp index 6f21605a99a4..ab55dbd81821 100644 --- a/tools/incident_report/Android.bp +++ b/tools/incident_report/Android.bp @@ -32,7 +32,4 @@ cc_binary_host { ], cflags: ["-Wno-unused-parameter"], - - // b/34740546, work around clang-tidy segmentation fault. - tidy_checks: ["-modernize*"], } diff --git a/tools/incident_section_gen/Android.bp b/tools/incident_section_gen/Android.bp index 7f8151f196ae..1756e06c66fa 100644 --- a/tools/incident_section_gen/Android.bp +++ b/tools/incident_section_gen/Android.bp @@ -19,8 +19,6 @@ // ========================================================== cc_binary_host { name: "incident-section-gen", - // b/34740546, work around clang-tidy segmentation fault. - tidy_checks: ["-modernize*"], cflags: [ "-g", "-O0", |