diff options
Diffstat (limited to 'core/java')
21 files changed, 263 insertions, 49 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d28ff51..f2c907a 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -3975,6 +3975,8 @@ public class DevicePolicyManager { * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li> * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li> + * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards. + * </li> * </ul> * <p>Changing the following settings has no effect as of * {@link android.os.Build.VERSION_CODES#MNC}: diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 50e1a68..e7deae8 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -42,12 +42,12 @@ import java.util.List; public class SystemSensorManager extends SensorManager { private static native void nativeClassInit(); private static native long nativeCreate(String opPackageName); - private static native int nativeGetNextSensor(long nativeInstance, Sensor sensor, int next); + private static native boolean nativeGetSensorAtIndex(long nativeInstance, + Sensor sensor, int index); private static native boolean nativeIsDataInjectionEnabled(long nativeInstance); private static boolean sSensorModuleInitialized = false; private static InjectEventQueue mInjectEventQueue = null; - private static boolean mDataInjectionMode = false; private final Object mLock = new Object(); @@ -81,15 +81,12 @@ public class SystemSensorManager extends SensorManager { } // initialize the sensor list - int i = 0; - do { + for (int index = 0;;++index) { Sensor sensor = new Sensor(); - i = nativeGetNextSensor(mNativeInstance, sensor, i); - if (i >= 0) { - mFullSensorsList.add(sensor); - mHandleToSensor.append(sensor.getHandle(), sensor); - } - } while (i > 0); + if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break; + mFullSensorsList.add(sensor); + mHandleToSensor.append(sensor.getHandle(), sensor); + } } @@ -235,7 +232,6 @@ public class SystemSensorManager extends SensorManager { Log.e(TAG, "Data Injection mode not enabled"); return false; } - mDataInjectionMode = true; // Initialize a client for data_injection. if (mInjectEventQueue == null) { mInjectEventQueue = new InjectEventQueue(mMainLooper, this); @@ -254,7 +250,7 @@ public class SystemSensorManager extends SensorManager { protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, long timestamp) { synchronized (mLock) { - if (!mDataInjectionMode) { + if (mInjectEventQueue == null) { Log.e(TAG, "Data injection mode not activated before calling injectSensorData"); return false; } @@ -264,7 +260,6 @@ public class SystemSensorManager extends SensorManager { if (ret != 0) { mInjectEventQueue.dispose(); mInjectEventQueue = null; - mDataInjectionMode = false; } return ret == 0; } diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index c547b06..62ebfb3 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -497,8 +497,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess * capture requests get the input images from, rather than the camera device. The application - * can create a {@link android.media.ImageWriter} with this input {@link Surface} and use it to - * provide input images for reprocess capture requests.</p> + * can create a {@link android.media.ImageWriter ImageWriter} with this input {@link Surface} + * and use it to provide input images for reprocess capture requests. When the reprocessable + * capture session is closed, the input {@link Surface} is abandoned and becomes invalid.</p> * * @return The {@link Surface} where reprocessing capture requests get the input images from. If * this is not a reprocess capture session, {@code null} will be returned. diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index e8dbc5b..f7c6274 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -488,9 +488,13 @@ public abstract class CameraMetadata<TKey> { * <li>{@link CaptureRequest#EDGE_MODE android.edge.mode}</li> * </ul> * </li> + * <li>{@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes} and + * {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes} will both list ZERO_SHUTTER_LAG as a supported mode.</li> * </ul> * + * @see CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES * @see CaptureRequest#EDGE_MODE + * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES * @see CaptureRequest#NOISE_REDUCTION_MODE * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS @@ -593,9 +597,13 @@ public abstract class CameraMetadata<TKey> { * <li>{@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}</li> * </ul> * </li> + * <li>{@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes} and + * {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes} will both list ZERO_SHUTTER_LAG as a supported mode.</li> * </ul> * + * @see CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES * @see CaptureRequest#EDGE_MODE + * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES * @see CaptureRequest#NOISE_REDUCTION_MODE * @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL @@ -1999,6 +2007,30 @@ public abstract class CameraMetadata<TKey> { */ public static final int EDGE_MODE_HIGH_QUALITY = 2; + /** + * <p>Edge enhancement is applied at different levels for different output streams, + * based on resolution. Streams at maximum recording resolution (see {@link android.hardware.camera2.CameraDevice#createCaptureSession }) or below have + * edge enhancement applied, while higher-resolution streams have no edge enhancement + * applied. The level of edge enhancement for low-resolution streams is tuned so that + * frame rate is not impacted, and the quality is equal to or better than FAST (since it + * is only applied to lower-resolution outputs, quality may improve from FAST).</p> + * <p>This mode is intended to be used by applications operating in a zero-shutter-lag mode + * with YUV or PRIVATE reprocessing, where the application continuously captures + * high-resolution intermediate buffers into a circular buffer, from which a final image is + * produced via reprocessing when a user takes a picture. For such a use case, the + * high-resolution buffers must not have edge enhancement applied to maximize efficiency of + * preview and to avoid double-applying enhancement when reprocessed, while low-resolution + * buffers (used for recording or preview, generally) need edge enhancement applied for + * reasonable preview quality.</p> + * <p>This mode is guaranteed to be supported by devices that support either the + * YUV_REPROCESSING or PRIVATE_REPROCESSING capabilities + * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} lists either of those capabilities).</p> + * + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + * @see CaptureRequest#EDGE_MODE + */ + public static final int EDGE_MODE_ZERO_SHUTTER_LAG = 3; + // // Enumeration values for CaptureRequest#FLASH_MODE // @@ -2104,6 +2136,31 @@ public abstract class CameraMetadata<TKey> { */ public static final int NOISE_REDUCTION_MODE_MINIMAL = 3; + /** + * <p>Noise reduction is applied at different levels for different output streams, + * based on resolution. Streams at maximum recording resolution (see {@link android.hardware.camera2.CameraDevice#createCaptureSession }) or below have noise + * reduction applied, while higher-resolution streams have MINIMAL (if supported) or no + * noise reduction applied (if MINIMAL is not supported.) The degree of noise reduction + * for low-resolution streams is tuned so that frame rate is not impacted, and the quality + * is equal to or better than FAST (since it is only applied to lower-resolution outputs, + * quality may improve from FAST).</p> + * <p>This mode is intended to be used by applications operating in a zero-shutter-lag mode + * with YUV or PRIVATE reprocessing, where the application continuously captures + * high-resolution intermediate buffers into a circular buffer, from which a final image is + * produced via reprocessing when a user takes a picture. For such a use case, the + * high-resolution buffers must not have noise reduction applied to maximize efficiency of + * preview and to avoid over-applying noise filtering when reprocessing, while + * low-resolution buffers (used for recording or preview, generally) need noise reduction + * applied for reasonable preview quality.</p> + * <p>This mode is guaranteed to be supported by devices that support either the + * YUV_REPROCESSING or PRIVATE_REPROCESSING capabilities + * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} lists either of those capabilities).</p> + * + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + * @see CaptureRequest#NOISE_REDUCTION_MODE + */ + public static final int NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG = 4; + // // Enumeration values for CaptureRequest#SENSOR_TEST_PATTERN_MODE // diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 5d7da79..6d8cc54 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -1583,7 +1583,14 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * will be applied. HIGH_QUALITY mode indicates that the * camera device will use the highest-quality enhancement algorithms, * even if it slows down capture rate. FAST means the camera device will - * not slow down capture rate when applying edge enhancement.</p> + * not slow down capture rate when applying edge enhancement. Every output stream will + * have a similar amount of enhancement applied.</p> + * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular + * buffer of high-resolution images during preview and reprocess image(s) from that buffer + * into a final capture when triggered by the user. In this mode, the camera device applies + * edge enhancement to low-resolution streams (below maximum recording resolution) to + * maximize preview quality, but does not apply edge enhancement to high-resolution streams, + * since those will be reprocessed later if necessary.</p> * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively. * The camera device may adjust its internal noise reduction parameters for best @@ -1593,6 +1600,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <li>{@link #EDGE_MODE_OFF OFF}</li> * <li>{@link #EDGE_MODE_FAST FAST}</li> * <li>{@link #EDGE_MODE_HIGH_QUALITY HIGH_QUALITY}</li> + * <li>{@link #EDGE_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li> * </ul></p> * <p><b>Available values for this device:</b><br> * {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes}</p> @@ -1607,6 +1615,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * @see #EDGE_MODE_OFF * @see #EDGE_MODE_FAST * @see #EDGE_MODE_HIGH_QUALITY + * @see #EDGE_MODE_ZERO_SHUTTER_LAG */ @PublicKey public static final Key<Integer> EDGE_MODE = @@ -1993,7 +2002,14 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * will be applied. HIGH_QUALITY mode indicates that the camera device * will use the highest-quality noise filtering algorithms, * even if it slows down capture rate. FAST means the camera device will not - * slow down capture rate when applying noise filtering.</p> + * slow down capture rate when applying noise filtering. Every output stream will + * have a similar amount of enhancement applied.</p> + * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular + * buffer of high-resolution images during preview and reprocess image(s) from that buffer + * into a final capture when triggered by the user. In this mode, the camera device applies + * noise reduction to low-resolution streams (below maximum recording resolution) to maximize + * preview quality, but does not apply noise reduction to high-resolution streams, since + * those will be reprocessed later if necessary.</p> * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera device * will apply FAST/HIGH_QUALITY YUV domain noise reduction, respectively. The camera device * may adjust the noise reduction parameters for best image quality based on the @@ -2004,6 +2020,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <li>{@link #NOISE_REDUCTION_MODE_FAST FAST}</li> * <li>{@link #NOISE_REDUCTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li> * <li>{@link #NOISE_REDUCTION_MODE_MINIMAL MINIMAL}</li> + * <li>{@link #NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li> * </ul></p> * <p><b>Available values for this device:</b><br> * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}</p> @@ -2019,6 +2036,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * @see #NOISE_REDUCTION_MODE_FAST * @see #NOISE_REDUCTION_MODE_HIGH_QUALITY * @see #NOISE_REDUCTION_MODE_MINIMAL + * @see #NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG */ @PublicKey public static final Key<Integer> NOISE_REDUCTION_MODE = diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index e071409..f7cf185 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -2095,7 +2095,14 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * will be applied. HIGH_QUALITY mode indicates that the * camera device will use the highest-quality enhancement algorithms, * even if it slows down capture rate. FAST means the camera device will - * not slow down capture rate when applying edge enhancement.</p> + * not slow down capture rate when applying edge enhancement. Every output stream will + * have a similar amount of enhancement applied.</p> + * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular + * buffer of high-resolution images during preview and reprocess image(s) from that buffer + * into a final capture when triggered by the user. In this mode, the camera device applies + * edge enhancement to low-resolution streams (below maximum recording resolution) to + * maximize preview quality, but does not apply edge enhancement to high-resolution streams, + * since those will be reprocessed later if necessary.</p> * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively. * The camera device may adjust its internal noise reduction parameters for best @@ -2105,6 +2112,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <li>{@link #EDGE_MODE_OFF OFF}</li> * <li>{@link #EDGE_MODE_FAST FAST}</li> * <li>{@link #EDGE_MODE_HIGH_QUALITY HIGH_QUALITY}</li> + * <li>{@link #EDGE_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li> * </ul></p> * <p><b>Available values for this device:</b><br> * {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes}</p> @@ -2119,6 +2127,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * @see #EDGE_MODE_OFF * @see #EDGE_MODE_FAST * @see #EDGE_MODE_HIGH_QUALITY + * @see #EDGE_MODE_ZERO_SHUTTER_LAG */ @PublicKey public static final Key<Integer> EDGE_MODE = @@ -2777,7 +2786,14 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * will be applied. HIGH_QUALITY mode indicates that the camera device * will use the highest-quality noise filtering algorithms, * even if it slows down capture rate. FAST means the camera device will not - * slow down capture rate when applying noise filtering.</p> + * slow down capture rate when applying noise filtering. Every output stream will + * have a similar amount of enhancement applied.</p> + * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular + * buffer of high-resolution images during preview and reprocess image(s) from that buffer + * into a final capture when triggered by the user. In this mode, the camera device applies + * noise reduction to low-resolution streams (below maximum recording resolution) to maximize + * preview quality, but does not apply noise reduction to high-resolution streams, since + * those will be reprocessed later if necessary.</p> * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera device * will apply FAST/HIGH_QUALITY YUV domain noise reduction, respectively. The camera device * may adjust the noise reduction parameters for best image quality based on the @@ -2788,6 +2804,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <li>{@link #NOISE_REDUCTION_MODE_FAST FAST}</li> * <li>{@link #NOISE_REDUCTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li> * <li>{@link #NOISE_REDUCTION_MODE_MINIMAL MINIMAL}</li> + * <li>{@link #NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li> * </ul></p> * <p><b>Available values for this device:</b><br> * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}</p> @@ -2803,6 +2820,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * @see #NOISE_REDUCTION_MODE_FAST * @see #NOISE_REDUCTION_MODE_HIGH_QUALITY * @see #NOISE_REDUCTION_MODE_MINIMAL + * @see #NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG */ @PublicKey public static final Key<Integer> NOISE_REDUCTION_MODE = diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 9cf3759..acad496 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -83,7 +83,8 @@ oneway interface IWindow { * The window is beginning to animate. The application should stop drawing frames until the * window is not animating anymore, indicated by being called {@link #windowEndAnimating}. * - * @param remainingFrameCount how many frames the app might still draw before stopping drawing + * @param remainingFrameCount how many frames the app might still draw before stopping drawing; + * pass -1 to let it continue drawing */ void onAnimationStarted(int remainingFrameCount); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 63dd492..de61c31 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -15366,7 +15366,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize(); if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) { if (width > 0 && height > 0) { - Log.w(VIEW_LOG_TAG, "View too large to fit into drawing cache, needs " + Log.w(VIEW_LOG_TAG, getClass().getSimpleName() + " not displayed because it is" + + " too large to fit into a software layer (or drawing cache), needs " + projectedBitmapSize + " bytes, only " + drawingCacheSize + " available"); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 6d0d788..9b1db57 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2367,8 +2367,7 @@ public final class ViewRootImpl implements ViewParent, * @hide */ void outputDisplayList(View view) { - RenderNode renderNode = view.updateDisplayListIfDirty(); - renderNode.output(); + view.mRenderNode.output(); } /** @@ -5327,7 +5326,7 @@ public final class ViewRootImpl implements ViewParent, } public void handleDispatchWindowAnimationStarted(int remainingFrameCount) { - if (!mDrawDuringWindowsAnimating) { + if (!mDrawDuringWindowsAnimating && remainingFrameCount != -1) { mRemainingFrameCount = remainingFrameCount; mWindowsAnimating = true; } diff --git a/core/java/android/webkit/PermissionRequest.java b/core/java/android/webkit/PermissionRequest.java index 6ad639c..18ec334 100644 --- a/core/java/android/webkit/PermissionRequest.java +++ b/core/java/android/webkit/PermissionRequest.java @@ -26,6 +26,16 @@ import android.net.Uri; * * Either {@link #grant(String[]) grant()} or {@link #deny()} must be called in UI * thread to respond to the request. + * + * New protected resources whose names are not defined here may be requested in + * future versions of WebView, even when running on an older Android release. To + * avoid unintentionally granting requests for new permissions, you should pass the + * specific permissions you intend to grant to {@link #grant(String[]) grant()}, + * and avoid writing code like this example: + * <pre> + * permissionRequest.grant(permissionRequest.getResources()) // This is wrong!!! + * </pre> + * See the WebView's release notes for information about new protected resources. */ public abstract class PermissionRequest { /** @@ -43,6 +53,15 @@ public abstract class PermissionRequest { */ public final static String RESOURCE_PROTECTED_MEDIA_ID = "android.webkit.resource.PROTECTED_MEDIA_ID"; + /** + * Resource will allow sysex messages to be sent to or received from MIDI devices. These + * messages are privileged operations, e.g. modifying sound libraries and sampling data, or + * even updating the MIDI device's firmware. + * + * Permission may be requested for this resource in API levels 21 and above, if the Android + * device has been updated to WebView 45 or above. + */ + public final static String RESOURCE_MIDI_SYSEX = "android.webkit.resource.MIDI_SYSEX"; /** * Call this method to get the origin of the web page which is trying to access diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 8bf6992..b2b98db 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -6605,8 +6605,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te void addScrapView(View scrap, int position) { final AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams(); if (lp == null) { - // Can't recycle, skip the scrap heap. - getSkippedScrap().add(scrap); + // Can't recycle, but we don't know anything about the view. + // Ignore it completely. return; } @@ -6616,8 +6616,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te // should otherwise not be recycled. final int viewType = lp.viewType; if (!shouldRecycleViewType(viewType)) { - // Can't recycle, skip the scrap heap. - getSkippedScrap().add(scrap); + // Can't recycle. If it's not a header or footer, which have + // special handling and should be ignored, then skip the scrap + // heap and we'll fully detach the view later. + if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { + getSkippedScrap().add(scrap); + } return; } diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 1158d1e..7c4ff18 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1121,7 +1121,6 @@ public class Editor { if (mTemporaryDetach) mPreserveDetachedSelection = false; downgradeEasyCorrectionSpans(); } - // No need to create the controller if (mSelectionModifierCursorController != null) { mSelectionModifierCursorController.resetTouchOffsets(); @@ -1793,7 +1792,7 @@ public class Editor { * * @return true if there already was a selection or if the current word was selected. */ - private boolean checkFieldAndSelectCurrentWord() { + boolean checkFieldAndSelectCurrentWord() { if (!mTextView.canSelectText() || !mTextView.requestFocus()) { Log.w(TextView.LOG_TAG, "TextView does not support text selection. Selection cancelled."); @@ -1840,7 +1839,7 @@ public class Editor { return selectionStarted; } - private boolean extractedTextModeWillBeStarted() { + boolean extractedTextModeWillBeStarted() { if (!(mTextView.isInExtractedMode())) { final InputMethodManager imm = InputMethodManager.peekInstance(); return imm != null && imm.isFullscreenMode(); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 6b8abab..43edc44 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5232,7 +5232,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // - onFocusChanged cannot start it when focus is given to a view with selected text (after // a screen rotation) since layout is not yet initialized at that point. if (mEditor != null && mEditor.mCreatedWithASelection) { - mEditor.startSelectionActionMode(); + if (mEditor.extractedTextModeWillBeStarted()) { + mEditor.checkFieldAndSelectCurrentWord(); + } else { + mEditor.startSelectionActionMode(); + } mEditor.mCreatedWithASelection = false; } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 1b55557..c4f57c7 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -59,6 +59,8 @@ import com.android.internal.R; import com.android.internal.logging.MetricsLogger; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; public class ChooserActivity extends ResolverActivity { @@ -97,7 +99,10 @@ public class ChooserActivity extends ResolverActivity { + " Have you considered returning results faster?"); break; } - mChooserListAdapter.addServiceResults(sri.originalTarget, sri.resultTargets); + if (sri.resultTargets != null) { + mChooserListAdapter.addServiceResults(sri.originalTarget, + sri.resultTargets); + } unbindService(sri.connection); mServiceConnections.remove(sri.connection); if (mServiceConnections.isEmpty()) { @@ -485,10 +490,13 @@ public class ChooserActivity extends ResolverActivity { private Drawable mDisplayIcon; private final Intent mFillInIntent; private final int mFillInFlags; + private final float mModifiedScore; - public ChooserTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget) { + public ChooserTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget, + float modifiedScore) { mSourceInfo = sourceInfo; mChooserTarget = chooserTarget; + mModifiedScore = modifiedScore; if (sourceInfo != null) { final ResolveInfo ri = sourceInfo.getResolveInfo(); if (ri != null) { @@ -520,6 +528,11 @@ public class ChooserActivity extends ResolverActivity { mDisplayIcon = other.mDisplayIcon; mFillInIntent = fillInIntent; mFillInFlags = flags; + mModifiedScore = other.mModifiedScore; + } + + public float getModifiedScore() { + return mModifiedScore; } @Override @@ -632,9 +645,16 @@ public class ChooserActivity extends ResolverActivity { public static final int TARGET_SERVICE = 1; public static final int TARGET_STANDARD = 2; + private static final int MAX_SERVICE_TARGETS = 8; + private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>(); private final List<TargetInfo> mCallerTargets = new ArrayList<>(); + private float mLateFee = 1.f; + + private final BaseChooserTargetComparator mBaseTargetComparator + = new BaseChooserTargetComparator(); + public ChooserListAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) { @@ -703,12 +723,12 @@ public class ChooserActivity extends ResolverActivity { @Override public int getCount() { - return super.getCount() + mServiceTargets.size() + mCallerTargets.size(); + return super.getCount() + getServiceTargetCount() + getCallerTargetCount(); } @Override public int getUnfilteredCount() { - return super.getUnfilteredCount() + mServiceTargets.size() + mCallerTargets.size(); + return super.getUnfilteredCount() + getServiceTargetCount() + getCallerTargetCount(); } public int getCallerTargetCount() { @@ -716,7 +736,7 @@ public class ChooserActivity extends ResolverActivity { } public int getServiceTargetCount() { - return mServiceTargets.size(); + return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS); } public int getStandardTargetCount() { @@ -726,13 +746,13 @@ public class ChooserActivity extends ResolverActivity { public int getPositionTargetType(int position) { int offset = 0; - final int callerTargetCount = mCallerTargets.size(); + final int callerTargetCount = getCallerTargetCount(); if (position < callerTargetCount) { return TARGET_CALLER; } offset += callerTargetCount; - final int serviceTargetCount = mServiceTargets.size(); + final int serviceTargetCount = getServiceTargetCount(); if (position - offset < serviceTargetCount) { return TARGET_SERVICE; } @@ -755,13 +775,13 @@ public class ChooserActivity extends ResolverActivity { public TargetInfo targetInfoForPosition(int position, boolean filtered) { int offset = 0; - final int callerTargetCount = mCallerTargets.size(); + final int callerTargetCount = getCallerTargetCount(); if (position < callerTargetCount) { return mCallerTargets.get(position); } offset += callerTargetCount; - final int serviceTargetCount = mServiceTargets.size(); + final int serviceTargetCount = getServiceTargetCount(); if (position - offset < serviceTargetCount) { return mServiceTargets.get(position - offset); } @@ -774,15 +794,49 @@ public class ChooserActivity extends ResolverActivity { public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) { if (DEBUG) Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size() + " targets"); + final float parentScore = getScore(origTarget); + Collections.sort(targets, mBaseTargetComparator); + float lastScore = 0; for (int i = 0, N = targets.size(); i < N; i++) { - mServiceTargets.add(new ChooserTargetInfo(origTarget, targets.get(i))); + final ChooserTarget target = targets.get(i); + float targetScore = target.getScore(); + targetScore *= parentScore; + targetScore *= mLateFee; + if (i > 0 && targetScore >= lastScore) { + // Apply a decay so that the top app can't crowd out everything else. + // This incents ChooserTargetServices to define what's truly better. + targetScore = lastScore * 0.95f; + } + insertServiceTarget(new ChooserTargetInfo(origTarget, target, targetScore)); + + if (DEBUG) { + Log.d(TAG, " => " + target.toString() + " score=" + targetScore + + " base=" + target.getScore() + + " lastScore=" + lastScore + + " parentScore=" + parentScore + + " lateFee=" + mLateFee); + } + + lastScore = targetScore; } - // TODO: Maintain sort by ranking scores. + mLateFee *= 0.95f; notifyDataSetChanged(); } + private void insertServiceTarget(ChooserTargetInfo chooserTargetInfo) { + final float newScore = chooserTargetInfo.getModifiedScore(); + for (int i = 0, N = mServiceTargets.size(); i < N; i++) { + final ChooserTargetInfo serviceTarget = mServiceTargets.get(i); + if (newScore > serviceTarget.getModifiedScore()) { + mServiceTargets.add(i, chooserTargetInfo); + return; + } + } + mServiceTargets.add(chooserTargetInfo); + } + private void pruneServiceTargets() { if (DEBUG) Log.d(TAG, "pruneServiceTargets"); for (int i = mServiceTargets.size() - 1; i >= 0; i--) { @@ -795,6 +849,14 @@ public class ChooserActivity extends ResolverActivity { } } + static class BaseChooserTargetComparator implements Comparator<ChooserTarget> { + @Override + public int compare(ChooserTarget lhs, ChooserTarget rhs) { + // Descending order + return (int) Math.signum(lhs.getScore() - rhs.getScore()); + } + } + class ChooserRowAdapter extends BaseAdapter { private ChooserListAdapter mChooserListAdapter; private final LayoutInflater mLayoutInflater; diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java index 4a468be..b0e0373 100644 --- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java +++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java @@ -18,7 +18,7 @@ package com.android.internal.app; import com.android.internal.R; -import android.app.AlertDialog; +import android.app.Dialog; import android.app.MediaRouteActionProvider; import android.app.MediaRouteButton; import android.content.Context; @@ -46,7 +46,7 @@ import android.widget.SeekBar; * * TODO: Move this back into the API, as in the support library media router. */ -public class MediaRouteControllerDialog extends AlertDialog { +public class MediaRouteControllerDialog extends Dialog { // Time to wait before updating the volume when the user lets go of the seek bar // to allow the route provider time to propagate the change and publish a new // route descriptor. @@ -134,6 +134,8 @@ public class MediaRouteControllerDialog extends AlertDialog { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().requestFeature(Window.FEATURE_LEFT_ICON); + setContentView(R.layout.media_route_controller_dialog); mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout); diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index e5ff51c..7bc18f3 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -1142,6 +1142,10 @@ public class ResolverActivity extends Activity { return mFilterLastUsed && mLastChosenPosition >= 0; } + public float getScore(DisplayResolveInfo target) { + return mResolverComparator.getScore(target.getResolvedComponentName()); + } + private void rebuildList() { List<ResolvedComponentInfo> currentResolveList = null; diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java index 585cdf1..31556e2 100644 --- a/core/java/com/android/internal/app/ResolverComparator.java +++ b/core/java/com/android/internal/app/ResolverComparator.java @@ -191,6 +191,14 @@ class ResolverComparator implements Comparator<ResolvedComponentInfo> { return mCollator.compare(sa.toString().trim(), sb.toString().trim()); } + public float getScore(ComponentName name) { + final ScoredTarget target = mScoredTargets.get(name); + if (target != null) { + return target.score; + } + return 0; + } + static class ScoredTarget { public final ComponentInfo componentInfo; public float score; diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index 263e522..66fa8fc 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -43,7 +43,7 @@ public class MetricsLogger implements MetricsConstants { public static final int SYSTEM_ALERT_WINDOW_APPS = 221; public static final int DREAMING = 222; public static final int DOZING = 223; - + public static final int OVERVIEW_ACTIVITY = 224; // Temporary constants go here, to await migration to MetricsConstants. public static void visible(Context context, int category) throws IllegalArgumentException { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 8b4b994..f421189 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -183,6 +183,7 @@ public final class BatteryStatsImpl extends BatteryStats { public interface ExternalStatsSync { void scheduleSync(String reason); void scheduleWifiSync(String reason); + void scheduleCpuSyncDueToRemovedUid(int uid); } public final MyHandler mHandler; @@ -2522,13 +2523,28 @@ public final class BatteryStatsImpl extends BatteryStats { mIsolatedUids.put(isolatedUid, appUid); } - public void removeIsolatedUidLocked(int isolatedUid, int appUid) { + /** + * Schedules a read of the latest cpu times before removing the isolated UID. + * @see #removeIsolatedUidLocked(int) + */ + public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { int curUid = mIsolatedUids.get(isolatedUid, -1); if (curUid == appUid) { - mIsolatedUids.delete(isolatedUid); + if (mExternalSync != null) { + mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); + } } } + /** + * This should only be called after the cpu times have been read. + * @see #scheduleRemoveIsolatedUidLocked(int, int) + */ + public void removeIsolatedUidLocked(int isolatedUid) { + mIsolatedUids.delete(isolatedUid); + mKernelUidCpuTimeReader.removeUid(isolatedUid); + } + public int mapUid(int uid) { int isolated = mIsolatedUids.get(uid, -1); return isolated > 0 ? isolated : uid; diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index b2699f8..ef2fef0 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -45,6 +45,7 @@ public class FloatingActionMode extends ActionMode { private final Rect mPreviousContentRectOnWindow; private final int[] mViewPosition; private final int[] mPreviousViewPosition; + private final int[] mRootViewPosition; private final Rect mViewRect; private final Rect mPreviousViewRect; private final Rect mScreenRect; @@ -80,6 +81,7 @@ public class FloatingActionMode extends ActionMode { mPreviousContentRectOnWindow = new Rect(); mViewPosition = new int[2]; mPreviousViewPosition = new int[2]; + mRootViewPosition = new int[2]; mViewRect = new Rect(); mPreviousViewRect = new Rect(); mScreenRect = new Rect(); @@ -137,7 +139,9 @@ public class FloatingActionMode extends ActionMode { checkToolbarInitialized(); mOriginatingView.getLocationInWindow(mViewPosition); + mOriginatingView.getRootView().getLocationInWindow(mRootViewPosition); mOriginatingView.getGlobalVisibleRect(mViewRect); + mViewRect.offset(mRootViewPosition[0], mRootViewPosition[1]); if (!Arrays.equals(mViewPosition, mPreviousViewPosition) || !mViewRect.equals(mPreviousViewRect)) { diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index 1071e12..fc9a1a5 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -231,7 +231,7 @@ public class ResolverDrawerLayout extends ViewGroup { mInitialTouchY = mLastTouchY = y; mActivePointerId = ev.getPointerId(0); final boolean hitView = findChildUnder(mInitialTouchX, mInitialTouchY) != null; - handled = (!hitView && mOnDismissedListener != null) || mCollapsibleHeight > 0; + handled = mOnDismissedListener != null || mCollapsibleHeight > 0; mIsDragging = hitView && handled; abortAnimation(); } |