diff options
78 files changed, 1195 insertions, 773 deletions
diff --git a/Android.bp b/Android.bp index dda318b38d0d..b4ea61aeec28 100644 --- a/Android.bp +++ b/Android.bp @@ -1091,7 +1091,7 @@ doc_defaults { "ext", "framework", "voip-common", - "android.test.mock", + "android.test.mock.impl", ], local_sourcepaths: frameworks_base_subdirs, html_dirs: [ @@ -1207,7 +1207,7 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " + "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo" -doc_defaults { +stubs_defaults { name: "metalava-api-stubs-default", srcs: [ ":opt-telephony-srcs", @@ -1228,14 +1228,13 @@ doc_defaults { "ext", "framework", "voip-common", - "android.test.mock", + "android.test.mock.impl", ], local_sourcepaths: frameworks_base_subdirs, installable: false, - metalava_enabled: true, - metalava_annotations_enabled: true, - metalava_previous_api: ":last-released-public-api", - metalava_merge_annotations_dirs: [ + annotations_enabled: true, + previous_api: ":last-released-public-api", + merge_annotations_dirs: [ "metalava-manual", "ojluni-annotated-stubs", ], @@ -1467,7 +1466,7 @@ java_library_static { ], } -droiddoc { +droidstubs { name: "hiddenapi-lists-docs", defaults: ["metalava-api-stubs-default"], arg_files: [ @@ -1526,7 +1525,7 @@ filegroup { ], } -droiddoc { +droidstubs { name: "api-stubs-docs", defaults: ["metalava-api-stubs-default"], api_filename: "public_api.txt", @@ -1548,7 +1547,7 @@ droiddoc { }, } -droiddoc { +droidstubs { name: "system-api-stubs-docs", defaults: ["metalava-api-stubs-default"], api_tag_name: "SYSTEM", @@ -1572,7 +1571,7 @@ droiddoc { }, } -droiddoc { +droidstubs { name: "test-api-stubs-docs", defaults: ["metalava-api-stubs-default"], api_tag_name: "TEST", diff --git a/Android.mk b/Android.mk index 988c009bdbac..5c4c2376f80e 100644 --- a/Android.mk +++ b/Android.mk @@ -322,6 +322,11 @@ $(OUT_DOCS)/offline-sdk-timestamp: $(OUT_DOCS)/offline-sdk-docs-docs.zip ( unzip -qo $< -d $(OUT_DOCS)/offline-sdk && touch -f $@ ) || exit 1 # ==== hiddenapi lists ======================================= +.KATI_RESTAT: \ + $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST) \ + $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \ + $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \ + $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \ .KATI_IMPLICIT_OUTPUTS := \ $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \ @@ -346,10 +351,14 @@ $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST): \ $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)) \ $(PRIVATE_GREYLIST_INPUTS) \ --input-blacklists frameworks/base/config/hiddenapi-force-blacklist.txt \ - --output-whitelist $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST) \ - --output-light-greylist $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \ - --output-dark-greylist $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \ - --output-blacklist $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) + --output-whitelist $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST).tmp \ + --output-light-greylist $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST).tmp \ + --output-dark-greylist $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST).tmp \ + --output-blacklist $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST).tmp + $(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST)) + $(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST)) + $(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST)) + $(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)) # Include subdirectory makefiles # ============================================================ diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index 1f8ab21783ac..07b0ae10fd55 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -14,3 +14,5 @@ api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREU strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT} hidden_api_txt_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT} + +owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$" diff --git a/api/current.txt b/api/current.txt index 6a70b14c1afd..2a1295c1ed02 100755 --- a/api/current.txt +++ b/api/current.txt @@ -42440,6 +42440,7 @@ package android.telephony { } public class SubscriptionManager { + method public void addOnOpportunisticSubscriptionsChangedListener(java.util.concurrent.Executor, android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); method public boolean canManageSubscription(android.telephony.SubscriptionInfo); method public static deprecated android.telephony.SubscriptionManager from(android.content.Context); @@ -42453,8 +42454,11 @@ package android.telephony { method public static int getDefaultSmsSubscriptionId(); method public static int getDefaultSubscriptionId(); method public static int getDefaultVoiceSubscriptionId(); + method public static int[] getSubscriptionIds(int); method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int); method public boolean isNetworkRoaming(int); + method public static boolean isValidSubscriptionId(int); + method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); method public void setSubscriptionOverrideCongested(int, boolean, long); method public void setSubscriptionOverrideUnmetered(int, boolean, long); @@ -42470,6 +42474,11 @@ package android.telephony { field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff } + public static class SubscriptionManager.OnOpportunisticSubscriptionsChangedListener { + ctor public SubscriptionManager.OnOpportunisticSubscriptionsChangedListener(); + method public void onOpportunisticSubscriptionsChanged(); + } + public static class SubscriptionManager.OnSubscriptionsChangedListener { ctor public SubscriptionManager.OnSubscriptionsChangedListener(); method public void onSubscriptionsChanged(); diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index 9ca0745c04f4..35676059124a 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -11825,6 +11825,7 @@ HPLlibcore/io/BlockGuardOs;->readlink(Ljava/lang/String;)Ljava/lang/String; HPLlibcore/io/BlockGuardOs;->rename(Ljava/lang/String;Ljava/lang/String;)V HPLlibcore/io/BlockGuardOs;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/SocketAddress;)I HPLlibcore/io/BlockGuardOs;->write(Ljava/io/FileDescriptor;Ljava/nio/ByteBuffer;)I +HPLlibcore/io/ForwardingOs;->android_fdsan_exchange_owner_tag(Ljava/io/FileDescriptor;JJ)V HPLlibcore/io/ForwardingOs;->munlock(JJ)V HPLlibcore/io/ForwardingOs;->munmap(JJ)V HPLlibcore/io/ForwardingOs;->setsockoptByte(Ljava/io/FileDescriptor;III)V @@ -51627,6 +51628,7 @@ HSPLlibcore/io/IoTracker;->trackIo(ILlibcore/io/IoTracker$Mode;)V HSPLlibcore/io/IoUtils$FileReader;-><init>(Ljava/lang/String;)V HSPLlibcore/io/IoUtils$FileReader;->readFully()Llibcore/io/IoUtils$FileReader; HSPLlibcore/io/IoUtils$FileReader;->toByteArray()[B +HSPLlibcore/io/IoUtils;->acquireRawFd(Ljava/io/FileDescriptor;)I HSPLlibcore/io/IoUtils;->canOpenReadOnly(Ljava/lang/String;)Z HSPLlibcore/io/IoUtils;->close(Ljava/io/FileDescriptor;)V HSPLlibcore/io/IoUtils;->closeQuietly(Ljava/io/FileDescriptor;)V @@ -51634,6 +51636,7 @@ HSPLlibcore/io/IoUtils;->closeQuietly(Ljava/lang/AutoCloseable;)V HSPLlibcore/io/IoUtils;->readFileAsByteArray(Ljava/lang/String;)[B HSPLlibcore/io/IoUtils;->readFileAsString(Ljava/lang/String;)Ljava/lang/String; HSPLlibcore/io/IoUtils;->setBlocking(Ljava/io/FileDescriptor;Z)V +HSPLlibcore/io/IoUtils;->setFdOwner(Ljava/io/FileDescriptor;Ljava/lang/Object;)V HSPLlibcore/io/Linux;->read(Ljava/io/FileDescriptor;[BII)I HSPLlibcore/io/Linux;->recvfrom(Ljava/io/FileDescriptor;[BIIILjava/net/InetSocketAddress;)I HSPLlibcore/io/Linux;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;I)I diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 99b58d9eb42d..d520b28d42f7 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -2209,7 +2209,6 @@ Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landr Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String; Lcom/android/internal/view/BaseIWindow;-><init>()V Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList()Ljava/util/List; Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager; Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession; Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings; diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index 92fbd5927244..676baceffb87 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -29,7 +29,6 @@ import android.os.Handler; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; -import android.os.UserHandle; import android.os.WorkSource; import android.text.TextUtils; import android.util.ArrayMap; @@ -1150,7 +1149,9 @@ public class AlarmManager { public void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); proto.write(AlarmClockInfoProto.TRIGGER_TIME_MS, mTriggerTime); - mShowIntent.writeToProto(proto, AlarmClockInfoProto.SHOW_INTENT); + if (mShowIntent != null) { + mShowIntent.writeToProto(proto, AlarmClockInfoProto.SHOW_INTENT); + } proto.end(token); } } diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index 53315cce82dd..d148afb32b02 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -400,7 +400,7 @@ public class AppWidgetProviderInfo implements Parcelable { that.initialLayout = this.initialLayout; that.initialKeyguardLayout = this.initialKeyguardLayout; that.configure = this.configure == null ? null : this.configure.clone(); - that.label = this.label == null ? null : this.label.substring(0); + that.label = this.label; that.icon = this.icon; that.previewImage = this.previewImage; that.autoAdvanceViewId = this.autoAdvanceViewId; diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 243d7d8121c0..7cdae22061f1 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -621,6 +621,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY = 1 << 20; + /** + * Indicates whether this package requires access to non-SDK APIs. + * Only system apps and tests are allowed to use this property. + * @hide + */ + public static final int PRIVATE_FLAG_USES_NON_SDK_API = 1 << 22; + /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, @@ -1001,13 +1008,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public String appComponentFactory; /** - * Indicates whether this package requires access to non-SDK APIs. Only system apps - * and tests are allowed to use this property. - * @hide - */ - public boolean usesNonSdkApi; - - /** * The category of this app. Categories are used to cluster multiple apps * together into meaningful groups, such as when summarizing battery, * network, or disk usage. Apps should only define this value when they fit @@ -1283,6 +1283,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { pw.println(prefix + "category=" + category); } pw.println(prefix + "HiddenApiEnforcementPolicy=" + getHiddenApiEnforcementPolicy()); + pw.println(prefix + "usesNonSdkApi=" + usesNonSdkApi()); } super.dumpBack(pw, prefix); } @@ -1704,11 +1705,18 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName); } + /** + * @hide + */ + public boolean usesNonSdkApi() { + return (privateFlags & PRIVATE_FLAG_USES_NON_SDK_API) != 0; + } + private boolean isAllowedToUseHiddenApis() { if (isSignedWithPlatformKey()) { return true; } else if (isSystemApp() || isUpdatedSystemApp()) { - return usesNonSdkApi || isPackageWhitelistedForHiddenApis(); + return usesNonSdkApi() || isPackageWhitelistedForHiddenApis(); } else { return false; } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index b7be5a7ced2d..7eefe552149b 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -3580,8 +3580,10 @@ public class PackageParser { ai.appComponentFactory = buildClassName(ai.packageName, factory, outError); } - ai.usesNonSdkApi = sa.getBoolean( - com.android.internal.R.styleable.AndroidManifestApplication_usesNonSdkApi, false); + if (sa.getBoolean( + com.android.internal.R.styleable.AndroidManifestApplication_usesNonSdkApi, false)) { + ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API; + } if (outError[0] == null) { CharSequence pname; diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index f7aea978f5d1..57ec17842ff1 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -1096,7 +1096,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration protoOutputStream.write(FONT_SCALE, fontScale); protoOutputStream.write(MCC, mcc); protoOutputStream.write(MNC, mnc); - mLocaleList.writeToProto(protoOutputStream, LOCALES); + if (mLocaleList != null) { + mLocaleList.writeToProto(protoOutputStream, LOCALES); + } protoOutputStream.write(SCREEN_LAYOUT, screenLayout); protoOutputStream.write(COLOR_MODE, colorMode); protoOutputStream.write(TOUCHSCREEN, touchscreen); @@ -1111,7 +1113,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration protoOutputStream.write(SCREEN_HEIGHT_DP, screenHeightDp); protoOutputStream.write(SMALLEST_SCREEN_WIDTH_DP, smallestScreenWidthDp); protoOutputStream.write(DENSITY_DPI, densityDpi); - windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION); + if (windowConfiguration != null) { + windowConfiguration.writeToProto(protoOutputStream, WINDOW_CONFIGURATION); + } protoOutputStream.end(token); } diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index d8cdf60ad850..8e96f56e8cd3 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -575,9 +575,7 @@ public class Camera { /** * An empty Camera for testing purpose. */ - Camera() { - initAppOps(); - } + Camera() {} private void initAppOps() { IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 9b18e9a12969..35584ae21869 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -1255,7 +1255,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>If this device is the largest or only camera device with a given facing, then this * position will be <code>(0, 0, 0)</code>; a camera device with a lens optical center located 3 cm * from the main sensor along the +X axis (to the right from the user's perspective) will - * report <code>(0.03, 0, 0)</code>.</p> + * report <code>(0.03, 0, 0)</code>. Note that this means that, for many computer vision + * applications, the position needs to be negated to convert it to a translation from the + * camera to the origin.</p> * <p>To transform a pixel coordinates between two cameras facing the same direction, first * the source camera {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} must be corrected for. Then the source * camera {@link CameraCharacteristics#LENS_INTRINSIC_CALIBRATION android.lens.intrinsicCalibration} needs to be applied, followed by the @@ -1267,7 +1269,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>To compare this against a real image from the destination camera, the destination camera * image then needs to be corrected for radial distortion before comparison or sampling.</p> * <p>When {@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference} is GYROSCOPE, then this position is relative to - * the center of the primary gyroscope on the device.</p> + * the center of the primary gyroscope on the device. The axis definitions are the same as + * with PRIMARY_CAMERA.</p> * <p><b>Units</b>: Meters</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * @@ -1299,13 +1302,15 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </code></pre> * <p>which can then be combined with the camera pose rotation * <code>R</code> and translation <code>t</code> ({@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation} and - * {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}, respective) to calculate the + * {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}, respectively) to calculate the * complete transform from world coordinates to pixel * coordinates:</p> - * <pre><code>P = [ K 0 * [ R t - * 0 1 ] 0 1 ] + * <pre><code>P = [ K 0 * [ R -Rt + * 0 1 ] 0 1 ] * </code></pre> - * <p>and with <code>p_w</code> being a point in the world coordinate system + * <p>(Note the negation of poseTranslation when mapping from camera + * to world coordinates, and multiplication by the rotation).</p> + * <p>With <code>p_w</code> being a point in the world coordinate system * and <code>p_s</code> being a point in the camera active pixel array * coordinate system, and with the mapping including the * homogeneous division by z:</p> @@ -1327,6 +1332,13 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * activeArraySize rectangle), to determine the final pixel * coordinate of the world point for processed (non-RAW) * output buffers.</p> + * <p>For camera devices, the center of pixel <code>(x,y)</code> is located at + * coordinate <code>(x + 0.5, y + 0.5)</code>. So on a device with a + * precorrection active array of size <code>(10,10)</code>, the valid pixel + * indices go from <code>(0,0)-(9,9)</code>, and an perfectly-built camera would + * have an optical center at the exact center of the pixel grid, at + * coordinates <code>(5.0, 5.0)</code>, which is the top-left corner of pixel + * <code>(5,5)</code>.</p> * <p><b>Units</b>: * Pixels in the * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index 1275a852ee2b..caa99d5cb2a8 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -819,11 +819,11 @@ public abstract class CameraMetadata<TKey> { * camera in the list of supported camera devices.</p> * <p>This capability requires the camera device to support the following:</p> * <ul> - * <li>This camera device must list the following static metadata entries in {@link android.hardware.camera2.CameraCharacteristics }:<ul> - * <li>android.logicalMultiCamera.physicalIds</li> - * <li>{@link CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE android.logicalMultiCamera.sensorSyncType}</li> - * </ul> - * </li> + * <li>The IDs of underlying physical cameras are returned via + * {@link android.hardware.camera2.CameraCharacteristics#getPhysicalCameraIds }.</li> + * <li>This camera device must list static metadata + * {@link CameraCharacteristics#LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE android.logicalMultiCamera.sensorSyncType} in + * {@link android.hardware.camera2.CameraCharacteristics }.</li> * <li>The underlying physical cameras' static metadata must list the following entries, * so that the application can correlate pixels from the physical streams:<ul> * <li>{@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference}</li> diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 0b92b0cbef15..4a20468276d3 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -2530,7 +2530,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * outputs will crop horizontally (pillarbox), and 16:9 * streams will match exactly. These additional crops will * be centered within the crop region.</p> - * <p>If the coordinate system is android.sensor.info.activeArraysSize, the width and height + * <p>If the coordinate system is {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, the width and height * of the crop region cannot be set to be smaller than * <code>floor( activeArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code> and * <code>floor( activeArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>, respectively.</p> @@ -2871,8 +2871,14 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> new Key<Integer>("android.statistics.lensShadingMapMode", int.class); /** - * <p>A control for selecting whether OIS position information is included in output - * result metadata.</p> + * <p>A control for selecting whether optical stabilization (OIS) position + * information is included in output result metadata.</p> + * <p>Since optical image stabilization generally involves motion much faster than the duration + * of individualq image exposure, multiple OIS samples can be included for a single capture + * result. For example, if the OIS reporting operates at 200 Hz, a typical camera operating + * at 30fps may have 6-7 OIS samples per capture result. This information can be combined + * with the rolling shutter skew to account for lens motion during image exposure in + * post-processing algorithms.</p> * <p><b>Possible values:</b> * <ul> * <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li> @@ -3272,14 +3278,28 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * any correction at all would slow down capture rate. Every output stream will have a * similar amount of enhancement applied.</p> * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not - * applied to any RAW output. Metadata coordinates such as face rectangles or metering - * regions are also not affected by correction.</p> + * applied to any RAW output.</p> * <p>This control will be on by default on devices that support this control. Applications * disabling distortion correction need to pay extra attention with the coordinate system of * metering regions, crop region, and face rectangles. When distortion correction is OFF, * metadata coordinates follow the coordinate system of * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}. When distortion is not OFF, metadata - * coordinates follow the coordinate system of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p> + * coordinates follow the coordinate system of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}. The + * camera device will map these metadata fields to match the corrected image produced by the + * camera device, for both capture requests and results. However, this mapping is not very + * precise, since rectangles do not generally map to rectangles when corrected. Only linear + * scaling between the active array and precorrection active array coordinates is + * performed. Applications that require precise correction of metadata need to undo that + * linear scaling, and apply a more complete correction that takes into the account the app's + * own requirements.</p> + * <p>The full list of metadata that is affected in this way by distortion correction is:</p> + * <ul> + * <li>{@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}</li> + * <li>{@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}</li> + * <li>{@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}</li> + * <li>{@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}</li> + * <li>{@link CaptureResult#STATISTICS_FACES android.statistics.faces}</li> + * </ul> * <p><b>Possible values:</b> * <ul> * <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li> @@ -3290,10 +3310,15 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CaptureRequest#CONTROL_AE_REGIONS + * @see CaptureRequest#CONTROL_AF_REGIONS + * @see CaptureRequest#CONTROL_AWB_REGIONS * @see CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES * @see CameraCharacteristics#LENS_DISTORTION + * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE + * @see CaptureResult#STATISTICS_FACES * @see #DISTORTION_CORRECTION_MODE_OFF * @see #DISTORTION_CORRECTION_MODE_FAST * @see #DISTORTION_CORRECTION_MODE_HIGH_QUALITY diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index e007d282ad04..1e894e8a29c2 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -2858,7 +2858,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <p>If this device is the largest or only camera device with a given facing, then this * position will be <code>(0, 0, 0)</code>; a camera device with a lens optical center located 3 cm * from the main sensor along the +X axis (to the right from the user's perspective) will - * report <code>(0.03, 0, 0)</code>.</p> + * report <code>(0.03, 0, 0)</code>. Note that this means that, for many computer vision + * applications, the position needs to be negated to convert it to a translation from the + * camera to the origin.</p> * <p>To transform a pixel coordinates between two cameras facing the same direction, first * the source camera {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} must be corrected for. Then the source * camera {@link CameraCharacteristics#LENS_INTRINSIC_CALIBRATION android.lens.intrinsicCalibration} needs to be applied, followed by the @@ -2870,7 +2872,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <p>To compare this against a real image from the destination camera, the destination camera * image then needs to be corrected for radial distortion before comparison or sampling.</p> * <p>When {@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference} is GYROSCOPE, then this position is relative to - * the center of the primary gyroscope on the device.</p> + * the center of the primary gyroscope on the device. The axis definitions are the same as + * with PRIMARY_CAMERA.</p> * <p><b>Units</b>: Meters</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * @@ -2902,13 +2905,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * </code></pre> * <p>which can then be combined with the camera pose rotation * <code>R</code> and translation <code>t</code> ({@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation} and - * {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}, respective) to calculate the + * {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}, respectively) to calculate the * complete transform from world coordinates to pixel * coordinates:</p> - * <pre><code>P = [ K 0 * [ R t - * 0 1 ] 0 1 ] + * <pre><code>P = [ K 0 * [ R -Rt + * 0 1 ] 0 1 ] * </code></pre> - * <p>and with <code>p_w</code> being a point in the world coordinate system + * <p>(Note the negation of poseTranslation when mapping from camera + * to world coordinates, and multiplication by the rotation).</p> + * <p>With <code>p_w</code> being a point in the world coordinate system * and <code>p_s</code> being a point in the camera active pixel array * coordinate system, and with the mapping including the * homogeneous division by z:</p> @@ -2930,6 +2935,13 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * activeArraySize rectangle), to determine the final pixel * coordinate of the world point for processed (non-RAW) * output buffers.</p> + * <p>For camera devices, the center of pixel <code>(x,y)</code> is located at + * coordinate <code>(x + 0.5, y + 0.5)</code>. So on a device with a + * precorrection active array of size <code>(10,10)</code>, the valid pixel + * indices go from <code>(0,0)-(9,9)</code>, and an perfectly-built camera would + * have an optical center at the exact center of the pixel grid, at + * coordinates <code>(5.0, 5.0)</code>, which is the top-left corner of pixel + * <code>(5,5)</code>.</p> * <p><b>Units</b>: * Pixels in the * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} @@ -3194,7 +3206,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * outputs will crop horizontally (pillarbox), and 16:9 * streams will match exactly. These additional crops will * be centered within the crop region.</p> - * <p>If the coordinate system is android.sensor.info.activeArraysSize, the width and height + * <p>If the coordinate system is {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, the width and height * of the crop region cannot be set to be smaller than * <code>floor( activeArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code> and * <code>floor( activeArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>, respectively.</p> @@ -4083,8 +4095,14 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { new Key<Integer>("android.statistics.lensShadingMapMode", int.class); /** - * <p>A control for selecting whether OIS position information is included in output - * result metadata.</p> + * <p>A control for selecting whether optical stabilization (OIS) position + * information is included in output result metadata.</p> + * <p>Since optical image stabilization generally involves motion much faster than the duration + * of individualq image exposure, multiple OIS samples can be included for a single capture + * result. For example, if the OIS reporting operates at 200 Hz, a typical camera operating + * at 30fps may have 6-7 OIS samples per capture result. This information can be combined + * with the rolling shutter skew to account for lens motion during image exposure in + * post-processing algorithms.</p> * <p><b>Possible values:</b> * <ul> * <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li> @@ -4118,11 +4136,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <p>An array of shifts of OIS samples, in x direction.</p> * <p>The array contains the amount of shifts in x direction, in pixels, based on OIS samples. - * A positive value is a shift from left to right in active array coordinate system. For - * example, if the optical center is (1000, 500) in active array coordinates, a shift of - * (3, 0) puts the new optical center at (1003, 500).</p> + * A positive value is a shift from left to right in the pre-correction active array + * coordinate system. For example, if the optical center is (1000, 500) in pre-correction + * active array coordinates, a shift of (3, 0) puts the new optical center at (1003, 500).</p> * <p>The number of shifts must match the number of timestamps in * android.statistics.oisTimestamps.</p> + * <p>The OIS samples are not affected by whether lens distortion correction is enabled (on + * supporting devices). They are always reported in pre-correction active array coordinates, + * since the scaling of OIS shifts would depend on the specific spot on the sensor the shift + * is needed.</p> * <p><b>Units</b>: Pixels in active array.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * @hide @@ -4133,11 +4155,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <p>An array of shifts of OIS samples, in y direction.</p> * <p>The array contains the amount of shifts in y direction, in pixels, based on OIS samples. - * A positive value is a shift from top to bottom in active array coordinate system. For - * example, if the optical center is (1000, 500) in active array coordinates, a shift of - * (0, 5) puts the new optical center at (1000, 505).</p> + * A positive value is a shift from top to bottom in pre-correction active array coordinate + * system. For example, if the optical center is (1000, 500) in active array coordinates, a + * shift of (0, 5) puts the new optical center at (1000, 505).</p> * <p>The number of shifts must match the number of timestamps in * android.statistics.oisTimestamps.</p> + * <p>The OIS samples are not affected by whether lens distortion correction is enabled (on + * supporting devices). They are always reported in pre-correction active array coordinates, + * since the scaling of OIS shifts would depend on the specific spot on the sensor the shift + * is needed.</p> * <p><b>Units</b>: Pixels in active array.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * @hide @@ -4146,15 +4172,21 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { new Key<float[]>("android.statistics.oisYShifts", float[].class); /** - * <p>An array of OIS samples.</p> + * <p>An array of optical stabilization (OIS) position samples.</p> * <p>Each OIS sample contains the timestamp and the amount of shifts in x and y direction, * in pixels, of the OIS sample.</p> - * <p>A positive value for a shift in x direction is a shift from left to right in active array - * coordinate system. For example, if the optical center is (1000, 500) in active array - * coordinates, a shift of (3, 0) puts the new optical center at (1003, 500).</p> - * <p>A positive value for a shift in y direction is a shift from top to bottom in active array - * coordinate system. For example, if the optical center is (1000, 500) in active array - * coordinates, a shift of (0, 5) puts the new optical center at (1000, 505).</p> + * <p>A positive value for a shift in x direction is a shift from left to right in the + * pre-correction active array coordinate system. For example, if the optical center is + * (1000, 500) in pre-correction active array coordinates, a shift of (3, 0) puts the new + * optical center at (1003, 500).</p> + * <p>A positive value for a shift in y direction is a shift from top to bottom in + * pre-correction active array coordinate system. For example, if the optical center is + * (1000, 500) in active array coordinates, a shift of (0, 5) puts the new optical center at + * (1000, 505).</p> + * <p>The OIS samples are not affected by whether lens distortion correction is enabled (on + * supporting devices). They are always reported in pre-correction active array coordinates, + * since the scaling of OIS shifts would depend on the specific spot on the sensor the shift + * is needed.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> */ @PublicKey @@ -4584,14 +4616,28 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * any correction at all would slow down capture rate. Every output stream will have a * similar amount of enhancement applied.</p> * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not - * applied to any RAW output. Metadata coordinates such as face rectangles or metering - * regions are also not affected by correction.</p> + * applied to any RAW output.</p> * <p>This control will be on by default on devices that support this control. Applications * disabling distortion correction need to pay extra attention with the coordinate system of * metering regions, crop region, and face rectangles. When distortion correction is OFF, * metadata coordinates follow the coordinate system of * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}. When distortion is not OFF, metadata - * coordinates follow the coordinate system of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p> + * coordinates follow the coordinate system of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}. The + * camera device will map these metadata fields to match the corrected image produced by the + * camera device, for both capture requests and results. However, this mapping is not very + * precise, since rectangles do not generally map to rectangles when corrected. Only linear + * scaling between the active array and precorrection active array coordinates is + * performed. Applications that require precise correction of metadata need to undo that + * linear scaling, and apply a more complete correction that takes into the account the app's + * own requirements.</p> + * <p>The full list of metadata that is affected in this way by distortion correction is:</p> + * <ul> + * <li>{@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}</li> + * <li>{@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}</li> + * <li>{@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}</li> + * <li>{@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}</li> + * <li>{@link CaptureResult#STATISTICS_FACES android.statistics.faces}</li> + * </ul> * <p><b>Possible values:</b> * <ul> * <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li> @@ -4602,10 +4648,15 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CaptureRequest#CONTROL_AE_REGIONS + * @see CaptureRequest#CONTROL_AF_REGIONS + * @see CaptureRequest#CONTROL_AWB_REGIONS * @see CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES * @see CameraCharacteristics#LENS_DISTORTION + * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE + * @see CaptureResult#STATISTICS_FACES * @see #DISTORTION_CORRECTION_MODE_OFF * @see #DISTORTION_CORRECTION_MODE_FAST * @see #DISTORTION_CORRECTION_MODE_HIGH_QUALITY diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 9bcc6001615f..40465ceafcb8 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -197,7 +197,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { * * <p>Example: "//www.google.com/search?q=android" * - * @return the decoded scheme-specific-part + * @return the encoded scheme-specific-part */ public abstract String getEncodedSchemeSpecificPart(); diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index f17e0f026fda..684a8ee43c87 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -386,7 +386,9 @@ public final class Looper { final long looperToken = proto.start(fieldId); proto.write(LooperProto.THREAD_NAME, mThread.getName()); proto.write(LooperProto.THREAD_ID, mThread.getId()); - mQueue.writeToProto(proto, LooperProto.QUEUE); + if (mQueue != null) { + mQueue.writeToProto(proto, LooperProto.QUEUE); + } proto.end(looperToken); } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 53b224c36cb2..b93afdf3a090 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -30,6 +30,7 @@ import android.content.pm.PackageManager; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -2249,7 +2250,7 @@ public final class InputMethodManager { * Notify that a user took some action with this input method. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(trackingBug = 114740982, maxTargetSdk = Build.VERSION_CODES.P) public void notifyUserAction() { synchronized (mH) { if (mLastSentUserActionNotificationSequenceNumber == diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS index 21d750c59a4e..e65d11404a4e 100644 --- a/core/java/com/android/internal/util/OWNERS +++ b/core/java/com/android/internal/util/OWNERS @@ -1,24 +1,4 @@ -per-file AsyncChannel*=lorenzo@google.com -per-file AsyncChannel*=satk@google.com -per-file AsyncChannel*=silberst@google.com -per-file BitUtils*=ek@google.com -per-file BitUtils*=lorenzo@google.com -per-file BitUtils*=satk@google.com -per-file MessageUtils*=ek@google.com -per-file MessageUtils*=lorenzo@google.com -per-file MessageUtils*=satk@google.com -per-file Protocol*=ek@google.com -per-file Protocol*=lorenzo@google.com -per-file Protocol*=quiche@google.com -per-file Protocol*=satk@google.com -per-file Protocol*=silberst@google.com -per-file RingBuffer*=ek@google.com -per-file RingBuffer*=lorenzo@google.com -per-file RingBuffer*=satk@google.com -per-file State*=ek@google.com -per-file State*=lorenzo@google.com -per-file State*=quiche@google.com -per-file State*=silberst@google.com -per-file TokenBucket*=ek@google.com -per-file TokenBucket*=lorenzo@google.com -per-file TokenBucket*=satk@google.com +per-file AsyncChannel* = lorenzo@google.com, satk@google.com, etancohen@google.com +per-file BitUtils*, MessageUtils*, Protocol*, RingBuffer*, TokenBucket* = jchalard@google.com, lorenzo@google.com, satk@google.com +per-file Protocol* = etancohen@google.com, lorenzo@google.com +per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com diff --git a/data/etc/platform.xml b/data/etc/platform.xml index b3f05dc9fc98..6f52fbd1b4f5 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -182,11 +182,11 @@ code to link against. --> <library name="android.test.base" - file="/system/framework/android.test.base.jar" /> + file="/system/framework/android.test.base.impl.jar" /> <library name="android.test.mock" - file="/system/framework/android.test.mock.jar" /> + file="/system/framework/android.test.mock.impl.jar" /> <library name="android.test.runner" - file="/system/framework/android.test.runner.jar" /> + file="/system/framework/android.test.runner.impl.jar" /> <!-- These are the standard packages that are white-listed to always have internet access while in power save mode, even if they aren't in the foreground. --> diff --git a/libs/androidfw/include/androidfw/ByteBucketArray.h b/libs/androidfw/include/androidfw/ByteBucketArray.h index d84a207697e9..949c9445b3e8 100644 --- a/libs/androidfw/include/androidfw/ByteBucketArray.h +++ b/libs/androidfw/include/androidfw/ByteBucketArray.h @@ -60,7 +60,7 @@ class ByteBucketArray { } T& editItemAt(size_t index) { - CHECK(index < size()) << "ByteBucketArray.getOrCreate(index=" << index + CHECK(index < size()) << "ByteBucketArray.editItemAt(index=" << index << ") with size=" << size(); uint8_t bucket_index = static_cast<uint8_t>(index) >> 4; diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 047622222065..5ad73653a615 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -715,6 +715,7 @@ public final class AudioAttributes implements Parcelable { break; case AudioSystem.STREAM_TTS: mContentType = CONTENT_TYPE_SONIFICATION; + mFlags |= FLAG_BEACON; break; case AudioSystem.STREAM_ACCESSIBILITY: mContentType = CONTENT_TYPE_SPEECH; @@ -1039,6 +1040,10 @@ public final class AudioAttributes implements Parcelable { return fromGetVolumeControlStream ? AudioSystem.STREAM_VOICE_CALL : AudioSystem.STREAM_BLUETOOTH_SCO; } + if ((aa.getAllFlags() & FLAG_BEACON) == FLAG_BEACON) { + return fromGetVolumeControlStream ? + AudioSystem.STREAM_MUSIC : AudioSystem.STREAM_TTS; + } // usage to stream type mapping switch (aa.getUsage()) { diff --git a/packages/CaptivePortalLogin/Android.mk b/packages/CaptivePortalLogin/Android.mk index 8a96b1693dc1..7dc23ff8e8b8 100644 --- a/packages/CaptivePortalLogin/Android.mk +++ b/packages/CaptivePortalLogin/Android.mk @@ -2,7 +2,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional -LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 services.net +LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java index ac5f5373d8ec..0e0f63cb084c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java @@ -33,7 +33,6 @@ import java.util.List; final class A2dpSinkProfile implements LocalBluetoothProfile { private static final String TAG = "A2dpSinkProfile"; - private static boolean V = true; private BluetoothA2dpSink mService; private boolean mIsProfileReady; @@ -57,7 +56,7 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); + Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothA2dpSink) proxy; // We just bound to the service, so refresh the UI for any connected A2DP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -76,7 +75,7 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mIsProfileReady=false; } } @@ -109,7 +108,9 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { } public List<BluetoothDevice> getConnectedDevices() { - if (mService == null) return new ArrayList<BluetoothDevice>(0); + if (mService == null) { + return new ArrayList<BluetoothDevice>(0); + } return mService.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, @@ -117,24 +118,18 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { } public boolean connect(BluetoothDevice device) { - if (mService == null) return false; - List<BluetoothDevice> srcs = getConnectedDevices(); - if (srcs != null) { - for (BluetoothDevice src : srcs) { - if (src.equals(device)) { - // Connect to same device, Ignore it - Log.d(TAG,"Ignoring Connect"); - return true; - } - } + if (mService == null) { + return false; } return mService.connect(device); } public boolean disconnect(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } // Downgrade priority as user is disconnecting the headset. - if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){ + if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); } return mService.disconnect(device); @@ -148,17 +143,23 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { } public boolean isPreferred(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; } public int getPreferred(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.PRIORITY_OFF; + if (mService == null) { + return BluetoothProfile.PRIORITY_OFF; + } return mService.getPriority(device); } public void setPreferred(BluetoothDevice device, boolean preferred) { - if (mService == null) return; + if (mService == null) { + return; + } if (preferred) { if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -169,7 +170,9 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { } boolean isA2dpPlaying() { - if (mService == null) return false; + if (mService == null) { + return false; + } List<BluetoothDevice> srcs = mService.getConnectedDevices(); if (!srcs.isEmpty()) { if (mService.isA2dpPlaying(srcs.get(0))) { @@ -211,11 +214,11 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.A2DP_SINK, - mService); + mService); mService = null; }catch (Throwable t) { Log.w(TAG, "Error cleaning up A2DP proxy", t); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java index 03f6afb39613..0857b019ee64 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java @@ -36,7 +36,6 @@ import java.util.List; */ final class HfpClientProfile implements LocalBluetoothProfile { private static final String TAG = "HfpClientProfile"; - private static boolean V = false; private BluetoothHeadsetClient mService; private boolean mIsProfileReady; @@ -61,7 +60,7 @@ final class HfpClientProfile implements LocalBluetoothProfile { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); + Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothHeadsetClient) proxy; // We just bound to the service, so refresh the UI for any connected HFP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -82,7 +81,7 @@ final class HfpClientProfile implements LocalBluetoothProfile { @Override public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mIsProfileReady=false; } } @@ -118,7 +117,9 @@ final class HfpClientProfile implements LocalBluetoothProfile { } public List<BluetoothDevice> getConnectedDevices() { - if (mService == null) return new ArrayList<BluetoothDevice>(0); + if (mService == null) { + return new ArrayList<BluetoothDevice>(0); + } return mService.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, @@ -127,23 +128,17 @@ final class HfpClientProfile implements LocalBluetoothProfile { @Override public boolean connect(BluetoothDevice device) { - if (mService == null) return false; - List<BluetoothDevice> srcs = getConnectedDevices(); - if (srcs != null) { - for (BluetoothDevice src : srcs) { - if (src.equals(device)) { - // Connect to same device, Ignore it - Log.d(TAG,"Ignoring Connect"); - return true; - } - } + if (mService == null) { + return false; } return mService.connect(device); } @Override public boolean disconnect(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } // Downgrade priority as user is disconnecting the headset. if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){ mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -161,19 +156,25 @@ final class HfpClientProfile implements LocalBluetoothProfile { @Override public boolean isPreferred(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; } @Override public int getPreferred(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.PRIORITY_OFF; + if (mService == null) { + return BluetoothProfile.PRIORITY_OFF; + } return mService.getPriority(device); } @Override public void setPreferred(BluetoothDevice device, boolean preferred) { - if (mService == null) return; + if (mService == null) { + return; + } if (preferred) { if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -219,7 +220,7 @@ final class HfpClientProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy( diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java index aa7a7af582a7..511c4ce678e2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java @@ -32,11 +32,10 @@ import java.util.ArrayList; import java.util.List; /** - * MapProfile handles Bluetooth MAP profile. + * MapProfile handles the Bluetooth MAP MSE role */ public class MapProfile implements LocalBluetoothProfile { private static final String TAG = "MapProfile"; - private static boolean V = true; private BluetoothMap mService; private boolean mIsProfileReady; @@ -60,7 +59,7 @@ public class MapProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); + Log.d(TAG, "Bluetooth service connected"); mService = (BluetoothMap) proxy; // We just bound to the service, so refresh the UI for any connected MAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -82,14 +81,14 @@ public class MapProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); + Log.d(TAG, "Bluetooth service disconnected"); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } } public boolean isProfileReady() { - if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady); + Log.d(TAG, "isProfileReady(): " + mIsProfileReady); return mIsProfileReady; } @@ -117,45 +116,45 @@ public class MapProfile implements LocalBluetoothProfile { } public boolean connect(BluetoothDevice device) { - if(V)Log.d(TAG,"connect() - should not get called"); + Log.d(TAG, "connect() - should not get called"); return false; // MAP never connects out } public boolean disconnect(BluetoothDevice device) { - if (mService == null) return false; - List<BluetoothDevice> deviceList = mService.getConnectedDevices(); - if (!deviceList.isEmpty() && deviceList.get(0).equals(device)) { - if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { - mService.setPriority(device, BluetoothProfile.PRIORITY_ON); - } - return mService.disconnect(device); - } else { + if (mService == null) { return false; } + if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { + mService.setPriority(device, BluetoothProfile.PRIORITY_ON); + } + return mService.disconnect(device); } public int getConnectionStatus(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.STATE_DISCONNECTED; - List<BluetoothDevice> deviceList = mService.getConnectedDevices(); - if(V) Log.d(TAG,"getConnectionStatus: status is: "+ mService.getConnectionState(device)); - - return !deviceList.isEmpty() && deviceList.get(0).equals(device) - ? mService.getConnectionState(device) - : BluetoothProfile.STATE_DISCONNECTED; + if (mService == null) { + return BluetoothProfile.STATE_DISCONNECTED; + } + return mService.getConnectionState(device); } public boolean isPreferred(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; } public int getPreferred(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.PRIORITY_OFF; + if (mService == null) { + return BluetoothProfile.PRIORITY_OFF; + } return mService.getPriority(device); } public void setPreferred(BluetoothDevice device, boolean preferred) { - if (mService == null) return; + if (mService == null) { + return; + } if (preferred) { if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -166,7 +165,9 @@ public class MapProfile implements LocalBluetoothProfile { } public List<BluetoothDevice> getConnectedDevices() { - if (mService == null) return new ArrayList<BluetoothDevice>(0); + if (mService == null) { + return new ArrayList<BluetoothDevice>(0); + } return mService.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, @@ -204,7 +205,7 @@ public class MapProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP, diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index f7aa29796ce8..33321938fe3f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -134,7 +134,7 @@ public class DataUsageController { final NetworkStatsHistory history = session.getHistoryForNetwork(template, FIELDS); final long now = System.currentTimeMillis(); final long start, end; - if (policy != null) { + if (policy != null && policy.hasCycle()) { final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager .cycleIterator(policy).next(); start = cycle.first.toInstant().toEpochMilli(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java new file mode 100644 index 000000000000..d38a2d0782d7 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothA2dpSink; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class A2dpSinkProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothA2dpSink mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private A2dpSinkProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.A2DP_SINK)); + + mProfile = new A2dpSinkProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK, mService); + } + + @Test + public void connect_shouldConnectBluetoothA2dpSink() { + mProfile.connect(mBluetoothDevice); + verify(mService).connect(mBluetoothDevice); + } + + @Test + public void disconnect_shouldDisconnectBluetoothA2dpSink() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +}
\ No newline at end of file diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java new file mode 100644 index 000000000000..7b467d69e7f4 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHeadsetClient; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class HfpClientProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothHeadsetClient mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private HfpClientProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.HEADSET_CLIENT)); + + mProfile = new HfpClientProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.HEADSET_CLIENT, mService); + } + + @Test + public void connect_shouldConnectBluetoothHeadsetClient() { + mProfile.connect(mBluetoothDevice); + verify(mService).connect(mBluetoothDevice); + } + + @Test + public void disconnect_shouldDisconnectBluetoothHeadsetClient() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +} diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index 01e81525d5b5..380f6a7e581e 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -612,7 +612,7 @@ public class IpSecService extends IIpSecService.Stub { mSrvConfig .getNetdInstance() .ipSecDeleteSecurityAssociation( - mResourceId, + uid, mConfig.getSourceAddress(), mConfig.getDestinationAddress(), spi, @@ -679,7 +679,7 @@ public class IpSecService extends IIpSecService.Stub { mSrvConfig .getNetdInstance() .ipSecDeleteSecurityAssociation( - mResourceId, mSourceAddress, mDestinationAddress, mSpi, 0, 0); + uid, mSourceAddress, mDestinationAddress, mSpi, 0, 0); } } catch (ServiceSpecificException | RemoteException e) { Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e); @@ -821,13 +821,13 @@ public class IpSecService extends IIpSecService.Stub { for (int selAddrFamily : ADDRESS_FAMILIES) { netd.ipSecDeleteSecurityPolicy( - 0, + uid, selAddrFamily, IpSecManager.DIRECTION_OUT, mOkey, 0xffffffff); netd.ipSecDeleteSecurityPolicy( - 0, + uid, selAddrFamily, IpSecManager.DIRECTION_IN, mIkey, @@ -1083,7 +1083,8 @@ public class IpSecService extends IIpSecService.Stub { } checkNotNull(binder, "Null Binder passed to allocateSecurityParameterIndex"); - UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); + int callingUid = Binder.getCallingUid(); + UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid); final int resourceId = mNextResourceId++; int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX; @@ -1096,7 +1097,7 @@ public class IpSecService extends IIpSecService.Stub { spi = mSrvConfig .getNetdInstance() - .ipSecAllocateSpi(resourceId, "", destinationAddress, requestedSpi); + .ipSecAllocateSpi(callingUid, "", destinationAddress, requestedSpi); Log.d(TAG, "Allocated SPI " + spi); userRecord.mSpiRecords.put( resourceId, @@ -1264,7 +1265,8 @@ public class IpSecService extends IIpSecService.Stub { // TODO: Check that underlying network exists, and IP addresses not assigned to a different // network (b/72316676). - UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); + int callerUid = Binder.getCallingUid(); + UserRecord userRecord = mUserResourceTracker.getUserRecord(callerUid); if (!userRecord.mTunnelQuotaTracker.isAvailable()) { return new IpSecTunnelInterfaceResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE); } @@ -1285,7 +1287,7 @@ public class IpSecService extends IIpSecService.Stub { for (int selAddrFamily : ADDRESS_FAMILIES) { // Always send down correct local/remote addresses for template. netd.ipSecAddSecurityPolicy( - 0, // Use 0 for reqId + callerUid, selAddrFamily, IpSecManager.DIRECTION_OUT, localAddr, @@ -1294,7 +1296,7 @@ public class IpSecService extends IIpSecService.Stub { okey, 0xffffffff); netd.ipSecAddSecurityPolicy( - 0, // Use 0 for reqId + callerUid, selAddrFamily, IpSecManager.DIRECTION_IN, remoteAddr, @@ -1532,7 +1534,7 @@ public class IpSecService extends IIpSecService.Stub { mSrvConfig .getNetdInstance() .ipSecAddSecurityAssociation( - resourceId, + Binder.getCallingUid(), c.getMode(), c.getSourceAddress(), c.getDestinationAddress(), @@ -1623,13 +1625,14 @@ public class IpSecService extends IIpSecService.Stub { @Override public synchronized void applyTransportModeTransform( ParcelFileDescriptor socket, int direction, int resourceId) throws RemoteException { - UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); + int callingUid = Binder.getCallingUid(); + UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid); checkDirection(direction); // Get transform record; if no transform is found, will throw IllegalArgumentException TransformRecord info = userRecord.mTransformRecords.getResourceOrThrow(resourceId); // TODO: make this a function. - if (info.pid != getCallingPid() || info.uid != getCallingUid()) { + if (info.pid != getCallingPid() || info.uid != callingUid) { throw new SecurityException("Only the owner of an IpSec Transform may apply it!"); } @@ -1643,7 +1646,7 @@ public class IpSecService extends IIpSecService.Stub { .getNetdInstance() .ipSecApplyTransportModeTransform( socket.getFileDescriptor(), - resourceId, + callingUid, direction, c.getSourceAddress(), c.getDestinationAddress(), @@ -1675,7 +1678,8 @@ public class IpSecService extends IIpSecService.Stub { enforceTunnelPermissions(callingPackage); checkDirection(direction); - UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid()); + int callingUid = Binder.getCallingUid(); + UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid); // Get transform record; if no transform is found, will throw IllegalArgumentException TransformRecord transformInfo = @@ -1717,7 +1721,7 @@ public class IpSecService extends IIpSecService.Stub { mSrvConfig .getNetdInstance() .ipSecUpdateSecurityPolicy( - 0, // Use 0 for reqId + callingUid, selAddrFamily, direction, tunnelInterfaceInfo.getLocalAddress(), diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index bd0a4c7bb1c8..9c81748ea435 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -315,7 +315,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub } private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap(); - private volatile boolean mBandwidthControlEnabled; private volatile boolean mFirewallEnabled; private volatile boolean mStrictEnabled; @@ -619,27 +618,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub */ private void prepareNativeDaemon() { - mBandwidthControlEnabled = false; - - // only enable bandwidth control when support exists - final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists(); - // push any existing quota or UID rules synchronized (mQuotaLock) { - if (hasKernelSupport) { - Slog.d(TAG, "enabling bandwidth control"); - try { - mConnector.execute("bandwidth", "enable"); - mBandwidthControlEnabled = true; - } catch (NativeDaemonConnectorException e) { - Log.wtf(TAG, "problem enabling bandwidth controls", e); - } - } else { - Slog.i(TAG, "not enabling bandwidth control"); - } - - SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0"); + // Netd unconditionally enable bandwidth control + SystemProperties.set(PROP_QTAGUID_ENABLED, "1"); mStrictEnabled = true; @@ -721,11 +704,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub } } - if (mBandwidthControlEnabled) { - try { - getBatteryStats().noteNetworkStatsEnabled(); - } catch (RemoteException e) { - } + + try { + getBatteryStats().noteNetworkStatsEnabled(); + } catch (RemoteException e) { } } @@ -1571,10 +1553,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void setInterfaceQuota(String iface, long quotaBytes) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - // silently discard when control disabled - // TODO: eventually migrate to be always enabled - if (!mBandwidthControlEnabled) return; - synchronized (mQuotaLock) { if (mActiveQuotas.containsKey(iface)) { throw new IllegalStateException("iface " + iface + " already has quota"); @@ -1582,10 +1560,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub try { // TODO: support quota shared across interfaces - mConnector.execute("bandwidth", "setiquota", iface, quotaBytes); + mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes); + mActiveQuotas.put(iface, quotaBytes); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } synchronized (mTetheringStatsProviders) { @@ -1605,10 +1584,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void removeInterfaceQuota(String iface) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - // silently discard when control disabled - // TODO: eventually migrate to be always enabled - if (!mBandwidthControlEnabled) return; - synchronized (mQuotaLock) { if (!mActiveQuotas.containsKey(iface)) { // TODO: eventually consider throwing @@ -1620,9 +1595,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub try { // TODO: support quota shared across interfaces - mConnector.execute("bandwidth", "removeiquota", iface); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + mNetdService.bandwidthRemoveInterfaceQuota(iface); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } synchronized (mTetheringStatsProviders) { @@ -1642,10 +1617,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void setInterfaceAlert(String iface, long alertBytes) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - // silently discard when control disabled - // TODO: eventually migrate to be always enabled - if (!mBandwidthControlEnabled) return; - // quick sanity check if (!mActiveQuotas.containsKey(iface)) { throw new IllegalStateException("setting alert requires existing quota on iface"); @@ -1658,10 +1629,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub try { // TODO: support alert shared across interfaces - mConnector.execute("bandwidth", "setinterfacealert", iface, alertBytes); + mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes); mActiveAlerts.put(iface, alertBytes); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } } @@ -1670,10 +1641,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void removeInterfaceAlert(String iface) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - // silently discard when control disabled - // TODO: eventually migrate to be always enabled - if (!mBandwidthControlEnabled) return; - synchronized (mQuotaLock) { if (!mActiveAlerts.containsKey(iface)) { // TODO: eventually consider throwing @@ -1682,10 +1649,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub try { // TODO: support alert shared across interfaces - mConnector.execute("bandwidth", "removeinterfacealert", iface); + mNetdService.bandwidthRemoveInterfaceAlert(iface); mActiveAlerts.remove(iface); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } } @@ -1694,27 +1661,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void setGlobalAlert(long alertBytes) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - // silently discard when control disabled - // TODO: eventually migrate to be always enabled - if (!mBandwidthControlEnabled) return; - try { - mConnector.execute("bandwidth", "setglobalalert", alertBytes); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + mNetdService.bandwidthSetGlobalAlert(alertBytes); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - // silently discard when control disabled - // TODO: eventually migrate to be always enabled - if (!mBandwidthControlEnabled) return; - - final String chain = blacklist ? "naughtyapps" : "niceapps"; - final String suffix = enable ? "add" : "remove"; - synchronized (mQuotaLock) { boolean oldEnable; SparseBooleanArray quotaList; @@ -1729,7 +1685,19 @@ public class NetworkManagementService extends INetworkManagementService.Stub Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth"); try { - mConnector.execute("bandwidth", suffix + chain, uid); + if (blacklist) { + if (enable) { + mNetdService.bandwidthAddNaughtyApp(uid); + } else { + mNetdService.bandwidthRemoveNaughtyApp(uid); + } + } else { + if (enable) { + mNetdService.bandwidthAddNiceApp(uid); + } else { + mNetdService.bandwidthRemoveNiceApp(uid); + } + } synchronized (mRulesLock) { if (enable) { quotaList.put(uid, true); @@ -1737,8 +1705,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub quotaList.delete(uid); } } - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); } @@ -1863,7 +1831,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public boolean isBandwidthControlEnabled() { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - return mBandwidthControlEnabled; + return true; } @Override @@ -2370,7 +2338,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub mConnector.dump(fd, pw, args); pw.println(); - pw.print("Bandwidth control enabled: "); pw.println(mBandwidthControlEnabled); pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio); pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio); pw.print("mNetworkActive="); pw.println(mNetworkActive); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 566ce4f48e25..0955beda1df5 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -99,6 +99,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { IPhoneStateListener callback; IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; + IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback; int callerUid; int callerPid; @@ -117,6 +118,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { return (onSubscriptionsChangedListenerCallback != null); } + boolean matchOnOpportunisticSubscriptionsChangedListener() { + return (onOpportunisticSubscriptionsChangedListenerCallback != null); + } + boolean canReadCallLog() { try { return TelephonyPermissions.checkReadCallLog( @@ -131,7 +136,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { return "{callingPackage=" + callingPackage + " binder=" + binder + " callback=" + callback + " onSubscriptionsChangedListenererCallback=" - + onSubscriptionsChangedListenerCallback + + onSubscriptionsChangedListenerCallback + + " onOpportunisticSubscriptionsChangedListenererCallback=" + + onOpportunisticSubscriptionsChangedListenerCallback + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + "}"; } @@ -147,7 +154,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private final AppOpsManager mAppOps; - private boolean hasNotifySubscriptionInfoChangedOccurred = false; + private boolean mHasNotifySubscriptionInfoChangedOccurred = false; + + private boolean mHasNotifyOpportunisticSubscriptionInfoChangedOccurred = false; private int mNumPhones; @@ -407,7 +416,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { log("listen oscl: Register r=" + r); } // Always notify when registration occurs if there has been a notification. - if (hasNotifySubscriptionInfoChangedOccurred) { + if (mHasNotifySubscriptionInfoChangedOccurred) { try { if (VDBG) log("listen oscl: send to r=" + r); r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); @@ -417,7 +426,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } else { - log("listen oscl: hasNotifySubscriptionInfoChangedOccurred==false no callback"); + log("listen oscl: mHasNotifySubscriptionInfoChangedOccurred==false no callback"); } } } @@ -429,15 +438,61 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(callback.asBinder()); } + + @Override + public void addOnOpportunisticSubscriptionsChangedListener(String callingPackage, + IOnSubscriptionsChangedListener callback) { + int callerUserId = UserHandle.getCallingUserId(); + mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); + if (VDBG) { + log("listen ooscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId() + + " callerUserId=" + callerUserId + " callback=" + callback + + " callback.asBinder=" + callback.asBinder()); + } + + synchronized (mRecords) { + // register + IBinder b = callback.asBinder(); + Record r = add(b); + + if (r == null) { + return; + } + + r.context = mContext; + r.onOpportunisticSubscriptionsChangedListenerCallback = callback; + r.callingPackage = callingPackage; + r.callerUid = Binder.getCallingUid(); + r.callerPid = Binder.getCallingPid(); + r.events = 0; + if (DBG) { + log("listen ooscl: Register r=" + r); + } + // Always notify when registration occurs if there has been a notification. + if (mHasNotifyOpportunisticSubscriptionInfoChangedOccurred) { + try { + if (VDBG) log("listen ooscl: send to r=" + r); + r.onOpportunisticSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); + if (VDBG) log("listen ooscl: sent to r=" + r); + } catch (RemoteException e) { + if (VDBG) log("listen ooscl: remote exception sending to r=" + r + " e=" + e); + remove(r.binder); + } + } else { + log("listen ooscl: hasNotifyOpptSubInfoChangedOccurred==false no callback"); + } + } + } + @Override public void notifySubscriptionInfoChanged() { if (VDBG) log("notifySubscriptionInfoChanged:"); synchronized (mRecords) { - if (!hasNotifySubscriptionInfoChangedOccurred) { + if (!mHasNotifySubscriptionInfoChangedOccurred) { log("notifySubscriptionInfoChanged: first invocation mRecords.size=" + mRecords.size()); } - hasNotifySubscriptionInfoChangedOccurred = true; + mHasNotifySubscriptionInfoChangedOccurred = true; mRemoveList.clear(); for (Record r : mRecords) { if (r.matchOnSubscriptionsChangedListener()) { @@ -456,6 +511,33 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override + public void notifyOpportunisticSubscriptionInfoChanged() { + if (VDBG) log("notifyOpptSubscriptionInfoChanged:"); + synchronized (mRecords) { + if (!mHasNotifyOpportunisticSubscriptionInfoChangedOccurred) { + log("notifyOpptSubscriptionInfoChanged: first invocation mRecords.size=" + + mRecords.size()); + } + mHasNotifyOpportunisticSubscriptionInfoChangedOccurred = true; + mRemoveList.clear(); + for (Record r : mRecords) { + if (r.matchOnOpportunisticSubscriptionsChangedListener()) { + try { + if (VDBG) log("notifyOpptSubChanged: call oosc to r=" + r); + r.onOpportunisticSubscriptionsChangedListenerCallback + .onSubscriptionsChanged(); + if (VDBG) log("notifyOpptSubChanged: done oosc to r=" + r); + } catch (RemoteException ex) { + if (VDBG) log("notifyOpptSubChanged: RemoteException r=" + r); + mRemoveList.add(r.binder); + } + } + } + handleRemoveListLocked(); + } + } + + @Override public void listen(String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow) { listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2447a03bc25f..9d0a8653178a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5886,6 +5886,7 @@ public class ActivityManagerService extends IActivityManager.Stub private final void handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart) { int pid = app.pid; + final boolean clearLaunchStartTime = !restarting && app.removed && app.foregroundActivities; boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1, false /*replacingPid*/); if (!kept && !restarting) { @@ -5926,6 +5927,19 @@ public class ActivityManagerService extends IActivityManager.Stub } finally { mWindowManager.continueSurfaceLayout(); } + + // TODO (b/67683350) + // When an app process is removed, activities from the process may be relaunched. In the + // case of forceStopPackageLocked the activities are finished before any window is drawn, + // and the launch time is not cleared. This will be incorrectly used to calculate launch + // time for the next launched activity launched in the same windowing mode. + if (clearLaunchStartTime) { + final LaunchTimeTracker.Entry entry = mStackSupervisor + .getLaunchTimeTracker().getEntry(mStackSupervisor.getWindowingMode()); + if (entry != null) { + entry.mLaunchStartTime = 0; + } + } } private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { @@ -21996,7 +22010,7 @@ public class ActivityManagerService extends IActivityManager.Stub activeInstr.mUiAutomationConnection = uiAutomationConnection; activeInstr.mResultClass = className; - boolean disableHiddenApiChecks = ai.usesNonSdkApi + boolean disableHiddenApiChecks = ai.usesNonSdkApi() || (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0; if (disableHiddenApiChecks) { enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS, diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index f082271ab094..350fb2f6c58a 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -537,8 +537,8 @@ public final class OverlayManagerService extends SystemService { @Override public boolean setEnabledExclusive(@Nullable final String packageName, final boolean enable, int userId) throws RemoteException { - enforceChangeOverlayPackagesPermission("setEnabled"); - userId = handleIncomingUser(userId, "setEnabled"); + enforceChangeOverlayPackagesPermission("setEnabledExclusive"); + userId = handleIncomingUser(userId, "setEnabledExclusive"); if (packageName == null || !enable) { return false; } @@ -557,8 +557,8 @@ public final class OverlayManagerService extends SystemService { @Override public boolean setEnabledExclusiveInCategory(@Nullable String packageName, int userId) throws RemoteException { - enforceChangeOverlayPackagesPermission("setEnabled"); - userId = handleIncomingUser(userId, "setEnabled"); + enforceChangeOverlayPackagesPermission("setEnabledExclusiveInCategory"); + userId = handleIncomingUser(userId, "setEnabledExclusiveInCategory"); if (packageName == null) { return false; } diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index 320affb1eee2..748cf08905bb 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -40,6 +40,7 @@ import java.io.File; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -124,7 +125,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { synchronized (mPackageManagerService.mPackages) { // Important: the packages we need to run with ab-ota compiler-reason. important = PackageManagerServiceUtils.getPackagesForDexopt( - mPackageManagerService.mPackages.values(), mPackageManagerService); + mPackageManagerService.mPackages.values(), mPackageManagerService, + DEBUG_DEXOPT); // Others: we should optimize this with the (first-)boot compiler-reason. others = new ArrayList<>(mPackageManagerService.mPackages.values()); others.removeAll(important); @@ -157,6 +159,24 @@ public class OtaDexoptService extends IOtaDexopt.Stub { long spaceAvailableNow = getAvailableSpace(); prepareMetricsLogging(important.size(), others.size(), spaceAvailable, spaceAvailableNow); + + if (DEBUG_DEXOPT) { + try { + // Output some data about the packages. + PackageParser.Package lastUsed = Collections.max(important, + (pkg1, pkg2) -> Long.compare( + pkg1.getLatestForegroundPackageUseTimeInMills(), + pkg2.getLatestForegroundPackageUseTimeInMills())); + Log.d(TAG, "A/B OTA: lastUsed time = " + + lastUsed.getLatestForegroundPackageUseTimeInMills()); + Log.d(TAG, "A/B OTA: deprioritized packages:"); + for (PackageParser.Package pkg : others) { + Log.d(TAG, " " + pkg.packageName + " - " + + pkg.getLatestForegroundPackageUseTimeInMills()); + } + } catch (Exception ignored) { + } + } } @Override diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java index 1aea8f0b0543..390c0ccb3c6e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java @@ -164,6 +164,13 @@ public class PackageManagerServiceUtils { public static List<PackageParser.Package> getPackagesForDexopt( Collection<PackageParser.Package> packages, PackageManagerService packageManagerService) { + return getPackagesForDexopt(packages, packageManagerService, DEBUG_DEXOPT); + } + + public static List<PackageParser.Package> getPackagesForDexopt( + Collection<PackageParser.Package> packages, + PackageManagerService packageManagerService, + boolean debug) { ArrayList<PackageParser.Package> remainingPkgs = new ArrayList<>(packages); LinkedList<PackageParser.Package> result = new LinkedList<>(); ArrayList<PackageParser.Package> sortTemp = new ArrayList<>(remainingPkgs.size()); @@ -189,14 +196,14 @@ public class PackageManagerServiceUtils { // TODO: add a property to control this? Predicate<PackageParser.Package> remainingPredicate; if (!remainingPkgs.isEmpty() && packageManagerService.isHistoricalPackageUsageAvailable()) { - if (DEBUG_DEXOPT) { + if (debug) { Log.i(TAG, "Looking at historical package use"); } // Get the package that was used last. PackageParser.Package lastUsed = Collections.max(remainingPkgs, (pkg1, pkg2) -> Long.compare(pkg1.getLatestForegroundPackageUseTimeInMills(), pkg2.getLatestForegroundPackageUseTimeInMills())); - if (DEBUG_DEXOPT) { + if (debug) { Log.i(TAG, "Taking package " + lastUsed.packageName + " as reference in time use"); } long estimatedPreviousSystemUseTime = @@ -218,7 +225,7 @@ public class PackageManagerServiceUtils { applyPackageFilter(remainingPredicate, result, remainingPkgs, sortTemp, packageManagerService); - if (DEBUG_DEXOPT) { + if (debug) { Log.i(TAG, "Packages to be dexopted: " + packagesToString(result)); Log.i(TAG, "Packages skipped from dexopt: " + packagesToString(remainingPkgs)); } diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java index 3cdef1e73ae4..0176dd496a33 100644 --- a/services/net/java/android/net/ip/IpClient.java +++ b/services/net/java/android/net/ip/IpClient.java @@ -228,6 +228,9 @@ public class IpClient extends StateMachine { // Encourages logging of any available arguments, and all call sites // are necessarily logged identically. // + // NOTE: Log first because passed objects may or may not be thread-safe and + // once passed on to the callback they may be modified by another thread. + // // TODO: Find an lighter weight approach. private class LoggingCallbackWrapper extends Callback { private static final String PREFIX = "INVOKE "; @@ -243,63 +246,63 @@ public class IpClient extends StateMachine { @Override public void onPreDhcpAction() { - mCallback.onPreDhcpAction(); log("onPreDhcpAction()"); + mCallback.onPreDhcpAction(); } @Override public void onPostDhcpAction() { - mCallback.onPostDhcpAction(); log("onPostDhcpAction()"); + mCallback.onPostDhcpAction(); } @Override public void onNewDhcpResults(DhcpResults dhcpResults) { - mCallback.onNewDhcpResults(dhcpResults); log("onNewDhcpResults({" + dhcpResults + "})"); + mCallback.onNewDhcpResults(dhcpResults); } @Override public void onProvisioningSuccess(LinkProperties newLp) { - mCallback.onProvisioningSuccess(newLp); log("onProvisioningSuccess({" + newLp + "})"); + mCallback.onProvisioningSuccess(newLp); } @Override public void onProvisioningFailure(LinkProperties newLp) { - mCallback.onProvisioningFailure(newLp); log("onProvisioningFailure({" + newLp + "})"); + mCallback.onProvisioningFailure(newLp); } @Override public void onLinkPropertiesChange(LinkProperties newLp) { - mCallback.onLinkPropertiesChange(newLp); log("onLinkPropertiesChange({" + newLp + "})"); + mCallback.onLinkPropertiesChange(newLp); } @Override public void onReachabilityLost(String logMsg) { - mCallback.onReachabilityLost(logMsg); log("onReachabilityLost(" + logMsg + ")"); + mCallback.onReachabilityLost(logMsg); } @Override public void onQuit() { - mCallback.onQuit(); log("onQuit()"); + mCallback.onQuit(); } @Override public void installPacketFilter(byte[] filter) { - mCallback.installPacketFilter(filter); log("installPacketFilter(byte[" + filter.length + "])"); + mCallback.installPacketFilter(filter); } @Override public void startReadPacketFilter() { - mCallback.startReadPacketFilter(); log("startReadPacketFilter()"); + mCallback.startReadPacketFilter(); } @Override public void setFallbackMulticastFilter(boolean enabled) { - mCallback.setFallbackMulticastFilter(enabled); log("setFallbackMulticastFilter(" + enabled + ")"); + mCallback.setFallbackMulticastFilter(enabled); } @Override public void setNeighborDiscoveryOffload(boolean enable) { - mCallback.setNeighborDiscoveryOffload(enable); log("setNeighborDiscoveryOffload(" + enable + ")"); + mCallback.setNeighborDiscoveryOffload(enable); } } @@ -1385,6 +1388,20 @@ public class IpClient extends StateMachine { private boolean startIpReachabilityMonitor() { try { + // TODO: Fetch these parameters from settings, and install a + // settings observer to watch for update and re-program these + // parameters (Q: is this level of dynamic updatability really + // necessary or does reading from settings at startup suffice?). + final int NUM_SOLICITS = 5; + final int INTER_SOLICIT_INTERVAL_MS = 750; + setNeighborParameters(mDependencies.getNetd(), mInterfaceName, + NUM_SOLICITS, INTER_SOLICIT_INTERVAL_MS); + } catch (Exception e) { + mLog.e("Failed to adjust neighbor parameters", e); + // Carry on using the system defaults (currently: 3, 1000); + } + + try { mIpReachabilityMonitor = new IpReachabilityMonitor( mContext, mInterfaceParams, @@ -1863,6 +1880,20 @@ public class IpClient extends StateMachine { } } + private static void setNeighborParameters( + INetd netd, String ifName, int num_solicits, int inter_solicit_interval_ms) + throws RemoteException, IllegalArgumentException { + Preconditions.checkNotNull(netd); + Preconditions.checkArgument(!TextUtils.isEmpty(ifName)); + Preconditions.checkArgument(num_solicits > 0); + Preconditions.checkArgument(inter_solicit_interval_ms > 0); + + for (int family : new Integer[]{INetd.IPV4, INetd.IPV6}) { + netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms", Integer.toString(inter_solicit_interval_ms)); + netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit", Integer.toString(num_solicits)); + } + } + // TODO: extract out into CollectionUtils. static <T> boolean any(Iterable<T> coll, Predicate<T> fn) { for (T t : coll) { diff --git a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java index 8fbc01ea4493..9d686efcb2ab 100644 --- a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java +++ b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java @@ -119,13 +119,23 @@ public class RouterAdvertisementDaemon { private volatile UnicastResponder mUnicastResponder; public static class RaParams { + // Tethered traffic will have the hop limit properly decremented. + // Consequently, set the hoplimit greater by one than the upstream + // unicast hop limit. + // + // TODO: Dynamically pass down the IPV6_UNICAST_HOPS value from the + // upstream interface for more correct behaviour. + static final byte DEFAULT_HOPLIMIT = 65; + public boolean hasDefaultRoute; + public byte hopLimit; public int mtu; public HashSet<IpPrefix> prefixes; public HashSet<Inet6Address> dnses; public RaParams() { hasDefaultRoute = false; + hopLimit = DEFAULT_HOPLIMIT; mtu = IPV6_MIN_MTU; prefixes = new HashSet<IpPrefix>(); dnses = new HashSet<Inet6Address>(); @@ -133,6 +143,7 @@ public class RouterAdvertisementDaemon { public RaParams(RaParams other) { hasDefaultRoute = other.hasDefaultRoute; + hopLimit = other.hopLimit; mtu = other.mtu; prefixes = (HashSet) other.prefixes.clone(); dnses = (HashSet) other.dnses.clone(); @@ -273,10 +284,12 @@ public class RouterAdvertisementDaemon { final ByteBuffer ra = ByteBuffer.wrap(mRA); ra.order(ByteOrder.BIG_ENDIAN); + final boolean haveRaParams = (mRaParams != null); boolean shouldSendRA = false; try { - putHeader(ra, mRaParams != null && mRaParams.hasDefaultRoute); + putHeader(ra, haveRaParams && mRaParams.hasDefaultRoute, + haveRaParams ? mRaParams.hopLimit : RaParams.DEFAULT_HOPLIMIT); putSlla(ra, mInterface.macAddr.toByteArray()); mRaLength = ra.position(); @@ -287,7 +300,7 @@ public class RouterAdvertisementDaemon { // // putExpandedFlagsOption(ra); - if (mRaParams != null) { + if (haveRaParams) { putMtu(ra, mRaParams.mtu); mRaLength = ra.position(); @@ -348,7 +361,7 @@ public class RouterAdvertisementDaemon { private static byte asByte(int value) { return (byte) value; } private static short asShort(int value) { return (short) value; } - private static void putHeader(ByteBuffer ra, boolean hasDefaultRoute) { + private static void putHeader(ByteBuffer ra, boolean hasDefaultRoute, byte hopLimit) { /** Router Advertisement Message Format @@ -366,11 +379,10 @@ public class RouterAdvertisementDaemon { | Options ... +-+-+-+-+-+-+-+-+-+-+-+- */ - final byte DEFAULT_HOPLIMIT = 64; ra.put(ICMPV6_ND_ROUTER_ADVERT) .put(asByte(0)) .putShort(asShort(0)) - .put(DEFAULT_HOPLIMIT) + .put(hopLimit) // RFC 4191 "high" preference, iff. advertising a default route. .put(hasDefaultRoute ? asByte(0x08) : asByte(0)) .putShort(hasDefaultRoute ? asShort(DEFAULT_LIFETIME) : asShort(0)) diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 119733e6a3d1..0c8280b9e086 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -19,6 +19,7 @@ package android.telephony; import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED; import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED; +import android.annotation.CallbackExecutor; import android.annotation.DurationMillisLong; import android.annotation.NonNull; import android.annotation.Nullable; @@ -47,6 +48,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.euicc.EuiccManager; import android.util.DisplayMetrics; +import android.util.Log; import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ISub; @@ -57,6 +59,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; /** @@ -666,7 +669,7 @@ public class SubscriptionManager { tr.addOnSubscriptionsChangedListener(pkgName, listener.callback); } } catch (RemoteException ex) { - // Should not happen + Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); } } @@ -684,7 +687,7 @@ public class SubscriptionManager { + " listener=" + listener); } try { - // We use the TelephonyRegistry as its runs in the system and thus is always + // We use the TelephonyRegistry as it runs in the system and thus is always // available where as SubscriptionController could crash and not be available ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry")); @@ -692,7 +695,116 @@ public class SubscriptionManager { tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); } } catch (RemoteException ex) { - // Should not happen + Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + } + } + + /** + * A listener class for monitoring changes to {@link SubscriptionInfo} records of opportunistic + * subscriptions. + * <p> + * Override the onOpportunisticSubscriptionsChanged method in the object that extends this + * or {@link #addOnOpportunisticSubscriptionsChangedListener( + * Executor, OnOpportunisticSubscriptionsChangedListener)} + * to register your listener and to unregister invoke + * {@link #removeOnOpportunisticSubscriptionsChangedListener( + * OnOpportunisticSubscriptionsChangedListener)} + * <p> + * Permissions android.Manifest.permission.READ_PHONE_STATE is required + * for #onOpportunisticSubscriptionsChanged to be invoked. + */ + public static class OnOpportunisticSubscriptionsChangedListener { + private Executor mExecutor; + /** + * Callback invoked when there is any change to any SubscriptionInfo. Typically + * this method would invoke {@link #getActiveSubscriptionInfoList} + */ + public void onOpportunisticSubscriptionsChanged() { + if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN"); + } + + private void setExecutor(Executor executor) { + mExecutor = executor; + } + + /** + * The callback methods need to be called on the handler thread where + * this object was created. If the binder did that for us it'd be nice. + */ + IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { + @Override + public void onSubscriptionsChanged() { + if (DBG) log("onOpportunisticSubscriptionsChanged callback received."); + mExecutor.execute(() -> onOpportunisticSubscriptionsChanged()); + } + }; + + private void log(String s) { + Rlog.d(LOG_TAG, s); + } + } + + /** + * Register for changes to the list of opportunistic subscription records or to the + * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged + * method of the listener will be invoked immediately if there has been a notification. + * + * @param listener an instance of {@link OnOpportunisticSubscriptionsChangedListener} with + * onOpportunisticSubscriptionsChanged overridden. + */ + public void addOnOpportunisticSubscriptionsChangedListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull OnOpportunisticSubscriptionsChangedListener listener) { + if (executor == null || listener == null) { + return; + } + + String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + if (DBG) { + logd("register addOnOpportunisticSubscriptionsChangedListener pkgName=" + pkgName + + " listener=" + listener); + } + + listener.setExecutor(executor); + + try { + // We use the TelephonyRegistry as it runs in the system and thus is always + // available. Where as SubscriptionController could crash and not be available + ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( + "telephony.registry")); + if (tr != null) { + tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback); + } + } catch (RemoteException ex) { + Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + } + } + + /** + * Unregister the {@link OnOpportunisticSubscriptionsChangedListener} that is currently + * listening opportunistic subscriptions change. This is not strictly necessary + * as the listener will automatically be unregistered if an attempt to invoke the listener + * fails. + * + * @param listener that is to be unregistered. + */ + public void removeOnOpportunisticSubscriptionsChangedListener( + OnOpportunisticSubscriptionsChangedListener listener) { + String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + if (DBG) { + logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug=" + + pkgForDebug + " listener=" + listener); + } + try { + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( + "telephony.registry")); + if (tr != null) { + tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); + } + } catch (RemoteException ex) { + Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); } } @@ -1177,6 +1289,15 @@ public class SubscriptionManager { } + /** + * Get an array of Subscription Ids for specified slot Index. + * @param slotIndex the slot Index. + * @return subscription Ids or null if the given slot Index is not valid. + */ + public static int[] getSubscriptionIds(int slotIndex) { + return getSubId(slotIndex); + } + /** @hide */ @UnsupportedAppUsage public static int[] getSubId(int slotIndex) { @@ -1468,12 +1589,14 @@ public class SubscriptionManager { } /** - * @return true if a valid subId else false - * @hide + * Checks if the supplied subscription ID is valid. + * Note: a valid subscription ID does not necessarily correspond to an active subscription. + * + * @param subscriptionId The subscription ID. + * @return true if the supplied subscriptionId is valid; false otherwise. */ - @UnsupportedAppUsage - public static boolean isValidSubscriptionId(int subId) { - return subId > INVALID_SUBSCRIPTION_ID ; + public static boolean isValidSubscriptionId(int subscriptionId) { + return subscriptionId > INVALID_SUBSCRIPTION_ID; } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e3c0b308a3d9..2cc175c395e0 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -134,6 +134,22 @@ public class TelephonyManager { static final int NEVER_USE = 2; } + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"NETWORK_SELECTION_MODE_"}, + value = { + NETWORK_SELECTION_MODE_UNKNOWN, + NETWORK_SELECTION_MODE_AUTO, + NETWORK_SELECTION_MODE_MANUAL}) + public @interface NetworkSelectionMode {} + + /** @hide */ + public static final int NETWORK_SELECTION_MODE_UNKNOWN = 0; + /** @hide */ + public static final int NETWORK_SELECTION_MODE_AUTO = 1; + /** @hide */ + public static final int NETWORK_SELECTION_MODE_MANUAL = 2; + /** The otaspMode passed to PhoneStateListener#onOtaspChanged */ /** @hide */ static public final int OTASP_UNINITIALIZED = 0; @@ -2862,9 +2878,11 @@ public class TelephonyManager { } /** - * Return if the current radio is LTE on CDMA. This - * is a tri-state return value as for a period of time - * the mode may be unknown. + * Return if the current radio is LTE on CDMA. This is a tri-state return value as for a period + * of time the mode may be unknown. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} * * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE} * or {@link PhoneConstants#LTE_ON_CDMA_TRUE} @@ -5699,6 +5717,9 @@ public class TelephonyManager { /** * Sets the network selection mode to automatic. * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). @@ -5721,27 +5742,36 @@ public class TelephonyManager { /** * Perform a radio scan and return the list of available networks. * - * The return value is a list of the OperatorInfo of the networks found. Note that this - * scan can take a long time (sometimes minutes) to happen. + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * + * <p> Note that this scan can take a long time (sometimes minutes) to happen. * * <p>Requires Permission: - * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling - * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier + * privileges (see {@link #hasCarrierPrivileges}) + * + * @return {@link CellNetworkScanResult} with the status + * {@link CellNetworkScanResult#STATUS_SUCCESS} and a list of + * {@link com.android.internal.telephony.OperatorInfo} if it's available. Otherwise, the failure + * caused will be included in the result. * * @hide - * TODO: Add an overload that takes no args. */ - public CellNetworkScanResult getCellNetworkScanResults(int subId) { + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public CellNetworkScanResult getAvailableNetworks() { try { ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.getCellNetworkScanResults(subId); + if (telephony != null) { + return telephony.getCellNetworkScanResults(getSubId()); + } } catch (RemoteException ex) { - Rlog.e(TAG, "getCellNetworkScanResults RemoteException", ex); + Rlog.e(TAG, "getAvailableNetworks RemoteException", ex); } catch (NullPointerException ex) { - Rlog.e(TAG, "getCellNetworkScanResults NPE", ex); + Rlog.e(TAG, "getAvailableNetworks NPE", ex); } - return null; + return new CellNetworkScanResult( + CellNetworkScanResult.STATUS_UNKNOWN_ERROR, null /* OperatorInfo */); } /** @@ -5791,6 +5821,9 @@ public class TelephonyManager { /** * Ask the radio to connect to the input network and change selection mode to manual. * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * * <p>Requires Permission: * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). @@ -5818,6 +5851,31 @@ public class TelephonyManager { return false; } + /** + * Get the network selection mode. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + + * @return the network selection mode. + * + * @hide + */ + @NetworkSelectionMode + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public int getNetworkSelectionMode() { + int mode = NETWORK_SELECTION_MODE_UNKNOWN; + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + mode = telephony.getNetworkSelectionMode(getSubId()); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getNetworkSelectionMode RemoteException", ex); + } + return mode; + } + /** * Set the preferred network type. * Used for device configuration by some CDMA operators. @@ -6732,6 +6790,84 @@ public class TelephonyManager { } /** + * Gets the roaming mode for CDMA phone. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * + * @return one of {@link #CDMA_ROAMING_MODE_RADIO_DEFAULT}, {@link #CDMA_ROAMING_MODE_HOME}, + * {@link #CDMA_ROAMING_MODE_AFFILIATED}, {@link #CDMA_ROAMING_MODE_ANY}. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public int getCdmaRoamingMode() { + int mode = CDMA_ROAMING_MODE_RADIO_DEFAULT; + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + mode = telephony.getCdmaRoamingMode(getSubId()); + } + } catch (RemoteException ex) { + Log.e(TAG, "Error calling ITelephony#getCdmaRoamingMode", ex); + } + return mode; + } + + /** + * Sets the roaming mode for CDMA phone to the given mode {@code mode}. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * + * @param mode should be one of {@link #CDMA_ROAMING_MODE_RADIO_DEFAULT}, + * {@link #CDMA_ROAMING_MODE_HOME}, {@link #CDMA_ROAMING_MODE_AFFILIATED}, + * {@link #CDMA_ROAMING_MODE_ANY}. + * + * @return {@code true} if successed. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public boolean setCdmaRoamingMode(int mode) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.setCdmaRoamingMode(getSubId(), mode); + } + } catch (RemoteException ex) { + Log.e(TAG, "Error calling ITelephony#setCdmaRoamingMode", ex); + } + return false; + } + + /** + * Sets the subscription mode for CDMA phone to the given mode {@code mode}. + * + * @param mode CDMA subscription mode + * + * @return {@code true} if successed. + * + * @see Phone#CDMA_SUBSCRIPTION_UNKNOWN + * @see Phone#CDMA_SUBSCRIPTION_RUIM_SIM + * @see Phone#CDMA_SUBSCRIPTION_NV + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public boolean setCdmaSubscriptionMode(int mode) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.setCdmaSubscriptionMode(getSubId(), mode); + } + } catch (RemoteException ex) { + Log.e(TAG, "Error calling ITelephony#setCdmaSubscriptionMode", ex); + } + return false; + } + + /** * Enables/Disables the data roaming on the subscription. * * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the @@ -7543,6 +7679,9 @@ public class TelephonyManager { /** * Returns the current {@link ServiceState} information. * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). */ @@ -8010,8 +8149,12 @@ public class TelephonyManager { } /** - * Check if phone is in emergency callback mode - * @return true if phone is in emergency callback mode + * Checks if phone is in emergency callback mode. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * + * @return true if phone is in emergency callback mode. * @hide */ @SystemApi diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index b4f3487a5f63..066db1fca140 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1536,6 +1536,34 @@ interface ITelephony { void setDataRoamingEnabled(int subId, boolean isEnabled); /** + * Gets the roaming mode for the CDMA phone with the subscription id {@code subId}. + * + * @param the subscription id. + * @return the roaming mode for CDMA phone. + */ + int getCdmaRoamingMode(int subId); + + /** + * Sets the roaming mode on the CDMA phone with the subscription {@code subId} to the given + * roaming mode {@code mode}. + * + * @param subId the subscription id. + * @param mode the roaming mode should be set. + * @return {@code true} if successed. + */ + boolean setCdmaRoamingMode(int subId, int mode); + + /** + * Sets the subscription mode for CDMA phone with the subscription {@code subId} to the given + * subscription mode {@code mode}. + * + * @param subId the subscription id. + * @param mode the subscription mode should be set. + * @return {@code true} if successed. + */ + boolean setCdmaSubscriptionMode(int subId, int mode); + + /** * A test API to override carrier information including mccmnc, imsi, iccid, gid1, gid2, * plmn and spn. This would be handy for, eg, forcing a particular carrier id, carrier's config * (also any country or carrier overlays) to be loaded when using a test SIM with a call box. @@ -1559,4 +1587,9 @@ interface ITelephony { * @hide */ int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage); + + /** + * Return the network selection mode on the subscription with id {@code subId}. + */ + int getNetworkSelectionMode(int subId); } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index e0e1a7b87916..43d56b39e0c4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -32,6 +32,8 @@ import com.android.internal.telephony.IOnSubscriptionsChangedListener; interface ITelephonyRegistry { void addOnSubscriptionsChangedListener(String pkg, IOnSubscriptionsChangedListener callback); + void addOnOpportunisticSubscriptionsChangedListener(String pkg, + IOnSubscriptionsChangedListener callback); void removeOnSubscriptionsChangedListener(String pkg, IOnSubscriptionsChangedListener callback); void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); @@ -73,6 +75,7 @@ interface ITelephonyRegistry { int activationState, int activationType); void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData); void notifySubscriptionInfoChanged(); + void notifyOpportunisticSubscriptionInfoChanged(); void notifyCarrierNetworkChange(in boolean active); void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state); void notifyPhoneCapabilityChanged(in PhoneCapability capability); diff --git a/test-base/Android.bp b/test-base/Android.bp index d25b47727c0b..0b8a02a815d9 100644 --- a/test-base/Android.bp +++ b/test-base/Android.bp @@ -19,9 +19,8 @@ // This contains the junit.framework and android.test classes that were in // Android API level 25 excluding those from android.test.runner. // Also contains the com.android.internal.util.Predicate[s] classes. -java_library { +java_sdk_library { name: "android.test.base", - installable: true, srcs: ["src/**/*.java"], @@ -29,11 +28,38 @@ java_library { javacflags: ["-Xep:DepAnn:ERROR"], }, + hostdex: true, + + api_packages: [ + "android.test", + "android.test.suitebuilder.annotation", + "com.android.internal.util", + "junit.framework", + ], + + droiddoc_options: ["stubsourceonly"], + compile_dex: true, +} + +// Build the android.test.base_static library +// ========================================== +// This is only intended for inclusion in the android.test.runner-minus-junit, +// robolectric_android-all-stub and repackaged.android.test.* libraries. +// Must not be used elewhere. +java_library_static { + name: "android.test.base_static", + installable: false, + + srcs: ["src/**/*.java"], + + errorprone: { + javacflags: ["-Xep:DepAnn:ERROR"], + }, + // Needs to be consistent with the repackaged version of this make target. java_version: "1.8", sdk_version: "current", - hostdex: true, } // Build the legacy-test library @@ -46,7 +72,7 @@ java_library { installable: true, sdk_version: "current", - static_libs: ["android.test.base"], + static_libs: ["android.test.base_static"], } // Build the repackaged.android.test.base library @@ -57,7 +83,7 @@ java_library_static { name: "repackaged.android.test.base", sdk_version: "current", - static_libs: ["android.test.base"], + static_libs: ["android.test.base_static"], jarjar_rules: "jarjar-rules.txt", // Pin java_version until jarjar is certified to support later versions. http://b/72703434 @@ -84,38 +110,3 @@ java_library_static { ], } -droiddoc { - name: "android-test-base-api-stubs-gen-docs", - srcs: [ - "src/**/*.java", - ], - custom_template: "droiddoc-templates-sdk", - installable: false, - args: "-stubpackages android.test:" + - "android.test.suitebuilder.annotation:" + - "com.android.internal.util:" + - "junit.framework -stubsourceonly -nodocs", - sdk_version: "current", - api_tag_name: "ANDROID_TEST_BASE", - api_filename: "android-test-base-api.txt", - removed_api_filename: "android-test-base-removed.txt", -} - -// Build the android.test.base.stubs library -// ========================================= -java_library_static { - name: "android.test.base.stubs", - srcs: [ - ":android-test-base-api-stubs-gen-docs", - ], - product_variables: { - pdk: { - enabled: false, - }, - unbundled_build: { - enabled: false, - }, - }, - sdk_version: "current", - compile_dex: true, -} diff --git a/test-base/Android.mk b/test-base/Android.mk index baf5726ff8bd..a9d30cf3131a 100644 --- a/test-base/Android.mk +++ b/test-base/Android.mk @@ -16,50 +16,6 @@ LOCAL_PATH:= $(call my-dir) -# For unbundled build we'll use the prebuilt jar from prebuilts/sdk. -ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) - -ANDROID_TEST_BASE_API_FILE := $(LOCAL_PATH)/api/android-test-base-current.txt -ANDROID_TEST_BASE_REMOVED_API_FILE := $(LOCAL_PATH)/api/android-test-base-removed.txt - -full_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,android.test.base.stubs,,COMMON)/classes.jar -# Archive a copy of the classes.jar in SDK build. -$(call dist-for-goals,sdk win_sdk,$(full_classes_jar):android.test.base.stubs.jar) - -# Check that the android.test.base.stubs library has not changed -# ============================================================== - -# Check that the API we're building hasn't changed from the not-yet-released -# SDK version. -$(eval $(call check-api, \ - check-android-test-base-api-current, \ - $(ANDROID_TEST_BASE_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_BASE_API_FILE), \ - $(ANDROID_TEST_BASE_REMOVED_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_BASE_REMOVED_API_FILE), \ - -error 2 -error 3 -error 4 -error 5 -error 6 \ - -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ - -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \ - -error 25 -error 26 -error 27, \ - cat $(LOCAL_PATH)/api/apicheck_msg_android_test_base.txt, \ - check-android-test-base-api, \ - $(OUT_DOCS)/android-test-base-api-stubs-gen-docs-stubs.srcjar \ - )) - -.PHONY: check-android-test-base-api -checkapi: check-android-test-base-api - -.PHONY: update-android-test-base-api -update-api: update-android-test-base-api - -update-android-test-base-api: $(INTERNAL_PLATFORM_ANDROID_TEST_BASE_API_FILE) | $(ACP) - @echo Copying current.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_BASE_API_FILE) $(ANDROID_TEST_BASE_API_FILE) - @echo Copying removed.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_BASE_REMOVED_API_FILE) $(ANDROID_TEST_BASE_REMOVED_API_FILE) - -endif # not TARGET_BUILD_APPS not TARGET_BUILD_PDK=true - ifeq ($(HOST_OS),linux) # Build the legacy-performance-test-hostdex library # ================================================= diff --git a/test-base/api/apicheck_msg_android_test_base.txt b/test-base/api/apicheck_msg_android_test_base.txt deleted file mode 100644 index 144aecc21bce..000000000000 --- a/test-base/api/apicheck_msg_android_test_base.txt +++ /dev/null @@ -1,17 +0,0 @@ - -****************************** -You have tried to change the API from what has been previously approved. - -To make these errors go away, you have two choices: - 1) You can add "@hide" javadoc comments to the methods, etc. listed in the - errors above. - - 2) You can update android-test-base-current.txt by executing the following command: - make update-android-test-base-api - - To submit the revised android-test-base-current.txt to the main Android repository, - you will need approval. -****************************** - - - diff --git a/test-base/api/android-test-base-current.txt b/test-base/api/current.txt index 7ebd6aa8a4a2..7ebd6aa8a4a2 100644 --- a/test-base/api/android-test-base-current.txt +++ b/test-base/api/current.txt diff --git a/test-base/api/android-test-base-removed.txt b/test-base/api/removed.txt index e69de29bb2d1..e69de29bb2d1 100644 --- a/test-base/api/android-test-base-removed.txt +++ b/test-base/api/removed.txt diff --git a/test-mock/api/android-test-mock-system-removed.txt b/test-base/api/system-current.txt index e69de29bb2d1..e69de29bb2d1 100644 --- a/test-mock/api/android-test-mock-system-removed.txt +++ b/test-base/api/system-current.txt diff --git a/test-runner/api/android-test-runner-removed.txt b/test-base/api/system-removed.txt index e69de29bb2d1..e69de29bb2d1 100644 --- a/test-runner/api/android-test-runner-removed.txt +++ b/test-base/api/system-removed.txt diff --git a/test-base/api/test-current.txt b/test-base/api/test-current.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-base/api/test-current.txt diff --git a/test-base/api/test-removed.txt b/test-base/api/test-removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-base/api/test-removed.txt diff --git a/test-legacy/Android.bp b/test-legacy/Android.bp index d2af8a9f1c82..833c714f07b0 100644 --- a/test-legacy/Android.bp +++ b/test-legacy/Android.bp @@ -25,7 +25,7 @@ java_library_static { static_libs: [ "android.test.base-minus-junit", "android.test.runner-minus-junit", - "android.test.mock", + "android.test.mock.impl", ], no_framework_libs: true, diff --git a/test-mock/Android.bp b/test-mock/Android.bp index 8d3faaef9f6b..5eba01779f46 100644 --- a/test-mock/Android.bp +++ b/test-mock/Android.bp @@ -16,95 +16,15 @@ // Build the android.test.mock library // =================================== -java_library { +java_sdk_library { name: "android.test.mock", - installable: true, - java_version: "1.8", srcs: ["src/**/*.java"], - no_framework_libs: true, - libs: [ - "framework", + api_packages: [ + "android.test.mock", ], -} - -doc_defaults { - name:"android.test.mock.docs-defaults", - srcs: ["src/android/test/mock/**/*.java"], - // Includes the main framework source to ensure that doclava has access to the - // visibility information for the base classes of the mock classes. Without it - // otherwise hidden methods could be visible. - srcs_lib: "framework", - srcs_lib_whitelist_dirs: ["core/java"], srcs_lib_whitelist_pkgs: ["android"], - libs: [ - "core-oj", - "core-libart", - "framework", - "conscrypt", - "okhttp", - "bouncycastle", - "ext", - ], - local_sourcepaths: ["src/android/test/mock"], - custom_template: "droiddoc-templates-sdk", - installable: false, -} - -android_test_mock_docs_args = - "-hide 110 -hide 111 -hide 113 -hide 121 -hide 125 -hide 126 -hide 127 -hide 128 " + - "-stubpackages android.test.mock " + - "-nodocs " - -droiddoc { - name: "android.test.mock.docs", - defaults: ["android.test.mock.docs-defaults"], - - api_tag_name: "ANDROID_TEST_MOCK", - api_filename: "api/android-test-mock-current.txt", - removed_api_filename: "api/android-test-mock-removed.txt", - - args: android_test_mock_docs_args, -} - -droiddoc { - name: "android.test.mock.docs-system", - defaults: ["android.test.mock.docs-defaults"], - - api_tag_name: "ANDROID_TEST_MOCK_SYSTEM", - api_filename: "api/android-test-mock-system-current.txt", - removed_api_filename: "api/android-test-mock-system-removed.txt", - - args: android_test_mock_docs_args + - "-showAnnotation android.annotation.SystemApi ", -} - -java_library_static { - name: "android.test.mock.stubs", - srcs: [":android.test.mock.docs"], - sdk_version: "current", - product_variables: { - unbundled_build: { - // Unbundled apps will use the prebuilt one - // prebuilts/sdk/current - enabled: false, - }, - }, - compile_dex: true, -} - -java_library_static { - name: "android.test.mock.stubs-system", - srcs: [":android.test.mock.docs-system"], - sdk_version: "system_current", - product_variables: { - unbundled_build: { - // Unbundled apps will use the prebuilt one - // prebuilts/sdk/system_current - enabled: false, - }, - }, compile_dex: true, } diff --git a/test-mock/Android.mk b/test-mock/Android.mk deleted file mode 100644 index 73a7340826a6..000000000000 --- a/test-mock/Android.mk +++ /dev/null @@ -1,93 +0,0 @@ -# -# Copyright (C) 2008 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. -# - -LOCAL_PATH:= $(call my-dir) - -# Archive a copy of the classes.jar in SDK build. -full_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,android.test.mock.stubs,,COMMON)/classes.jar -$(call dist-for-goals,sdk win_sdk,$(full_classes_jar):android.test.mock.stubs.jar) - -# Check that the android.test.mock.stubs library has not changed -# ============================================================== -ANDROID_TEST_MOCK_API_FILE := $(LOCAL_PATH)/api/android-test-mock-current.txt -ANDROID_TEST_MOCK_REMOVED_API_FILE := $(LOCAL_PATH)/api/android-test-mock-removed.txt - -# Check that the API we're building hasn't changed from the not-yet-released -# SDK version. -$(eval $(call check-api, \ - check-android-test-mock-api-current, \ - $(ANDROID_TEST_MOCK_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_API_FILE), \ - $(ANDROID_TEST_MOCK_REMOVED_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_REMOVED_API_FILE), \ - -error 2 -error 3 -error 4 -error 5 -error 6 \ - -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ - -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \ - -error 25 -error 26 -error 27, \ - cat $(LOCAL_PATH)/api/apicheck_msg_android_test_mock.txt, \ - check-android-test-mock-api, \ - $(OUT_DOCS)/android.test.mock.docs-stubs.srcjar \ - )) - -.PHONY: check-android-test-mock-api -checkapi: check-android-test-mock-api - -.PHONY: update-android-test-mock-api -update-api: update-android-test-mock-api - -update-android-test-mock-api: $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_API_FILE) | $(ACP) - @echo Copying current.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_API_FILE) $(ANDROID_TEST_MOCK_API_FILE) - @echo Copying removed.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_REMOVED_API_FILE) $(ANDROID_TEST_MOCK_REMOVED_API_FILE) - -# Archive a copy of the classes.jar in SDK build. -full_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,android.test.mock.stubs-system,,COMMON)/classes.jar -$(call dist-for-goals,sdk win_sdk,$(full_classes_jar):android.test.mock.stubs_system.jar) - -# Check that the android.test.mock.stubs-system library has not changed -# ===================================================================== -ANDROID_TEST_MOCK_SYSTEM_API_FILE := $(LOCAL_PATH)/api/android-test-mock-system-current.txt -ANDROID_TEST_MOCK_SYSTEM_REMOVED_API_FILE := $(LOCAL_PATH)/api/android-test-mock-system-removed.txt - -# Check that the API we're building hasn't changed from the not-yet-released -# SDK version. -$(eval $(call check-api, \ - check-android-test-mock-system-api-current, \ - $(ANDROID_TEST_MOCK_SYSTEM_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_SYSTEM_API_FILE), \ - $(ANDROID_TEST_MOCK_SYSTEM_REMOVED_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_SYSTEM_REMOVED_API_FILE), \ - -error 2 -error 3 -error 4 -error 5 -error 6 \ - -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ - -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \ - -error 25 -error 26 -error 27, \ - cat $(LOCAL_PATH)/api/apicheck_msg_android_test_mock-system.txt, \ - check-android-test-mock-system-api, \ - $(OUT_DOCS)/android.test.mock.docs-system-stubs.srcjar \ - )) - -.PHONY: check-android-test-mock-system-api -checkapi: check-android-test-mock-system-api - -.PHONY: update-android-test-mock-system-api -update-api: update-android-test-mock-system-api - -update-android-test-mock-system-api: $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_SYSTEM_API_FILE) | $(ACP) - @echo Copying current.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_SYSTEM_API_FILE) $(ANDROID_TEST_MOCK_SYSTEM_API_FILE) - @echo Copying removed.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_MOCK_SYSTEM_REMOVED_API_FILE) $(ANDROID_TEST_MOCK_SYSTEM_REMOVED_API_FILE) diff --git a/test-mock/api/apicheck_msg_android_test_mock-system.txt b/test-mock/api/apicheck_msg_android_test_mock-system.txt deleted file mode 100644 index 3a97117f3ea1..000000000000 --- a/test-mock/api/apicheck_msg_android_test_mock-system.txt +++ /dev/null @@ -1,17 +0,0 @@ - -****************************** -You have tried to change the API from what has been previously approved. - -To make these errors go away, you have two choices: - 1) You can add "@hide" javadoc comments to the methods, etc. listed in the - errors above. - - 2) You can update android-test-mock-current.txt by executing the following command: - make update-android-test-mock-system-api - - To submit the revised android-test-mock-system-current.txt to the main Android repository, - you will need approval. -****************************** - - - diff --git a/test-mock/api/apicheck_msg_android_test_mock.txt b/test-mock/api/apicheck_msg_android_test_mock.txt deleted file mode 100644 index e388935bf798..000000000000 --- a/test-mock/api/apicheck_msg_android_test_mock.txt +++ /dev/null @@ -1,17 +0,0 @@ - -****************************** -You have tried to change the API from what has been previously approved. - -To make these errors go away, you have two choices: - 1) You can add "@hide" javadoc comments to the methods, etc. listed in the - errors above. - - 2) You can update android-test-mock-current.txt by executing the following command: - make update-android-test-mock-api - - To submit the revised android-test-mock-current.txt to the main Android repository, - you will need approval. -****************************** - - - diff --git a/test-mock/api/android-test-mock-current.txt b/test-mock/api/current.txt index f3b253c0f460..f3b253c0f460 100644 --- a/test-mock/api/android-test-mock-current.txt +++ b/test-mock/api/current.txt diff --git a/test-mock/api/android-test-mock-removed.txt b/test-mock/api/removed.txt index bd109a887933..bd109a887933 100644 --- a/test-mock/api/android-test-mock-removed.txt +++ b/test-mock/api/removed.txt diff --git a/test-mock/api/android-test-mock-system-current.txt b/test-mock/api/system-current.txt index 20401a50b6a2..20401a50b6a2 100644 --- a/test-mock/api/android-test-mock-system-current.txt +++ b/test-mock/api/system-current.txt diff --git a/test-mock/api/system-removed.txt b/test-mock/api/system-removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-mock/api/system-removed.txt diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt new file mode 100644 index 000000000000..725ea935896f --- /dev/null +++ b/test-mock/api/test-current.txt @@ -0,0 +1,16 @@ +package android.test.mock { + + public deprecated class MockPackageManager extends android.content.pm.PackageManager { + method public java.lang.String getDefaultBrowserPackageNameAsUser(int); + method public int getInstallReason(java.lang.String, android.os.UserHandle); + method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); + method public java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); + method public java.lang.String[] getNamesForUids(int[]); + method public java.lang.String getPermissionControllerPackageName(); + method public java.lang.String getServicesSystemSharedLibraryPackageName(); + method public java.lang.String getSharedSystemSharedLibraryPackageName(); + method public boolean isPermissionReviewModeEnabled(); + } + +} + diff --git a/test-mock/api/test-removed.txt b/test-mock/api/test-removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-mock/api/test-removed.txt diff --git a/test-runner/Android.bp b/test-runner/Android.bp index 2caa6c45f16b..ea615b920df6 100644 --- a/test-runner/Android.bp +++ b/test-runner/Android.bp @@ -16,23 +16,32 @@ // Build the android.test.runner library // ===================================== -java_library { +java_sdk_library { name: "android.test.runner", - installable: true, - // Needs to be consistent with the repackaged version of this make target. - java_version: "1.8", srcs: ["src/**/*.java"], errorprone: { javacflags: ["-Xep:DepAnn:ERROR"], }, - sdk_version: "current", libs: [ "android.test.base", - "android.test.mock.stubs", + "android.test.mock", + ], + stub_only_libs: [ + "android.test.base", + "android.test.mock", ], + api_packages: [ + "android.test", + "android.test.suitebuilder", + "junit.runner", + "junit.textui", + ], + + droiddoc_options: ["stubsourceonly"], + compile_dex: true } // Build the android.test.runner-minus-junit library @@ -46,8 +55,8 @@ java_library { sdk_version: "current", libs: [ - "android.test.base", - "android.test.mock.stubs", + "android.test.base_static", + "android.test.mock", "junit", ], } @@ -70,7 +79,7 @@ java_library_static { sdk_version: "current", libs: [ - "android.test.base", + "android.test.base_static", ], jarjar_rules: "jarjar-rules.txt", @@ -78,48 +87,3 @@ java_library_static { java_version: "1.8", } -droiddoc { - name: "android-test-runner-api-stubs-gen-docs", - srcs: [ - "src/**/*.java", - ], - libs: [ - "core-oj", - "core-libart", - "framework", - "android.test.base", - "android.test.mock", - ], - custom_template: "droiddoc-templates-sdk", - installable: false, - args: "-stubpackages android.test:" + - "android.test.suitebuilder:" + - "junit.runner:" + - "junit.textui -stubsourceonly -nodocs", - api_tag_name: "ANDROID_TEST_RUNNER", - api_filename: "android-test-runner-current.txt", - removed_api_filename: "android-test-runner-removed.txt", -} - -// Build the android.test.runner.stubs library -// ========================================= -java_library_static { - name: "android.test.runner.stubs", - srcs: [ - ":android-test-runner-api-stubs-gen-docs", - ], - libs: [ - "android.test.base.stubs", - "android.test.mock.stubs", - ], - product_variables: { - pdk: { - enabled: false, - }, - unbundled_build: { - enabled: false, - }, - }, - sdk_version: "current", - compile_dex: true, -} diff --git a/test-runner/Android.mk b/test-runner/Android.mk index b70d2498d491..18bde8517351 100644 --- a/test-runner/Android.mk +++ b/test-runner/Android.mk @@ -16,49 +16,5 @@ LOCAL_PATH:= $(call my-dir) -# For unbundled build we'll use the prebuilt jar from prebuilts/sdk. -ifeq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) - -ANDROID_TEST_RUNNER_API_FILE := $(LOCAL_PATH)/api/android-test-runner-current.txt -ANDROID_TEST_RUNNER_REMOVED_API_FILE := $(LOCAL_PATH)/api/android-test-runner-removed.txt - -full_classes_jar := $(call intermediates-dir-for,JAVA_LIBRARIES,android.test.runner.stubs,,COMMON)/classes.jar -# Archive a copy of the classes.jar in SDK build. -$(call dist-for-goals,sdk win_sdk,$(full_classes_jar):android.test.runner.stubs.jar) - -# Check that the android.test.runner.stubs library has not changed -# ================================================================ - -# Check that the API we're building hasn't changed from the not-yet-released -# SDK version. -$(eval $(call check-api, \ - check-android-test-runner-api-current, \ - $(ANDROID_TEST_RUNNER_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_RUNNER_API_FILE), \ - $(ANDROID_TEST_RUNNER_REMOVED_API_FILE), \ - $(INTERNAL_PLATFORM_ANDROID_TEST_RUNNER_REMOVED_API_FILE), \ - -error 2 -error 3 -error 4 -error 5 -error 6 \ - -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \ - -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \ - -error 25 -error 26 -error 27, \ - cat $(LOCAL_PATH)/api/apicheck_msg_android_test_runner.txt, \ - check-android-test-runner-api, \ - $(OUT_DOCS)/android-test-runner-api-stubs-gen-docs-stubs.srcjar \ - )) - -.PHONY: check-android-test-runner-api -checkapi: check-android-test-runner-api - -.PHONY: update-android-test-runner-api -update-api: update-android-test-runner-api - -update-android-test-runner-api: $(INTERNAL_PLATFORM_ANDROID_TEST_RUNNER_API_FILE) | $(ACP) - @echo Copying current.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_RUNNER_API_FILE) $(ANDROID_TEST_RUNNER_API_FILE) - @echo Copying removed.txt - $(hide) $(ACP) $(INTERNAL_PLATFORM_ANDROID_TEST_RUNNER_REMOVED_API_FILE) $(ANDROID_TEST_RUNNER_REMOVED_API_FILE) - -endif # not TARGET_BUILD_APPS not TARGET_BUILD_PDK=true - # additionally, build unit tests in a separate .apk include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/test-runner/api/apicheck_msg_android_test_runner.txt b/test-runner/api/apicheck_msg_android_test_runner.txt deleted file mode 100644 index cf2d15ee1ee1..000000000000 --- a/test-runner/api/apicheck_msg_android_test_runner.txt +++ /dev/null @@ -1,17 +0,0 @@ - -****************************** -You have tried to change the API from what has been previously approved. - -To make these errors go away, you have two choices: - 1) You can add "@hide" javadoc comments to the methods, etc. listed in the - errors above. - - 2) You can update android-test-runner-current.txt by executing the following command: - make update-android-test-runner-api - - To submit the revised android-test-runner-current.txt to the main Android repository, - you will need approval. -****************************** - - - diff --git a/test-runner/api/android-test-runner-current.txt b/test-runner/api/current.txt index 1170eb53ab7f..1170eb53ab7f 100644 --- a/test-runner/api/android-test-runner-current.txt +++ b/test-runner/api/current.txt diff --git a/test-runner/api/removed.txt b/test-runner/api/removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-runner/api/removed.txt diff --git a/test-runner/api/system-current.txt b/test-runner/api/system-current.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-runner/api/system-current.txt diff --git a/test-runner/api/system-removed.txt b/test-runner/api/system-removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-runner/api/system-removed.txt diff --git a/test-runner/api/test-current.txt b/test-runner/api/test-current.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-runner/api/test-current.txt diff --git a/test-runner/api/test-removed.txt b/test-runner/api/test-removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test-runner/api/test-removed.txt diff --git a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java index 918873bf0bdd..d9bb7db17685 100644 --- a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java +++ b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java @@ -28,6 +28,7 @@ import org.mockito.internal.stubbing.StubberImpl; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.mockito.stubbing.Stubber; +import org.mockito.quality.Strictness; import junit.framework.Assert; import java.util.Locale; @@ -210,12 +211,16 @@ public class TextToSpeechTests extends InstrumentationTestCase { } public static abstract class CountDownBehaviour extends StubberImpl { + public CountDownBehaviour(Strictness strictness) { + super(strictness); + } + /** Used to mock methods that return a result. */ public abstract Stubber andReturn(Object result); } public static CountDownBehaviour doCountDown(final CountDownLatch latch) { - return new CountDownBehaviour() { + return new CountDownBehaviour(Strictness.WARN) { @Override public <T> T when(T mock) { return Mockito.doAnswer(new Answer<Void>() { @@ -229,7 +234,7 @@ public class TextToSpeechTests extends InstrumentationTestCase { @Override public Stubber andReturn(final Object result) { - return new StubberImpl() { + return new StubberImpl(Strictness.WARN) { @Override public <T> T when(T mock) { return Mockito.doAnswer(new Answer<Object>() { diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java index 102cb7c77055..99a5a69213fa 100644 --- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java +++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java @@ -41,9 +41,9 @@ import android.net.Network; import android.net.NetworkUtils; import android.os.Binder; import android.os.ParcelFileDescriptor; -import android.test.mock.MockContext; import android.support.test.filters.SmallTest; import android.system.Os; +import android.test.mock.MockContext; import java.net.Socket; import java.util.Arrays; @@ -121,6 +121,7 @@ public class IpSecServiceParameterizedTest { IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig; IpSecService mIpSecService; Network fakeNetwork = new Network(0xAB); + int mUid = Os.getuid(); private static final IpSecAlgorithm AUTH_ALGO = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4); @@ -181,7 +182,7 @@ public class IpSecServiceParameterizedTest { verify(mMockNetd) .ipSecDeleteSecurityAssociation( - eq(spiResp.resourceId), + eq(mUid), anyString(), anyString(), eq(TEST_SPI), @@ -189,8 +190,7 @@ public class IpSecServiceParameterizedTest { anyInt()); // Verify quota and RefcountedResource objects cleaned up - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent); try { userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); @@ -209,8 +209,7 @@ public class IpSecServiceParameterizedTest { mIpSecService.allocateSecurityParameterIndex( mDestinationAddr, TEST_SPI, new Binder()); - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); IpSecService.RefcountedResource refcountedRecord = userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId); @@ -218,7 +217,7 @@ public class IpSecServiceParameterizedTest { verify(mMockNetd) .ipSecDeleteSecurityAssociation( - eq(spiResp.resourceId), + eq(mUid), anyString(), anyString(), eq(TEST_SPI), @@ -270,7 +269,7 @@ public class IpSecServiceParameterizedTest { verify(mMockNetd) .ipSecAddSecurityAssociation( - eq(createTransformResp.resourceId), + eq(mUid), anyInt(), anyString(), anyString(), @@ -305,7 +304,7 @@ public class IpSecServiceParameterizedTest { verify(mMockNetd) .ipSecAddSecurityAssociation( - eq(createTransformResp.resourceId), + eq(mUid), anyInt(), anyString(), anyString(), @@ -361,13 +360,12 @@ public class IpSecServiceParameterizedTest { IpSecTransformResponse createTransformResp = mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId()); verify(mMockNetd, times(0)) .ipSecDeleteSecurityAssociation( - eq(createTransformResp.resourceId), + eq(mUid), anyString(), anyString(), eq(TEST_SPI), @@ -389,7 +387,7 @@ public class IpSecServiceParameterizedTest { verify(mMockNetd, times(1)) .ipSecDeleteSecurityAssociation( - eq(createTransformResp.resourceId), + eq(mUid), anyString(), anyString(), eq(TEST_SPI), @@ -397,8 +395,7 @@ public class IpSecServiceParameterizedTest { anyInt()); // Verify quota and RefcountedResource objects cleaned up - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent); assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent); @@ -433,8 +430,7 @@ public class IpSecServiceParameterizedTest { IpSecTransformResponse createTransformResp = mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage"); - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); IpSecService.RefcountedResource refcountedRecord = userRecord.mTransformRecords.getRefcountedResourceOrThrow( createTransformResp.resourceId); @@ -443,7 +439,7 @@ public class IpSecServiceParameterizedTest { verify(mMockNetd) .ipSecDeleteSecurityAssociation( - eq(createTransformResp.resourceId), + eq(mUid), anyString(), anyString(), eq(TEST_SPI), @@ -477,7 +473,7 @@ public class IpSecServiceParameterizedTest { verify(mMockNetd) .ipSecApplyTransportModeTransform( eq(pfd.getFileDescriptor()), - eq(resourceId), + eq(mUid), eq(IpSecManager.DIRECTION_OUT), anyString(), anyString(), @@ -509,8 +505,7 @@ public class IpSecServiceParameterizedTest { createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage"); // Check that we have stored the tracking object, and retrieve it - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); IpSecService.RefcountedResource refcountedRecord = userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( createTunnelResp.resourceId); @@ -530,8 +525,7 @@ public class IpSecServiceParameterizedTest { IpSecTunnelInterfaceResponse createTunnelResp = createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage"); - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, "blessedPackage"); @@ -551,8 +545,7 @@ public class IpSecServiceParameterizedTest { IpSecTunnelInterfaceResponse createTunnelResp = createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage"); - IpSecService.UserRecord userRecord = - mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid()); + IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid); IpSecService.RefcountedResource refcountedRecord = userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow( createTunnelResp.resourceId); diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh new file mode 100755 index 000000000000..e50c70d0656a --- /dev/null +++ b/tools/aosp/aosp_sha.sh @@ -0,0 +1,24 @@ +#!/bin/bash +LOCAL_DIR="$( dirname "${BASH_SOURCE}" )" + +if git branch -vv | grep -q -P "^\*[^\[]+\[aosp/"; then + # Change appears to be in AOSP + exit 0 +else + # Change appears to be non-AOSP; search for files + count=0 + while read -r file ; do + if (( count == 0 )); then + echo + fi + echo -e "\033[0;31mThe source of truth for '$file' is in AOSP.\033[0m" + (( count++ )) + done < <(git show --name-only --pretty=format: $1 | grep -- "$2") + if (( count != 0 )); then + echo + echo "If your change contains no confidential details (such as security fixes), please" + echo "upload and merge this change at https://android-review.googlesource.com/." + echo + exit 77 + fi +fi diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index 4a0931a149af..6c46e67be63d 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -59,6 +59,8 @@ def get_args(): def read_lines(filename): """Reads entire file and return it as a list of lines. + Lines which begin with a hash are ignored. + Args: filename (string): Path to the file to read from. @@ -66,7 +68,7 @@ def read_lines(filename): list: Lines of the loaded file as a list of strings. """ with open(filename, 'r') as f: - return f.readlines() + return filter(lambda line: not line.startswith('#'), f.readlines()) def write_lines(filename, lines): """Writes list of lines into a file, overwriting the file it it exists. diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh index 1c6eb1b286b1..bdcc8076dde1 100755 --- a/tools/hiddenapi/sort_api.sh +++ b/tools/hiddenapi/sort_api.sh @@ -11,8 +11,14 @@ fi readarray A < "$source_list" # Sort IFS=$'\n' +# Stash away comments +C=( $(grep -E '^#' <<< "${A[*]}") ) +A=( $(grep -v -E '^#' <<< "${A[*]}") ) +# Sort entries A=( $(LC_COLLATE=C sort -f <<< "${A[*]}") ) A=( $(uniq <<< "${A[*]}") ) +# Concatenate comments and entries +A=( ${C[*]} ${A[*]} ) unset IFS # Dump array back into the file printf '%s\n' "${A[@]}" > "$dest_list" diff --git a/tools/processors/unsupportedappusage/Android.bp b/tools/processors/unsupportedappusage/Android.bp index 98f3c955a2d2..1aca3edfab88 100644 --- a/tools/processors/unsupportedappusage/Android.bp +++ b/tools/processors/unsupportedappusage/Android.bp @@ -11,5 +11,15 @@ java_library_host { "guava", "unsupportedappusage-annotation" ], + openjdk9: { + javacflags: [ + "--add-modules=jdk.compiler", + "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + ], + }, + use_tools_jar: true, } |