summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java3
-rw-r--r--core/java/android/app/admin/DeviceAdminReceiver.java27
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java15
-rw-r--r--core/java/android/content/AbstractThreadedSyncAdapter.java27
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl4
-rw-r--r--core/java/android/content/pm/LauncherApps.java16
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java19
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java56
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java2
-rw-r--r--core/java/android/hardware/camera2/impl/CameraMetadataNative.java12
-rw-r--r--core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java10
-rw-r--r--core/java/android/hardware/camera2/params/StreamConfigurationMap.java280
-rw-r--r--core/java/android/hardware/camera2/params/TonemapCurve.java2
-rw-r--r--core/java/android/hardware/camera2/utils/HashCodeHelpers.java58
-rw-r--r--core/java/android/hardware/camera2/utils/SurfaceUtils.java26
-rw-r--r--core/java/android/inputmethodservice/ExtractEditText.java8
-rw-r--r--core/java/android/os/BatteryStats.java18
-rw-r--r--core/java/android/os/UserManager.java16
-rw-r--r--core/java/android/os/storage/VolumeInfo.java7
-rw-r--r--core/java/android/os/storage/VolumeRecord.java5
-rw-r--r--core/java/android/text/TextUtils.java5
-rw-r--r--core/java/android/util/Range.java2
-rw-r--r--core/java/android/view/DisplayListCanvas.java6
-rw-r--r--core/java/android/view/accessibility/CaptioningManager.java36
-rw-r--r--core/java/android/webkit/WebViewClient.java21
-rw-r--r--core/java/android/widget/Editor.java14
-rw-r--r--core/java/android/widget/OverScroller.java12
-rw-r--r--core/java/android/widget/RelativeLayout.java18
-rw-r--r--core/java/android/widget/Spinner.java8
-rw-r--r--core/java/android/widget/TextView.java9
30 files changed, 476 insertions, 266 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 1b4ee2e..e8ab109 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2075,6 +2075,9 @@ public class Activity extends ContextThemeWrapper
"by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
"android:windowActionBar to false in your theme to use a Toolbar instead.");
}
+ // Clear out the MenuInflater to make sure that it is valid for the new Action Bar
+ mMenuInflater = null;
+
ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);
mActionBar = tbab;
mWindow.setCallback(tbab.getWrappedWindowCallback());
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 87e2f9a..a1bb40c 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -19,6 +19,7 @@ package android.app.admin;
import android.accounts.AccountManager;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -227,14 +228,15 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
"android.app.action.PROFILE_PROVISIONING_COMPLETE";
/**
+ * @hide
* Broadcast Action: This broadcast is sent to indicate that the system is ready for the device
* initializer to perform user setup tasks. This is only applicable to devices managed by a
* device owner app.
*
* <p>The broadcast will be limited to the {@link DeviceAdminReceiver} component specified in
- * the {@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME} field
- * of the original intent or NFC bump that started the provisioning process. You will generally
- * handle this in {@link DeviceAdminReceiver#onReadyForUserInitialization}.
+ * the device initializer field of the original intent or NFC bump that started the provisioning
+ * process. You will generally handle this in
+ * {@link DeviceAdminReceiver#onReadyForUserInitialization}.
*
* <p>Input: Nothing.</p>
* <p>Output: Nothing</p>
@@ -435,23 +437,22 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
* Called during provisioning of a managed device to allow the device initializer to perform
* user setup steps. Only device initializers should override this method.
*
- * <p> Called when the DeviceAdminReceiver receives a
- * {@link #ACTION_READY_FOR_USER_INITIALIZATION} broadcast. As a prerequisite for the execution
- * of this callback the {@link DeviceAdminReceiver} has
- * to declare an intent filter for {@link #ACTION_READY_FOR_USER_INITIALIZATION}. Only the
- * component specified in the
- * {@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME} field of the
+ * <p> Called when the DeviceAdminReceiver receives an
+ * android.app.action.ACTION_READY_FOR_USER_INITIALIZATION broadcast. As a prerequisite for the
+ * execution of this callback the {@link DeviceAdminReceiver} has
+ * to declare an intent filter for android.app.action.ACTION_READY_FOR_USER_INITIALIZATION. Only
+ * the component specified in the device initializer component name field of the
* original intent or NFC bump that started the provisioning process will receive this callback.
*
* <p>It is not assumed that the device initializer is finished when it returns from
- * this call, as it may do additional setup asynchronously. The device initializer must call
- * {@link DevicePolicyManager#setUserEnabled(ComponentName admin)} when it has finished any
- * additional setup (such as adding an account by using the {@link AccountManager}) in order for
- * the user to be functional.
+ * this call, as it may do additional setup asynchronously. The device initializer must enable
+ * the current user when it has finished any additional setup (such as adding an account by
+ * using the {@link AccountManager}) in order for the user to be functional.
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
*/
+ @SystemApi
public void onReadyForUserInitialization(Context context, Intent intent) {
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b9862ca..125708a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -468,6 +468,7 @@ public class DevicePolicyManager {
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
/**
+ * @hide
* On devices managed by a device owner app, a {@link ComponentName} extra indicating the
* component of the application that is temporarily granted device owner privileges during
* device initialization and profile owner privileges during secondary user initialization.
@@ -483,6 +484,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME";
/**
+ * @hide
* A String extra holding an http url that specifies the download location of the device
* initializer package. When not provided it is assumed that the device initializer package is
* already installed.
@@ -494,6 +496,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION";
/**
+ * @hide
* An int extra holding a minimum required version code for the device initializer package.
* If the initializer is already installed on the device, it will only be re-downloaded from
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION} if the version of
@@ -506,6 +509,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE";
/**
+ * @hide
* A String extra holding a http cookie header which should be used in the http request to the
* url specified in {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
*
@@ -516,6 +520,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
+ * @hide
* A String extra holding the URL-safe base64 encoded SHA-256 checksum of the file at download
* location specified in
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
@@ -532,6 +537,7 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM";
/**
+ * @hide
* A String extra holding the URL-safe base64 encoded SHA-256 checksum of any signature of the
* android package archive at the download location specified in {@link
* #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
@@ -611,11 +617,6 @@ public class DevicePolicyManager {
* {@link #MIME_TYPE_PROVISIONING_NFC}:
* <ul>
* <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}.
* Replaces {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}. The value of the property
* should be converted to a String via
@@ -2756,6 +2757,7 @@ public class DevicePolicyManager {
}
/**
+ * @hide
* Sets the given component as the device initializer. The package must already be installed and
* set as an active device administrator, and there must not be an existing device initializer,
* for this call to succeed. This method can only be called by an app holding the
@@ -2784,6 +2786,7 @@ public class DevicePolicyManager {
}
/**
+ * @hide
* Used to determine if a particular package has been registered as the device initializer.
*
* @param packageName the package name of the app, to compare with the registered device
@@ -2802,6 +2805,7 @@ public class DevicePolicyManager {
}
/**
+ * @hide
* Removes the device initializer, so that it will not be invoked on user initialization for any
* subsequently created users. This method can be called by either the device owner or device
* initializer itself. The caller must be an active administrator.
@@ -2856,6 +2860,7 @@ public class DevicePolicyManager {
/**
+ * @hide
* Sets the enabled state of the user. A user should be enabled only once it is ready to
* be used.
*
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 809f900..d4dee5b 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -28,13 +28,26 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* An abstract implementation of a SyncAdapter that spawns a thread to invoke a sync operation.
- * If a sync operation is already in progress when a startSync() request is received then an error
- * will be returned to the new request and the existing request will be allowed to continue.
- * When a startSync() is received and there is no sync operation in progress then a thread
- * will be started to run the operation and {@link #onPerformSync} will be invoked on that thread.
- * If a cancelSync() is received that matches an existing sync operation then the thread
- * that is running that sync operation will be interrupted, which will indicate to the thread
- * that the sync has been canceled.
+ * If a sync operation is already in progress when a sync request is received, an error will be
+ * returned to the new request and the existing request will be allowed to continue.
+ * However if there is no sync in progress then a thread will be spawned and {@link #onPerformSync}
+ * will be invoked on that thread.
+ * <p>
+ * Syncs can be cancelled at any time by the framework. For example a sync that was not
+ * user-initiated and lasts longer than 30 minutes will be considered timed-out and cancelled.
+ * Similarly the framework will attempt to determine whether or not an adapter is making progress
+ * by monitoring its network activity over the course of a minute. If the network traffic over this
+ * window is close enough to zero the sync will be cancelled. You can also request the sync be
+ * cancelled via {@link ContentResolver#cancelSync(Account, String)} or
+ * {@link ContentResolver#cancelSync(SyncRequest)}.
+ * <p>
+ * A sync is cancelled by issuing a {@link Thread#interrupt()} on the syncing thread. <strong>Either
+ * your code in {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}
+ * must check {@link Thread#interrupted()}, or you you must override one of
+ * {@link #onSyncCanceled(Thread)}/{@link #onSyncCanceled()}</strong> (depending on whether or not
+ * your adapter supports syncing of multiple accounts in parallel). If your adapter does not
+ * respect the cancel issued by the framework you run the risk of your app's entire process being
+ * killed.
* <p>
* In order to be a sync adapter one must extend this class, provide implementations for the
* abstract methods and write a service that returns the result of {@link #getSyncAdapterBinder()}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0c07bc3..2dbcde9 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -282,6 +282,10 @@ interface IPackageManager {
*/
byte[] getPreferredActivityBackup(int userId);
void restorePreferredActivities(in byte[] backup, int userId);
+ byte[] getDefaultAppsBackup(int userId);
+ void restoreDefaultApps(in byte[] backup, int userId);
+ byte[] getIntentFilterVerificationBackup(int userId);
+ void restoreIntentFilterVerification(in byte[] backup, int userId);
/**
* Report the set of 'Home' activity candidates, plus (if any) which of them
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 5c21c8e..e9ec771 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -294,7 +294,7 @@ public class LauncherApps {
*/
public void registerCallback(Callback callback, Handler handler) {
synchronized (this) {
- if (callback != null && !mCallbacks.contains(callback)) {
+ if (callback != null && findCallbackLocked(callback) < 0) {
boolean addedFirstCallback = mCallbacks.size() == 0;
addCallbackLocked(callback, handler);
if (addedFirstCallback) {
@@ -325,17 +325,25 @@ public class LauncherApps {
}
}
- private void removeCallbackLocked(Callback callback) {
+ /** @return position in mCallbacks for callback or -1 if not present. */
+ private int findCallbackLocked(Callback callback) {
if (callback == null) {
throw new IllegalArgumentException("Callback cannot be null");
}
final int size = mCallbacks.size();
for (int i = 0; i < size; ++i) {
if (mCallbacks.get(i).mCallback == callback) {
- mCallbacks.remove(i);
- return;
+ return i;
}
}
+ return -1;
+ }
+
+ private void removeCallbackLocked(Callback callback) {
+ int pos = findCallbackLocked(callback);
+ if (pos >= 0) {
+ mCallbacks.remove(pos);
+ }
}
private void addCallbackLocked(Callback callback, Handler handler) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 27d14b3..261ce72 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -2679,9 +2679,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>Camera devices will come in three flavors: LEGACY, LIMITED and FULL.</p>
* <p>A FULL device will support below capabilities:</p>
* <ul>
- * <li>30fps operation at maximum resolution (== sensor resolution) is preferred, more than
- * 20fps is required, for at least uncompressed YUV
- * output. ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains BURST_CAPTURE)</li>
+ * <li>BURST_CAPTURE capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains BURST_CAPTURE)</li>
* <li>Per frame control ({@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} <code>==</code> PER_FRAME_CONTROL)</li>
* <li>Manual sensor control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR)</li>
* <li>Manual post-processing control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
@@ -2689,7 +2687,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <li>Arbitrary cropping region ({@link CameraCharacteristics#SCALER_CROPPING_TYPE android.scaler.croppingType} <code>==</code> FREEFORM)</li>
* <li>At least 3 processed (but not stalling) format output streams
* ({@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_PROC android.request.maxNumOutputProc} <code>&gt;=</code> 3)</li>
- * <li>The required stream configuration defined in android.scaler.availableStreamConfigurations</li>
+ * <li>The required stream configurations defined in android.scaler.availableStreamConfigurations</li>
* <li>The required exposure time range defined in {@link CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE android.sensor.info.exposureTimeRange}</li>
* <li>The required maxFrameDuration defined in {@link CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION android.sensor.info.maxFrameDuration}</li>
* </ul>
@@ -2709,23 +2707,11 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* post-processing, arbitrary cropping regions, and has relaxed performance constraints.</p>
* <p>Each higher level supports everything the lower level supports
* in this order: FULL <code>&gt;</code> LIMITED <code>&gt;</code> LEGACY.</p>
- * <p>A HIGH_RESOLUTION device is equivalent to a FULL device, except that:</p>
- * <ul>
- * <li>At least one output resolution of 8 megapixels or higher in uncompressed YUV is
- * supported at <code>&gt;=</code> 20 fps.</li>
- * <li>Maximum-size (sensor resolution) uncompressed YUV is supported at <code>&gt;=</code> 10
- * fps.</li>
- * <li>For devices that list the RAW capability and support either RAW10 or RAW12 output,
- * maximum-resolution RAW10 or RAW12 capture will operate at least at the rate of
- * maximum-resolution YUV capture, and at least one supported output resolution of
- * 8 megapixels or higher in RAW10 or RAW12 is supported <code>&gt;=</code> 20 fps.</li>
- * </ul>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}</li>
* <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}</li>
* <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}</li>
- * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION HIGH_RESOLUTION}</li>
* </ul></p>
* <p>This key is available on all devices.</p>
*
@@ -2743,7 +2729,6 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
* @see #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
- * @see #INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION
*/
@PublicKey
public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL =
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index c656fb8..5a80585 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -531,37 +531,32 @@ public abstract class CameraMetadata<TKey> {
public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5;
/**
- * <p>The camera device supports capturing maximum-resolution
- * images at &gt;= 20 frames per second, in at least the
- * uncompressed YUV format, when post-processing settings
- * are set to FAST.</p>
- * <p>More specifically, this means that a size matching the
- * camera device's active array size is listed as a
- * supported size for the YUV_420_888 format in
- * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}, the minimum frame
- * duration for that format and size is &lt;= 1/20 s, and
- * the {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges} entry
- * lists at least one FPS range where the minimum FPS is</p>
- * <blockquote>
- * <p>= 1 / minimumFrameDuration for the maximum-size
- * YUV_420_888 format.</p>
- * </blockquote>
- * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is
- * guaranted to have a value between 0 and 4, inclusive.
- * {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and
- * {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable} are also guaranteed
- * to be <code>true</code> so burst capture with these two locks ON
- * yields consistent image output.</p>
- * <p>On a camera device that reports the HIGH_RESOLUTION hardware
- * level, meaning the device supports very large capture sizes,
- * BURST_CAPTURE means that at least 8-megapixel images can be
- * captured at <code>&gt;=</code> 20 fps, and maximum-resolution images can be
- * captured at <code>&gt;=</code> 10 fps.</p>
+ * <p>The camera device supports capturing high-resolution images at &gt;= 20 frames per
+ * second, in at least the uncompressed YUV format, when post-processing settings are set
+ * to FAST. Additionally, maximum-resolution images can be captured at &gt;= 10 frames
+ * per second. Here, 'high resolution' means at least 8 megapixels, or the maximum
+ * resolution of the device, whichever is smaller.</p>
+ * <p>More specifically, this means that a size matching the camera device's active array
+ * size is listed as a supported size for the {@link android.graphics.ImageFormat#YUV_420_888 } format in either {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } or {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes },
+ * with a minimum frame duration for that format and size of either &lt;= 1/20 s, or
+ * &lt;= 1/10 s, respectively; and the {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges} entry
+ * lists at least one FPS range where the minimum FPS is &gt;= 1 / minimumFrameDuration
+ * for the maximum-size YUV_420_888 format. If that maximum size is listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes },
+ * then the list of resolutions for YUV_420_888 from {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } contains at
+ * least one resolution &gt;= 8 megapixels, with a minimum frame duration of &lt;= 1/20
+ * s.</p>
+ * <p>If the device supports the {@link android.graphics.ImageFormat#RAW10 }, {@link android.graphics.ImageFormat#RAW12 }, then those can also be captured at the same rate
+ * as the maximum-size YUV_420_888 resolution is.</p>
+ * <p>If the device supports the PRIVATE_REPROCESSING capability, then the same guarantees
+ * as for the YUV_420_888 format also apply to the {@link android.graphics.ImageFormat#PRIVATE } format.</p>
+ * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is guaranted to have a value between 0
+ * and 4, inclusive. {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable}
+ * are also guaranteed to be <code>true</code> so burst capture with these two locks ON yields
+ * consistent image output.</p>
*
* @see CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES
* @see CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE
* @see CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE
- * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
* @see CameraCharacteristics#SYNC_MAX_LATENCY
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
@@ -954,13 +949,6 @@ public abstract class CameraMetadata<TKey> {
*/
public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2;
- /**
- * <p>This camera device is capable of supporting advanced imaging applications at full rate,
- * and additional high-resolution outputs at lower rates.</p>
- * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
- */
- public static final int INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION = 3;
-
//
// Enumeration values for CameraCharacteristics#SYNC_MAX_LATENCY
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 9fa6687..e405ba6 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -398,7 +398,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
@Override
public int hashCode() {
- return HashCodeHelpers.hashCode(mSettings, mSurfaceSet, mUserTag);
+ return HashCodeHelpers.hashCodeGeneric(mSettings, mSurfaceSet, mUserTag);
}
public static final Parcelable.Creator<CaptureRequest> CREATOR =
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 10dd8ae..7e50fd9 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -842,11 +842,19 @@ public class CameraMetadataNative implements Parcelable {
CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
ReprocessFormatsMap inputOutputFormatsMap = getBase(
CameraCharacteristics.SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP);
-
+ int[] capabilities = getBase(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+ boolean listHighResolution = false;
+ for (int capability : capabilities) {
+ if (capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE) {
+ listHighResolution = true;
+ break;
+ }
+ }
return new StreamConfigurationMap(
configurations, minFrameDurations, stallDurations,
depthConfigurations, depthMinFrameDurations, depthStallDurations,
- highSpeedVideoConfigurations, inputOutputFormatsMap);
+ highSpeedVideoConfigurations, inputOutputFormatsMap,
+ listHighResolution);
}
private <T> Integer getMaxRegions(Key<T> key) {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index 2fb3203..e786707 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -605,6 +605,14 @@ public class LegacyCameraDevice implements AutoCloseable {
return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface));
}
+ /**
+ * Query the surface for its currently configured dataspace
+ */
+ public static int detectSurfaceDataspace(Surface surface) throws BufferQueueAbandonedException {
+ checkNotNull(surface);
+ return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface));
+ }
+
static void configureSurface(Surface surface, int width, int height,
int pixelFormat) throws BufferQueueAbandonedException {
checkNotNull(surface);
@@ -702,6 +710,8 @@ public class LegacyCameraDevice implements AutoCloseable {
private static native int nativeDetectSurfaceType(Surface surface);
+ private static native int nativeDetectSurfaceDataspace(Surface surface);
+
private static native int nativeDetectSurfaceDimens(Surface surface,
/*out*/int[/*2*/] dimens);
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index c6ea488..0935564 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -22,12 +22,13 @@ import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.utils.HashCodeHelpers;
+import android.hardware.camera2.utils.SurfaceUtils;
import android.hardware.camera2.legacy.LegacyCameraDevice;
import android.hardware.camera2.legacy.LegacyMetadataMapper;
-import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException;
import android.view.Surface;
import android.util.Range;
import android.util.Size;
+import android.util.SparseIntArray;
import java.util.Arrays;
import java.util.HashMap;
@@ -79,7 +80,8 @@ public final class StreamConfigurationMap {
* @param stallDurations a non-{@code null} array of {@link StreamConfigurationDuration}
* @param highSpeedVideoConfigurations an array of {@link HighSpeedVideoConfiguration}, null if
* camera device does not support high speed video recording
- *
+ * @param listHighResolution a flag indicating whether the device supports BURST_CAPTURE
+ * and thus needs a separate list of slow high-resolution output sizes
* @throws NullPointerException if any of the arguments except highSpeedVideoConfigurations
* were {@code null} or any subelements were {@code null}
*
@@ -93,10 +95,12 @@ public final class StreamConfigurationMap {
StreamConfigurationDuration[] depthMinFrameDurations,
StreamConfigurationDuration[] depthStallDurations,
HighSpeedVideoConfiguration[] highSpeedVideoConfigurations,
- ReprocessFormatsMap inputOutputFormatsMap) {
+ ReprocessFormatsMap inputOutputFormatsMap,
+ boolean listHighResolution) {
mConfigurations = checkArrayElementsNotNull(configurations, "configurations");
mMinFrameDurations = checkArrayElementsNotNull(minFrameDurations, "minFrameDurations");
mStallDurations = checkArrayElementsNotNull(stallDurations, "stallDurations");
+ mListHighResolution = listHighResolution;
if (depthConfigurations == null) {
mDepthConfigurations = new StreamConfiguration[0];
@@ -120,15 +124,27 @@ public final class StreamConfigurationMap {
// For each format, track how many sizes there are available to configure
for (StreamConfiguration config : configurations) {
- HashMap<Integer, Integer> map = config.isOutput() ? mOutputFormats : mInputFormats;
-
- Integer count = map.get(config.getFormat());
-
- if (count == null) {
- count = 0;
+ int fmt = config.getFormat();
+ SparseIntArray map = null;
+ if (config.isOutput()) {
+ mAllOutputFormats.put(fmt, mAllOutputFormats.get(fmt) + 1);
+ long duration = 0;
+ if (mListHighResolution) {
+ for (StreamConfigurationDuration configurationDuration : mMinFrameDurations) {
+ if (configurationDuration.getFormat() == fmt &&
+ configurationDuration.getWidth() == config.getSize().getWidth() &&
+ configurationDuration.getHeight() == config.getSize().getHeight()) {
+ duration = configurationDuration.getDuration();
+ break;
+ }
+ }
+ }
+ map = duration <= DURATION_20FPS_NS ?
+ mOutputFormats : mHighResOutputFormats;
+ } else {
+ map = mInputFormats;
}
-
- map.put(config.getFormat(), count + 1);
+ map.put(fmt, map.get(fmt) + 1);
}
// For each depth format, track how many sizes there are available to configure
@@ -138,16 +154,11 @@ public final class StreamConfigurationMap {
continue;
}
- Integer count = mDepthOutputFormats.get(config.getFormat());
-
- if (count == null) {
- count = 0;
- }
-
- mDepthOutputFormats.put(config.getFormat(), count + 1);
+ mDepthOutputFormats.put(config.getFormat(),
+ mDepthOutputFormats.get(config.getFormat()) + 1);
}
- if (!mOutputFormats.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) {
+ if (mOutputFormats.indexOfKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) < 0) {
throw new AssertionError(
"At least one stream configuration for IMPLEMENTATION_DEFINED must exist");
}
@@ -241,7 +252,7 @@ public final class StreamConfigurationMap {
* @return a non-empty array of sizes, or {@code null} if the format was not available.
*/
public Size[] getInputSizes(final int format) {
- return getPublicFormatSizes(format, /*output*/false);
+ return getPublicFormatSizes(format, /*output*/false, /*highRes*/false);
}
/**
@@ -274,9 +285,9 @@ public final class StreamConfigurationMap {
int internalFormat = imageFormatToInternal(format);
int dataspace = imageFormatToDataspace(format);
if (dataspace == HAL_DATASPACE_DEPTH) {
- return mDepthOutputFormats.containsKey(internalFormat);
+ return mDepthOutputFormats.indexOfKey(internalFormat) >= 0;
} else {
- return getFormatsMap(/*output*/true).containsKey(internalFormat);
+ return getFormatsMap(/*output*/true).indexOfKey(internalFormat) >= 0;
}
}
@@ -378,27 +389,24 @@ public final class StreamConfigurationMap {
public boolean isOutputSupportedFor(Surface surface) {
checkNotNull(surface, "surface must not be null");
- Size surfaceSize;
- int surfaceFormat = -1;
- try {
- surfaceSize = LegacyCameraDevice.getSurfaceSize(surface);
- surfaceFormat = LegacyCameraDevice.detectSurfaceType(surface);
- } catch(BufferQueueAbandonedException e) {
- throw new IllegalArgumentException("Abandoned surface", e);
- }
+ Size surfaceSize = SurfaceUtils.getSurfaceSize(surface);
+ int surfaceFormat = SurfaceUtils.getSurfaceFormat(surface);
+ int surfaceDataspace = SurfaceUtils.getSurfaceDataspace(surface);
// See if consumer is flexible.
- boolean isFlexible = LegacyCameraDevice.isFlexibleConsumer(surface);
+ boolean isFlexible = SurfaceUtils.isFlexibleConsumer(surface);
// Override RGB formats to IMPLEMENTATION_DEFINED, b/9487482
if ((surfaceFormat >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 &&
surfaceFormat <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) {
- surfaceFormat = LegacyMetadataMapper.HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+ surfaceFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
}
- for (StreamConfiguration config : mConfigurations) {
+ StreamConfiguration[] configs =
+ surfaceDataspace != HAL_DATASPACE_DEPTH ? mConfigurations : mDepthConfigurations;
+ for (StreamConfiguration config : configs) {
if (config.getFormat() == surfaceFormat && config.isOutput()) {
- // Mathing format, either need exact size match, or a flexible consumer
+ // Matching format, either need exact size match, or a flexible consumer
// and a size no bigger than MAX_DIMEN_FOR_ROUNDING
if (config.getSize().equals(surfaceSize)) {
return true;
@@ -414,12 +422,12 @@ public final class StreamConfigurationMap {
/**
* Get a list of sizes compatible with {@code klass} to use as an output.
*
- * <p>Since some of the supported classes may support additional formats beyond
+ * <p>Some of the supported classes may support additional formats beyond
* {@link ImageFormat#PRIVATE}; this function only returns
* sizes for {@link ImageFormat#PRIVATE}. For example, {@link android.media.ImageReader}
* supports {@link ImageFormat#YUV_420_888} and {@link ImageFormat#PRIVATE}, this method will
* only return the sizes for {@link ImageFormat#PRIVATE} for {@link android.media.ImageReader}
- * class .</p>
+ * class.</p>
*
* <p>If a well-defined format such as {@code NV21} is required, use
* {@link #getOutputSizes(int)} instead.</p>
@@ -444,7 +452,7 @@ public final class StreamConfigurationMap {
}
return getInternalFormatSizes(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
- HAL_DATASPACE_UNKNOWN,/*output*/true);
+ HAL_DATASPACE_UNKNOWN,/*output*/true, /*highRes*/false);
}
/**
@@ -453,6 +461,14 @@ public final class StreamConfigurationMap {
* <p>The {@code format} should be a supported format (one of the formats returned by
* {@link #getOutputFormats}).</p>
*
+ * As of API level 23, the {@link #getHighResolutionOutputSizes} method can be used on devices
+ * that support the
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}
+ * capability to get a list of high-resolution output sizes that cannot operate at the preferred
+ * 20fps rate. This means that for some supported formats, this method will return an empty
+ * list, if all the supported resolutions operate at below 20fps. For devices that do not
+ * support the BURST_CAPTURE capability, all output resolutions are listed through this method.
+ *
* @param format an image format from {@link ImageFormat} or {@link PixelFormat}
* @return
* an array of supported sizes,
@@ -463,7 +479,7 @@ public final class StreamConfigurationMap {
* @see #getOutputFormats
*/
public Size[] getOutputSizes(int format) {
- return getPublicFormatSizes(format, /*output*/true);
+ return getPublicFormatSizes(format, /*output*/true, /*highRes*/ false);
}
/**
@@ -616,6 +632,32 @@ public final class StreamConfigurationMap {
}
/**
+ * Get a list of supported high resolution sizes, which cannot operate at full BURST_CAPTURE
+ * rate.
+ *
+ * <p>This includes all output sizes that cannot meet the 20 fps frame rate requirements for the
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}
+ * capability. This does not include the stall duration, so for example, a JPEG or RAW16 output
+ * resolution with a large stall duration but a minimum frame duration that's above 20 fps will
+ * still be listed in the regular {@link #getOutputSizes} list. All the sizes on this list are
+ * still guaranteed to operate at a rate of at least 10 fps, not including stall duration.</p>
+ *
+ * <p>For a device that does not support the BURST_CAPTURE capability, this list will be
+ * {@code null}, since resolutions in the {@link #getOutputSizes} list are already not
+ * guaranteed to meet &gt;= 20 fps rate requirements. For a device that does support the
+ * BURST_CAPTURE capability, this list may be empty, if all supported resolutions meet the 20
+ * fps requirement.</p>
+ *
+ * @return an array of supported slower high-resolution sizes, or {@code null} if the
+ * BURST_CAPTURE capability is not supported
+ */
+ public Size[] getHighResolutionOutputSizes(int format) {
+ if (!mListHighResolution) return null;
+
+ return getPublicFormatSizes(format, /*output*/true, /*highRes*/ true);
+ }
+
+ /**
* Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration}
* for the format/size combination (in nanoseconds).
*
@@ -867,6 +909,7 @@ public final class StreamConfigurationMap {
return Arrays.equals(mConfigurations, other.mConfigurations) &&
Arrays.equals(mMinFrameDurations, other.mMinFrameDurations) &&
Arrays.equals(mStallDurations, other.mStallDurations) &&
+ Arrays.equals(mDepthConfigurations, other.mDepthConfigurations) &&
Arrays.equals(mHighSpeedVideoConfigurations,
other.mHighSpeedVideoConfigurations);
}
@@ -879,18 +922,31 @@ public final class StreamConfigurationMap {
@Override
public int hashCode() {
// XX: do we care about order?
- return HashCodeHelpers.hashCode(
+ return HashCodeHelpers.hashCodeGeneric(
mConfigurations, mMinFrameDurations,
- mStallDurations, mHighSpeedVideoConfigurations);
+ mStallDurations,
+ mDepthConfigurations, mHighSpeedVideoConfigurations);
}
// Check that the argument is supported by #getOutputFormats or #getInputFormats
private int checkArgumentFormatSupported(int format, boolean output) {
checkArgumentFormat(format);
- int[] formats = output ? getOutputFormats() : getInputFormats();
- for (int i = 0; i < formats.length; ++i) {
- if (format == formats[i]) {
+ int internalFormat = imageFormatToInternal(format);
+ int internalDataspace = imageFormatToDataspace(format);
+
+ if (output) {
+ if (internalDataspace == HAL_DATASPACE_DEPTH) {
+ if (mDepthOutputFormats.indexOfKey(internalFormat) >= 0) {
+ return format;
+ }
+ } else {
+ if (mAllOutputFormats.indexOfKey(internalFormat) >= 0) {
+ return format;
+ }
+ }
+ } else {
+ if (mInputFormats.indexOfKey(internalFormat) >= 0) {
return format;
}
}
@@ -1175,7 +1231,7 @@ public final class StreamConfigurationMap {
return formats;
}
- private Size[] getPublicFormatSizes(int format, boolean output) {
+ private Size[] getPublicFormatSizes(int format, boolean output, boolean highRes) {
try {
checkArgumentFormatSupported(format, output);
} catch (IllegalArgumentException e) {
@@ -1185,36 +1241,57 @@ public final class StreamConfigurationMap {
int internalFormat = imageFormatToInternal(format);
int dataspace = imageFormatToDataspace(format);
- return getInternalFormatSizes(internalFormat, dataspace, output);
+ return getInternalFormatSizes(internalFormat, dataspace, output, highRes);
}
- private Size[] getInternalFormatSizes(int format, int dataspace, boolean output) {
-
- HashMap<Integer, Integer> formatsMap =
- (dataspace == HAL_DATASPACE_DEPTH) ? mDepthOutputFormats : getFormatsMap(output);
-
- Integer sizesCount = formatsMap.get(format);
- if (sizesCount == null) {
+ private Size[] getInternalFormatSizes(int format, int dataspace,
+ boolean output, boolean highRes) {
+ SparseIntArray formatsMap =
+ !output ? mInputFormats :
+ dataspace == HAL_DATASPACE_DEPTH ? mDepthOutputFormats :
+ highRes ? mHighResOutputFormats :
+ mOutputFormats;
+
+ int sizesCount = formatsMap.get(format);
+ if ( ((!output || dataspace == HAL_DATASPACE_DEPTH) && sizesCount == 0) ||
+ (output && dataspace != HAL_DATASPACE_DEPTH && mAllOutputFormats.get(format) == 0)) {
+ // Only throw if this is really not supported at all
throw new IllegalArgumentException("format not available");
}
- int len = sizesCount;
- Size[] sizes = new Size[len];
+ Size[] sizes = new Size[sizesCount];
int sizeIndex = 0;
StreamConfiguration[] configurations =
(dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations;
-
for (StreamConfiguration config : configurations) {
- if (config.getFormat() == format && config.isOutput() == output) {
+ int fmt = config.getFormat();
+ if (fmt == format && config.isOutput() == output) {
+ if (output) {
+ // Filter slow high-res output formats; include for
+ // highRes, remove for !highRes
+ long duration = 0;
+ for (int i = 0; i < mMinFrameDurations.length; i++) {
+ StreamConfigurationDuration d = mMinFrameDurations[i];
+ if (d.getFormat() == fmt &&
+ d.getWidth() == config.getSize().getWidth() &&
+ d.getHeight() == config.getSize().getHeight()) {
+ duration = d.getDuration();
+ break;
+ }
+ }
+ if (highRes != (duration > DURATION_20FPS_NS)) {
+ continue;
+ }
+ }
sizes[sizeIndex++] = config.getSize();
}
}
- if (sizeIndex != len) {
+ if (sizeIndex != sizesCount) {
throw new AssertionError(
- "Too few sizes (expected " + len + ", actual " + sizeIndex + ")");
+ "Too few sizes (expected " + sizesCount + ", actual " + sizeIndex + ")");
}
return sizes;
@@ -1226,14 +1303,16 @@ public final class StreamConfigurationMap {
int i = 0;
- for (int format : getFormatsMap(output).keySet()) {
+ SparseIntArray map = getFormatsMap(output);
+ for (int j = 0; j < map.size(); j++) {
+ int format = map.keyAt(j);
if (format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
formats[i++] = imageFormatToPublic(format);
}
}
if (output) {
- for (int format : mDepthOutputFormats.keySet()) {
- formats[i++] = depthFormatToPublic(format);
+ for (int j = 0; j < mDepthOutputFormats.size(); j++) {
+ formats[i++] = depthFormatToPublic(mDepthOutputFormats.keyAt(j));
}
}
if (formats.length != i) {
@@ -1244,14 +1323,14 @@ public final class StreamConfigurationMap {
}
/** Get the format -> size count map for either output or input formats */
- private HashMap<Integer, Integer> getFormatsMap(boolean output) {
- return output ? mOutputFormats : mInputFormats;
+ private SparseIntArray getFormatsMap(boolean output) {
+ return output ? mAllOutputFormats : mInputFormats;
}
private long getInternalFormatDuration(int format, int dataspace, Size size, int duration) {
// assume format is already checked, since its internal
- if (!arrayContains(getInternalFormatSizes(format, dataspace, /*output*/true), size)) {
+ if (!isSupportedInternalConfiguration(format, dataspace, size)) {
throw new IllegalArgumentException("size was not supported");
}
@@ -1289,10 +1368,9 @@ public final class StreamConfigurationMap {
/** Count the number of publicly-visible output formats */
private int getPublicFormatCount(boolean output) {
- HashMap<Integer, Integer> formatsMap = getFormatsMap(output);
-
+ SparseIntArray formatsMap = getFormatsMap(output);
int size = formatsMap.size();
- if (formatsMap.containsKey(HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
+ if (formatsMap.indexOfKey(HAL_PIXEL_FORMAT_RAW_OPAQUE) >= 0) {
size -= 1;
}
if (output) {
@@ -1316,6 +1394,21 @@ public final class StreamConfigurationMap {
return false;
}
+ private boolean isSupportedInternalConfiguration(int format, int dataspace,
+ Size size) {
+ StreamConfiguration[] configurations =
+ (dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations;
+
+ for (int i = 0; i < configurations.length; i++) {
+ if (configurations[i].getFormat() == format &&
+ configurations[i].getSize().equals(size)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* Return this {@link StreamConfigurationMap} as a string representation.
*
@@ -1351,6 +1444,8 @@ public final class StreamConfigurationMap {
StringBuilder sb = new StringBuilder("StreamConfiguration(");
appendOutputsString(sb);
sb.append(", ");
+ appendHighResOutputsString(sb);
+ sb.append(", ");
appendInputsString(sb);
sb.append(", ");
appendValidOutputFormatsForInputString(sb);
@@ -1381,6 +1476,27 @@ public final class StreamConfigurationMap {
sb.append(")");
}
+ private void appendHighResOutputsString(StringBuilder sb) {
+ sb.append("HighResolutionOutputs(");
+ int[] formats = getOutputFormats();
+ for (int format : formats) {
+ Size[] sizes = getHighResolutionOutputSizes(format);
+ if (sizes == null) continue;
+ for (Size size : sizes) {
+ long minFrameDuration = getOutputMinFrameDuration(format, size);
+ long stallDuration = getOutputStallDuration(format, size);
+ sb.append(String.format("[w:%d, h:%d, format:%s(%d), min_duration:%d, " +
+ "stall:%d], ", size.getWidth(), size.getHeight(), formatToString(format),
+ format, minFrameDuration, stallDuration));
+ }
+ }
+ // Remove the pending ", "
+ if (sb.charAt(sb.length() - 1) == ' ') {
+ sb.delete(sb.length() - 2, sb.length());
+ }
+ sb.append(")");
+ }
+
private void appendInputsString(StringBuilder sb) {
sb.append("Inputs(");
int[] formats = getInputFormats();
@@ -1479,15 +1595,21 @@ public final class StreamConfigurationMap {
}
// from system/core/include/system/graphics.h
+ private static final int HAL_PIXEL_FORMAT_RAW16 = 0x20;
private static final int HAL_PIXEL_FORMAT_BLOB = 0x21;
private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22;
+ private static final int HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23;
private static final int HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24;
+ private static final int HAL_PIXEL_FORMAT_RAW10 = 0x25;
+ private static final int HAL_PIXEL_FORMAT_RAW12 = 0x26;
private static final int HAL_PIXEL_FORMAT_Y16 = 0x20363159;
+
private static final int HAL_DATASPACE_UNKNOWN = 0x0;
private static final int HAL_DATASPACE_JFIF = 0x101;
private static final int HAL_DATASPACE_DEPTH = 0x1000;
+ private static final long DURATION_20FPS_NS = 50000000L;
/**
* @see #getDurations(int, int)
*/
@@ -1505,15 +1627,20 @@ public final class StreamConfigurationMap {
private final HighSpeedVideoConfiguration[] mHighSpeedVideoConfigurations;
private final ReprocessFormatsMap mInputOutputFormatsMap;
- /** ImageFormat -> num output sizes mapping */
- private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mOutputFormats =
- new HashMap<Integer, Integer>();
- /** ImageFormat -> num input sizes mapping */
- private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mInputFormats =
- new HashMap<Integer, Integer>();
- /** ImageFormat -> num depth output sizes mapping */
- private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mDepthOutputFormats =
- new HashMap<Integer, Integer>();
+ private final boolean mListHighResolution;
+
+ /** internal format -> num output sizes mapping, not including slow high-res sizes, for
+ * non-depth dataspaces */
+ private final SparseIntArray mOutputFormats = new SparseIntArray();
+ /** internal format -> num output sizes mapping for slow high-res sizes, for non-depth
+ * dataspaces */
+ private final SparseIntArray mHighResOutputFormats = new SparseIntArray();
+ /** internal format -> num output sizes mapping for all non-depth dataspaces */
+ private final SparseIntArray mAllOutputFormats = new SparseIntArray();
+ /** internal format -> num input sizes mapping, for input reprocessing formats */
+ private final SparseIntArray mInputFormats = new SparseIntArray();
+ /** internal format -> num depth output sizes mapping, for HAL_DATASPACE_DEPTH */
+ private final SparseIntArray mDepthOutputFormats = new SparseIntArray();
/** High speed video Size -> FPS range count mapping*/
private final HashMap</*HighSpeedVideoSize*/Size, /*Count*/Integer> mHighSpeedVideoSizeMap =
new HashMap<Size, Integer>();
@@ -1522,4 +1649,3 @@ public final class StreamConfigurationMap {
mHighSpeedVideoFpsRangeMap = new HashMap<Range<Integer>, Integer>();
}
-
diff --git a/core/java/android/hardware/camera2/params/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java
index 398a7e9..2d7bbaa 100644
--- a/core/java/android/hardware/camera2/params/TonemapCurve.java
+++ b/core/java/android/hardware/camera2/params/TonemapCurve.java
@@ -277,7 +277,7 @@ public final class TonemapCurve {
return mHashCode;
}
- mHashCode = HashCodeHelpers.hashCode(mRed, mGreen, mBlue);
+ mHashCode = HashCodeHelpers.hashCodeGeneric(mRed, mGreen, mBlue);
mHashCalculated = true;
return mHashCode;
diff --git a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java
index 7b4aa09..731da8b 100644
--- a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java
+++ b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java
@@ -30,7 +30,7 @@ public final class HashCodeHelpers {
*
* @return the numeric hash code
*/
- public static int hashCode(int[] array) {
+ public static int hashCode(int... array) {
if (array == null) {
return 0;
}
@@ -60,7 +60,7 @@ public final class HashCodeHelpers {
*
* @return the numeric hash code
*/
- public static int hashCode(float[] array) {
+ public static int hashCode(float... array) {
if (array == null) {
return 0;
}
@@ -83,7 +83,7 @@ public final class HashCodeHelpers {
*
* @return the numeric hash code
*/
- public static <T> int hashCode(T[] array) {
+ public static <T> int hashCodeGeneric(T... array) {
if (array == null) {
return 0;
}
@@ -97,56 +97,4 @@ public final class HashCodeHelpers {
return h;
}
- public static <T> int hashCode(T a) {
- return (a == null) ? 0 : a.hashCode();
- }
-
- public static <T> int hashCode(T a, T b) {
- int h = hashCode(a);
-
- int x = (b == null) ? 0 : b.hashCode();
- h = ((h << 5) - h) ^ x; // (h * 31) XOR x
-
- return h;
- }
-
- public static <T> int hashCode(T a, T b, T c) {
- int h = hashCode(a, b);
-
- int x = (c == null) ? 0 : c.hashCode();
- h = ((h << 5) - h) ^ x; // (h * 31) XOR x
-
- return h;
- }
-
- public static <T> int hashCode(T a, T b, T c, T d) {
- int h = hashCode(a, b, c);
-
- int x = (d == null) ? 0 : d.hashCode();
- h = ((h << 5) - h) ^ x; // (h * 31) XOR x
-
- return h;
- }
-
- public static int hashCode(int x) {
- return hashCode(new int[] { x } );
- }
-
- public static int hashCode(int x, int y) {
- return hashCode(new int[] { x, y } );
- }
-
- public static int hashCode(int x, int y, int z) {
- return hashCode(new int[] { x, y, z } );
- }
-
- public static int hashCode(int x, int y, int z, int w) {
- return hashCode(new int[] { x, y, z, w } );
- }
-
- public static int hashCode(int x, int y, int z, int w, int t) {
- return hashCode(new int[] { x, y, z, w, t } );
- }
-
-
}
diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
index 40005a5..064b21a 100644
--- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java
+++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
@@ -79,4 +79,30 @@ public class SurfaceUtils {
throw new IllegalArgumentException("Surface was abandoned", e);
}
}
+
+ /**
+ * Get the Surface dataspace.
+ *
+ * @param surface The surface to be queried for dataspace.
+ * @return dataspace of the surface.
+ *
+ * @throws IllegalArgumentException if the surface is already abandoned.
+ */
+ public static int getSurfaceDataspace(Surface surface) {
+ try {
+ return LegacyCameraDevice.detectSurfaceDataspace(surface);
+ } catch (BufferQueueAbandonedException e) {
+ throw new IllegalArgumentException("Surface was abandoned", e);
+ }
+ }
+
+ /**
+ * Return true is the consumer is one of the consumers that can accept
+ * producer overrides of the default dimensions and format.
+ *
+ */
+ public static boolean isFlexibleConsumer(Surface output) {
+ return LegacyCameraDevice.isFlexibleConsumer(output);
+ }
+
}
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index f965f54..8bc2876 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -165,6 +165,14 @@ public class ExtractEditText extends EditText {
}
/**
+ * @hide
+ */
+ @Override
+ public boolean isInExtractedMode() {
+ return true;
+ }
+
+ /**
* {@inheritDoc}
* @hide
*/
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 593f804..7fda30a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -142,9 +142,9 @@ public abstract class BatteryStats implements Parcelable {
public static final int CAMERA_TURNED_ON = 17;
/**
- * A constant indicating a doze wake lock timer.
+ * A constant indicating a draw wake lock timer.
*/
- public static final int WAKE_TYPE_DOZE = 18;
+ public static final int WAKE_TYPE_DRAW = 18;
/**
* Include all of the data in the stats, including previously saved data.
@@ -3839,7 +3839,7 @@ public abstract class BatteryStats implements Parcelable {
final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
= u.getWakelockStats();
long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
- long totalDozeWakelock = 0;
+ long totalDrawWakelock = 0;
int countWakelock = 0;
for (int iw=wakelocks.size()-1; iw>=0; iw--) {
final Uid.Wakelock wl = wakelocks.valueAt(iw);
@@ -3854,8 +3854,8 @@ public abstract class BatteryStats implements Parcelable {
"partial", which, linePrefix);
linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
"window", which, linePrefix);
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DOZE), rawRealtime,
- "doze", which, linePrefix);
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
+ "draw", which, linePrefix);
sb.append(" realtime");
pw.println(sb.toString());
uidActivity = true;
@@ -3867,7 +3867,7 @@ public abstract class BatteryStats implements Parcelable {
rawRealtime, which);
totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
rawRealtime, which);
- totalDozeWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DOZE),
+ totalDrawWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_DRAW),
rawRealtime, which);
}
if (countWakelock > 1) {
@@ -3898,13 +3898,13 @@ public abstract class BatteryStats implements Parcelable {
formatTimeMs(sb, totalWindowWakelock);
sb.append("window");
}
- if (totalDozeWakelock != 0) {
+ if (totalDrawWakelock != 0) {
if (needComma) {
sb.append(",");
}
needComma = true;
- formatTimeMs(sb, totalDozeWakelock);
- sb.append("doze");
+ formatTimeMs(sb, totalDrawWakelock);
+ sb.append("draw");
}
sb.append(" realtime");
pw.println(sb.toString());
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 00350ec..9770941 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -449,6 +449,22 @@ public class UserManager {
public static final String DISALLOW_RECORD_AUDIO = "no_record_audio";
/**
+ * This user restriction has an effect only in a managed profile.
+ * If set:
+ * Intent filters of activities in the parent profile with action
+ * {@link android.content.Intent#ACTION_VIEW},
+ * category {@link android.content.Intent#CATEGORY_BROWSABLE}, scheme http or https, and which
+ * define a host can handle intents from the managed profile.
+ * The default value is <code>false</code>.
+ *
+ * <p/>Key for user restrictions.
+ * <p/>Type: Boolean
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ */
+ public static final String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking";
+
+ /**
* Application restriction key that is used to indicate the pending arrival
* of real restrictions for the app.
*
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 8d11527..e33baa9 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -137,6 +137,7 @@ public class VolumeInfo implements Parcelable {
public final String id;
public final int type;
public final DiskInfo disk;
+ public final String partGuid;
public int mountFlags = 0;
public int mountUserId = -1;
public int state = STATE_UNMOUNTED;
@@ -149,10 +150,11 @@ public class VolumeInfo implements Parcelable {
/** Framework state */
public final int mtpIndex;
- public VolumeInfo(String id, int type, DiskInfo disk, int mtpIndex) {
+ public VolumeInfo(String id, int type, DiskInfo disk, String partGuid, int mtpIndex) {
this.id = Preconditions.checkNotNull(id);
this.type = type;
this.disk = disk;
+ this.partGuid = partGuid;
this.mtpIndex = mtpIndex;
}
@@ -164,6 +166,7 @@ public class VolumeInfo implements Parcelable {
} else {
disk = null;
}
+ partGuid = parcel.readString();
mountFlags = parcel.readInt();
mountUserId = parcel.readInt();
state = parcel.readInt();
@@ -385,6 +388,7 @@ public class VolumeInfo implements Parcelable {
pw.increaseIndent();
pw.printPair("type", DebugUtils.valueToString(getClass(), "TYPE_", type));
pw.printPair("diskId", getDiskId());
+ pw.printPair("partGuid", partGuid);
pw.printPair("mountFlags", DebugUtils.flagsToString(getClass(), "MOUNT_FLAG_", mountFlags));
pw.printPair("mountUserId", mountUserId);
pw.printPair("state", DebugUtils.valueToString(getClass(), "STATE_", state));
@@ -453,6 +457,7 @@ public class VolumeInfo implements Parcelable {
} else {
parcel.writeInt(0);
}
+ parcel.writeString(partGuid);
parcel.writeInt(mountFlags);
parcel.writeInt(mountUserId);
parcel.writeInt(state);
diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java
index 096e2dd..cb16305 100644
--- a/core/java/android/os/storage/VolumeRecord.java
+++ b/core/java/android/os/storage/VolumeRecord.java
@@ -39,6 +39,7 @@ public class VolumeRecord implements Parcelable {
public final int type;
public final String fsUuid;
+ public String partGuid;
public String nickname;
public int userFlags;
@@ -50,6 +51,7 @@ public class VolumeRecord implements Parcelable {
public VolumeRecord(Parcel parcel) {
type = parcel.readInt();
fsUuid = parcel.readString();
+ partGuid = parcel.readString();
nickname = parcel.readString();
userFlags = parcel.readInt();
}
@@ -79,6 +81,8 @@ public class VolumeRecord implements Parcelable {
pw.increaseIndent();
pw.printPair("type", DebugUtils.valueToString(VolumeInfo.class, "TYPE_", type));
pw.printPair("fsUuid", fsUuid);
+ pw.printPair("partGuid", partGuid);
+ pw.println();
pw.printPair("nickname", nickname);
pw.printPair("userFlags",
DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags));
@@ -133,6 +137,7 @@ public class VolumeRecord implements Parcelable {
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(type);
parcel.writeString(fsUuid);
+ parcel.writeString(partGuid);
parcel.writeString(nickname);
parcel.writeInt(userFlags);
}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index d51aa79..d8f7158 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -465,6 +465,11 @@ public class TextUtils {
return false;
}
+ /** {@hide} */
+ public static String nullIfEmpty(@Nullable String str) {
+ return isEmpty(str) ? null : str;
+ }
+
/**
* Returns the length that the specified CharSequence would have if
* spaces and control characters were trimmed from the start and end,
diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java
index 211d01a..5524506 100644
--- a/core/java/android/util/Range.java
+++ b/core/java/android/util/Range.java
@@ -350,7 +350,7 @@ public final class Range<T extends Comparable<? super T>> {
*/
@Override
public int hashCode() {
- return HashCodeHelpers.hashCode(mLower, mUpper);
+ return HashCodeHelpers.hashCodeGeneric(mLower, mUpper);
}
private final T mLower;
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 52a12f3..3c21981 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -323,10 +323,4 @@ public class DisplayListCanvas extends Canvas {
}
private static native void nDrawRects(long renderer, long region, long paint);
-
- @Override
- public void drawPicture(Picture picture) {
- picture.endRecording();
- // TODO: Implement rendering
- }
}
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
index 410d39c..14f0b0a 100644
--- a/core/java/android/view/accessibility/CaptioningManager.java
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -266,11 +266,19 @@ public class CaptioningManager {
* background colors, edge properties, and typeface.
*/
public static final class CaptionStyle {
- /** Packed value for a color of 'none' and a cached opacity of 100%. */
+ /**
+ * Packed value for a color of 'none' and a cached opacity of 100%.
+ *
+ * @hide
+ */
private static final int COLOR_NONE_OPAQUE = 0x000000FF;
- /** Packed value for an unspecified color and opacity. */
- private static final int COLOR_UNSPECIFIED = 0x000001FF;
+ /**
+ * Packed value for a color of 'default' and opacity of 100%.
+ *
+ * @hide
+ */
+ public static final int COLOR_UNSPECIFIED = 0x00FFFFFF;
private static final CaptionStyle WHITE_ON_BLACK;
private static final CaptionStyle BLACK_ON_WHITE;
@@ -350,11 +358,11 @@ public class CaptioningManager {
private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor,
int windowColor, String rawTypeface) {
- mHasForegroundColor = foregroundColor != COLOR_UNSPECIFIED;
- mHasBackgroundColor = backgroundColor != COLOR_UNSPECIFIED;
+ mHasForegroundColor = hasColor(foregroundColor);
+ mHasBackgroundColor = hasColor(backgroundColor);
mHasEdgeType = edgeType != EDGE_TYPE_UNSPECIFIED;
- mHasEdgeColor = edgeColor != COLOR_UNSPECIFIED;
- mHasWindowColor = windowColor != COLOR_UNSPECIFIED;
+ mHasEdgeColor = hasColor(edgeColor);
+ mHasWindowColor = hasColor(windowColor);
// Always use valid colors, even when no override is specified, to
// ensure backwards compatibility with apps targeting KitKat MR2.
@@ -368,6 +376,20 @@ public class CaptioningManager {
}
/**
+ * Returns whether a packed color indicates a non-default value.
+ *
+ * @param packedColor the packed color value
+ * @return {@code true} if a non-default value is specified
+ * @hide
+ */
+ public static boolean hasColor(int packedColor) {
+ // Matches the color packing code from Settings. "Default" packed
+ // colors are indicated by zero alpha and non-zero red/blue. The
+ // cached alpha value used by Settings is stored in green.
+ return (packedColor >>> 24) != 0 || (packedColor & 0xFFFF00) == 0;
+ }
+
+ /**
* Applies a caption style, overriding any properties that are specified
* in the overlay caption.
*
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 2f5c9e2..de8ccc1 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -298,14 +298,27 @@ public class WebViewClient {
* Notify the host application to handle a SSL client certificate
* request. The host application is responsible for showing the UI
* if desired and providing the keys. There are three ways to
- * respond: proceed(), cancel() or ignore(). Webview remembers the
- * response if proceed() or cancel() is called and does not
- * call onReceivedClientCertRequest() again for the same host and port
- * pair. Webview does not remember the response if ignore() is called.
+ * respond: proceed(), cancel() or ignore(). Webview stores the response
+ * in memory (for the life of the application) if proceed() or cancel() is
+ * called and does not call onReceivedClientCertRequest() again for the
+ * same host and port pair. Webview does not store the response if ignore()
+ * is called.
*
* This method is called on the UI thread. During the callback, the
* connection is suspended.
*
+ * For most use cases, the application program should implement the
+ * {@link android.security.KeyChainAliasCallback} interface and pass it to
+ * {@link android.security.KeyChain#choosePrivateKeyAlias} to start an
+ * activity for the user to choose the proper alias. The keychain activity will
+ * provide the alias through the callback method in the implemented interface. Next
+ * the application should create an async task to call
+ * {@link android.security.KeyChain#getPrivateKey} to receive the key.
+ *
+ * An example implementation of client certificates can be seen at
+ * <A href="https://android.googlesource.com/platform/packages/apps/Browser/+/android-5.1.1_r1/src/com/android/browser/Tab.java">
+ * AOSP Browser</a>
+ *
* The default behavior is to cancel, returning no client certificate.
*
* @param view The WebView that is initiating the callback
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 9ca59f1..e050bda 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -623,7 +623,7 @@ public class Editor {
// One is the true focus lost where suggestions pop-up (if any) should be dismissed, and the
// other is an side effect of showing the suggestions pop-up itself. We use isShowingUp()
// to distinguish one from the other.
- if (mSuggestionsPopupWindow != null && ((mTextView instanceof ExtractEditText) ||
+ if (mSuggestionsPopupWindow != null && ((mTextView.isInExtractedMode()) ||
!mSuggestionsPopupWindow.isShowingUp())) {
// Should be done before hide insertion point controller since it triggers a show of it
mSuggestionsPopupWindow.hide();
@@ -640,7 +640,7 @@ public class Editor {
mTextView.removeAdjacentSuggestionSpans(end);
if (mTextView.isTextEditable() && mTextView.isSuggestionsEnabled() &&
- !(mTextView instanceof ExtractEditText)) {
+ !(mTextView.isInExtractedMode())) {
if (mSpellChecker == null && createSpellChecker) {
mSpellChecker = new SpellChecker(mTextView);
}
@@ -1063,7 +1063,7 @@ public class Editor {
// ExtractEditText clears focus, which gives focus to the ExtractEditText.
// This special case ensure that we keep current selection in that case.
// It would be better to know why the DecorView does not have focus at that time.
- if (((mTextView instanceof ExtractEditText) || mSelectionMoved) &&
+ if (((mTextView.isInExtractedMode()) || mSelectionMoved) &&
selStart >= 0 && selEnd >= 0) {
/*
* Someone intentionally set the selection, so let them
@@ -1099,7 +1099,7 @@ public class Editor {
// Don't leave us in the middle of a batch edit.
mTextView.onEndBatchEdit();
- if (mTextView instanceof ExtractEditText) {
+ if (mTextView.isInExtractedMode()) {
// terminateTextSelectionMode removes selection, which we want to keep when
// ExtractEditText goes out of focus.
final int selStart = mTextView.getSelectionStart();
@@ -1825,7 +1825,7 @@ public class Editor {
}
private boolean extractedTextModeWillBeStarted() {
- if (!(mTextView instanceof ExtractEditText)) {
+ if (!(mTextView.isInExtractedMode())) {
final InputMethodManager imm = InputMethodManager.peekInstance();
return imm != null && imm.isFullscreenMode();
}
@@ -4657,7 +4657,9 @@ public class Editor {
mEndHandle.showAtLocation(endOffset);
// No longer the first dragging motion, reset.
- startSelectionActionMode();
+ if (!(mTextView.isInExtractedMode())) {
+ startSelectionActionMode();
+ }
mDragAcceleratorActive = false;
mStartOffset = -1;
mSwitchedLines = false;
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 451e493..98bfd7d 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -731,7 +731,7 @@ public class OverScroller {
// mStartTime has been set
mFinished = false;
mState = CUBIC;
- mStart = start;
+ mCurrentPosition = mStart = start;
mFinal = end;
final int delta = start - end;
mDeceleration = getDeceleration(delta);
@@ -797,7 +797,9 @@ public class OverScroller {
private void fitOnBounceCurve(int start, int end, int velocity) {
// Simulate a bounce that started from edge
final float durationToApex = - velocity / mDeceleration;
- final float distanceToApex = velocity * velocity / 2.0f / Math.abs(mDeceleration);
+ // The float cast below is necessary to avoid integer overflow.
+ final float velocitySquared = (float) velocity * velocity;
+ final float distanceToApex = velocitySquared / 2.0f / Math.abs(mDeceleration);
final float distanceToEdge = Math.abs(end - start);
final float totalDuration = (float) Math.sqrt(
2.0 * (distanceToApex + distanceToEdge) / Math.abs(mDeceleration));
@@ -848,12 +850,14 @@ public class OverScroller {
private void onEdgeReached() {
// mStart, mVelocity and mStartTime were adjusted to their values when edge was reached.
- float distance = mVelocity * mVelocity / (2.0f * Math.abs(mDeceleration));
+ // The float cast below is necessary to avoid integer overflow.
+ final float velocitySquared = (float) mVelocity * mVelocity;
+ float distance = velocitySquared / (2.0f * Math.abs(mDeceleration));
final float sign = Math.signum(mVelocity);
if (distance > mOver) {
// Default deceleration is not sufficient to slow us down before boundary
- mDeceleration = - sign * mVelocity * mVelocity / (2.0f * mOver);
+ mDeceleration = - sign * velocitySquared / (2.0f * mOver);
distance = mOver;
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index affc5da..339038e 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -522,7 +522,7 @@ public class RelativeLayout extends ViewGroup {
View baselineView = null;
LayoutParams baselineParams = null;
for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
if (baselineView == null || baselineParams == null
@@ -548,9 +548,9 @@ public class RelativeLayout extends ViewGroup {
if (offsetHorizontalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) {
centerHorizontal(child, params, width);
@@ -578,9 +578,9 @@ public class RelativeLayout extends ViewGroup {
if (offsetVerticalAxis) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
final int[] rules = params.getRules(layoutDirection);
if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) {
centerVertical(child, params, height);
@@ -607,9 +607,9 @@ public class RelativeLayout extends ViewGroup {
final int verticalOffset = contentBounds.top - top;
if (horizontalOffset != 0 || verticalOffset != 0) {
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE && child != ignore) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
if (horizontalGravity) {
params.mLeft += horizontalOffset;
params.mRight += horizontalOffset;
@@ -626,9 +626,9 @@ public class RelativeLayout extends ViewGroup {
if (isLayoutRtl()) {
final int offsetWidth = myWidth - width;
for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
+ final View child = views[i];
if (child.getVisibility() != GONE) {
- LayoutParams params = (LayoutParams) child.getLayoutParams();
+ final LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mLeft -= offsetWidth;
params.mRight -= offsetWidth;
}
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index fdabe91..6abd129 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -711,9 +711,7 @@ public class Spinner extends AbsSpinner implements OnClickListener {
lp = generateDefaultLayoutParams();
}
- if (addChild) {
- addViewInLayout(child, 0, lp);
- }
+ addViewInLayout(child, 0, lp);
child.setSelected(hasFocus());
if (mDisableChildrenWhenDisabled) {
@@ -743,6 +741,10 @@ public class Spinner extends AbsSpinner implements OnClickListener {
childRight = childLeft + width;
child.layout(childLeft, childTop, childRight, childBottom);
+
+ if (!addChild) {
+ removeViewInLayout(child);
+ }
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index c538dc2..f733eab 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8637,6 +8637,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * @return true if this TextView is specialized for showing and interacting with the extracted
+ * text in a full-screen input method.
+ * @hide
+ */
+ public boolean isInExtractedMode() {
+ return false;
+ }
+
+ /**
* This is a temporary method. Future versions may support multi-locale text.
* Caveat: This method may not return the latest spell checker locale, but this should be
* acceptable and it's more important to make this method asynchronous.