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/AssistContent.java219
-rw-r--r--core/java/android/app/AssistStructure.java1075
-rw-r--r--core/java/android/app/VoiceInteractor.java3
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java7
-rw-r--r--core/java/android/app/assist/AssistContent.java172
-rw-r--r--core/java/android/app/assist/AssistStructure.java1024
-rw-r--r--core/java/android/app/usage/UsageStatsManagerInternal.java11
-rw-r--r--core/java/android/content/AbstractThreadedSyncAdapter.java45
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl26
-rw-r--r--core/java/android/content/pm/IPackagesProvider.aidl22
-rw-r--r--core/java/android/content/pm/PermissionInfo.java8
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java22
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java56
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java15
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java13
-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.java432
-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/net/ConnectivityManager.java22
-rw-r--r--core/java/android/net/NetworkCapabilities.java9
-rw-r--r--core/java/android/os/BatteryStats.java18
-rw-r--r--core/java/android/os/Debug.java21
-rw-r--r--core/java/android/os/StrictMode.java4
-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/provider/ContactsContract.java21
-rw-r--r--core/java/android/provider/Settings.java11
-rw-r--r--core/java/android/security/keymaster/KeymasterArguments.java6
-rw-r--r--core/java/android/service/carrier/CarrierService.java20
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java13
-rw-r--r--core/java/android/text/TextUtils.java5
-rw-r--r--core/java/android/text/format/Formatter.java11
-rw-r--r--core/java/android/transition/Visibility.java43
-rw-r--r--core/java/android/util/Range.java2
-rw-r--r--core/java/android/view/MotionEvent.java11
-rw-r--r--core/java/android/view/SurfaceControl.java13
-rw-r--r--core/java/android/view/View.java10
-rw-r--r--core/java/android/view/ViewStructure.java2
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java11
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java4
-rw-r--r--core/java/android/view/accessibility/AccessibilityRecord.java57
-rw-r--r--core/java/android/view/accessibility/CaptioningManager.java36
-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.java12
50 files changed, 1993 insertions, 1684 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/AssistContent.java b/core/java/android/app/AssistContent.java
deleted file mode 100644
index ad2ba39..0000000
--- a/core/java/android/app/AssistContent.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import android.content.ClipData;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Holds information about the content an application is viewing, to hand to an
- * assistant at the user's request. This is filled in by
- * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
- * @deprecated use {@link android.app.assist.AssistContent}.
- */
-@Deprecated
-public class AssistContent {
- private boolean mIsAppProvidedIntent = false;
- private Intent mIntent;
- private String mStructuredData;
- private ClipData mClipData;
- private Uri mUri;
- private final Bundle mExtras;
-
- /**
- * @hide
- * Key name this data structure is stored in the Bundle generated by
- * {@link android.app.Activity#onProvideAssistData}.
- */
- public static final String ASSIST_KEY = "android:assist_content";
-
- /**
- * @hide
- * Retrieve the framework-generated AssistContent that is stored within
- * the Bundle filled in by {@link android.app.Activity#onProvideAssistContent}.
- */
- public static android.app.assist.AssistContent getAssistContent(Bundle assistBundle) {
- return assistBundle.getParcelable(ASSIST_KEY);
- }
-
- public AssistContent() {
- mExtras = new Bundle();
- }
-
- /**
- * @hide
- * Called by {@link android.app.ActivityThread} to set the default Intent based on
- * {@link android.app.Activity#getIntent Activity.getIntent}.
- *
- * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
- * of a web (http or https scheme) URI.</p>
- */
- public void setDefaultIntent(Intent intent) {
- mIntent = intent;
- setWebUri(null);
- if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
- Uri uri = intent.getData();
- if (uri != null) {
- if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
- setWebUri(uri);
- }
- }
- }
- }
-
- /**
- * Sets the Intent associated with the content, describing the current top-level context of
- * the activity. If this contains a reference to a piece of data related to the activity,
- * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
- * service can access it.
- */
- public void setIntent(Intent intent) {
- mIsAppProvidedIntent = true;
- mIntent = intent;
- }
-
- /**
- * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from
- * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place.
- * @hide
- */
- public Intent getIntent() {
- return mIntent;
- }
-
- /**
- * Returns whether or not the current Intent was explicitly provided in
- * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
- * the Intent was automatically set based on
- * {@link android.app.Activity#getIntent Activity.getIntent}.
- */
- public boolean isAppProvidedIntent() {
- return mIsAppProvidedIntent;
- }
-
- /**
- * Optional additional content items that are involved with
- * the current UI. Access to this content will be granted to the assistant as if you
- * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
- */
- public void setClipData(ClipData clip) {
- mClipData = clip;
- }
-
- /**
- * Return the current {@link #setClipData}, which you can modify in-place.
- */
- public ClipData getClipData() {
- return mClipData;
- }
-
- /**
- * Sets optional structured data regarding the content being viewed. The provided data
- * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
- * <a href="http://schema.org/">schema.org</a> vocabulary.
- */
- public void setStructuredData(String structuredData) {
- mStructuredData = structuredData;
- }
-
- /**
- * Returns the current {@link #setStructuredData}.
- */
- public String getStructuredData() {
- return mStructuredData;
- }
-
- /**
- * Set a web URI associated with the current data being shown to the user.
- * This URI could be opened in a web browser, or in the app as an
- * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
- * being displayed by it. The URI here should be something that is transportable
- * off the device into other environments to acesss the same data as is currently
- * being shown in the app; if the app does not have such a representation, it should
- * leave the null and only report the local intent and clip data.
- */
- public void setWebUri(Uri uri) {
- mUri = uri;
- }
-
- /**
- * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
- * there is none.
- */
- public Uri getWebUri() {
- return mUri;
- }
-
- /**
- * Return Bundle for extra vendor-specific data that can be modified and examined.
- */
- public Bundle getExtras() {
- return mExtras;
- }
-
- /** @hide */
- public AssistContent(Parcel in) {
- if (in.readInt() != 0) {
- mIntent = Intent.CREATOR.createFromParcel(in);
- }
- if (in.readInt() != 0) {
- mClipData = ClipData.CREATOR.createFromParcel(in);
- }
- if (in.readInt() != 0) {
- mUri = Uri.CREATOR.createFromParcel(in);
- }
- if (in.readInt() != 0) {
- mStructuredData = in.readString();
- }
- mIsAppProvidedIntent = in.readInt() == 1;
- mExtras = in.readBundle();
- }
-
- /** @hide */
- public void writeToParcelInternal(Parcel dest, int flags) {
- if (mIntent != null) {
- dest.writeInt(1);
- mIntent.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- if (mClipData != null) {
- dest.writeInt(1);
- mClipData.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- if (mUri != null) {
- dest.writeInt(1);
- mUri.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- if (mStructuredData != null) {
- dest.writeInt(1);
- dest.writeString(mStructuredData);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
- dest.writeBundle(mExtras);
- }
-}
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
deleted file mode 100644
index 7f6dae5..0000000
--- a/core/java/android/app/AssistStructure.java
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import android.content.ComponentName;
-import android.graphics.Rect;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PooledStringReader;
-import android.os.PooledStringWriter;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewAssistStructure;
-import android.view.ViewRootImpl;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-
-import java.util.ArrayList;
-
-/**
- * Assist data automatically created by the platform's implementation
- * of {@link android.app.Activity#onProvideAssistData}.
- * @deprecated use {@link android.app.assist.AssistStructure}.
- */
-@Deprecated
-public class AssistStructure {
- static final String TAG = "AssistStructure";
-
- /**
- * @hide
- * Key name this data structure is stored in the Bundle generated by
- * {@link android.app.Activity#onProvideAssistData}.
- */
- public static final String ASSIST_KEY = "android:assist_structure";
-
- /** @hide */
- public boolean mHaveData;
-
- ComponentName mActivityComponent;
-
- final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
-
- final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>();
-
- /** @hide */
- public SendChannel mSendChannel;
- /** @hide */
- public IBinder mReceiveChannel;
-
- Rect mTmpRect = new Rect();
-
- static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
- static final String DESCRIPTOR = "android.app.AssistStructure";
-
- /** @hide */
- public final class SendChannel extends Binder {
- @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- if (code == TRANSACTION_XFER) {
- data.enforceInterface(DESCRIPTOR);
- writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- return true;
- } else {
- return super.onTransact(code, data, reply, flags);
- }
- }
- }
-
- final static class ViewNodeText {
- CharSequence mText;
- int mTextSelectionStart;
- int mTextSelectionEnd;
- int mTextColor;
- int mTextBackgroundColor;
- float mTextSize;
- int mTextStyle;
- String mHint;
-
- ViewNodeText() {
- }
-
- ViewNodeText(Parcel in) {
- mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- mTextSelectionStart = in.readInt();
- mTextSelectionEnd = in.readInt();
- mTextColor = in.readInt();
- mTextBackgroundColor = in.readInt();
- mTextSize = in.readFloat();
- mTextStyle = in.readInt();
- mHint = in.readString();
- }
-
- void writeToParcel(Parcel out) {
- TextUtils.writeToParcel(mText, out, 0);
- out.writeInt(mTextSelectionStart);
- out.writeInt(mTextSelectionEnd);
- out.writeInt(mTextColor);
- out.writeInt(mTextBackgroundColor);
- out.writeFloat(mTextSize);
- out.writeInt(mTextStyle);
- out.writeString(mHint);
- }
- }
-
- /**
- * Describes a window in the assist data.
- */
- static public class WindowNode {
- final int mX;
- final int mY;
- final int mWidth;
- final int mHeight;
- final CharSequence mTitle;
- final int mDisplayId;
- final ViewNode mRoot;
-
- WindowNode(AssistStructure assist, ViewRootImpl root) {
- View view = root.getView();
- Rect rect = new Rect();
- view.getBoundsOnScreen(rect);
- mX = rect.left - view.getLeft();
- mY = rect.top - view.getTop();
- mWidth = rect.width();
- mHeight = rect.height();
- mTitle = root.getTitle();
- mDisplayId = root.getDisplayId();
- mRoot = new ViewNode();
- ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false);
- if ((root.getWindowFlags()&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
- // This is a secure window, so it doesn't want a screenshot, and that
- // means we should also not copy out its view hierarchy.
- view.onProvideStructure(builder);
- builder.setAssistBlocked(true);
- return;
- }
- view.dispatchProvideStructure(builder);
- }
-
- WindowNode(Parcel in, PooledStringReader preader) {
- mX = in.readInt();
- mY = in.readInt();
- mWidth = in.readInt();
- mHeight = in.readInt();
- mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- mDisplayId = in.readInt();
- mRoot = new ViewNode(in, preader);
- }
-
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
- out.writeInt(mX);
- out.writeInt(mY);
- out.writeInt(mWidth);
- out.writeInt(mHeight);
- TextUtils.writeToParcel(mTitle, out, 0);
- out.writeInt(mDisplayId);
- mRoot.writeToParcel(out, pwriter);
- }
-
- /**
- * Returns the left edge of the window, in pixels, relative to the left
- * edge of the screen.
- */
- public int getLeft() {
- return mX;
- }
-
- /**
- * Returns the top edge of the window, in pixels, relative to the top
- * edge of the screen.
- */
- public int getTop() {
- return mY;
- }
-
- /**
- * Returns the total width of the window in pixels.
- */
- public int getWidth() {
- return mWidth;
- }
-
- /**
- * Returns the total height of the window in pixels.
- */
- public int getHeight() {
- return mHeight;
- }
-
- /**
- * Returns the title associated with the window, if it has one.
- */
- public CharSequence getTitle() {
- return mTitle;
- }
-
- /**
- * Returns the ID of the display this window is on, for use with
- * {@link android.hardware.display.DisplayManager#getDisplay DisplayManager.getDisplay()}.
- */
- public int getDisplayId() {
- return mDisplayId;
- }
-
- /**
- * Returns the {@link ViewNode} containing the root content of the window.
- */
- public ViewNode getRootViewNode() {
- return mRoot;
- }
- }
-
- /**
- * Describes a single view in the assist data.
- */
- static public class ViewNode {
- /**
- * Magic value for text color that has not been defined, which is very unlikely
- * to be confused with a real text color.
- */
- public static final int TEXT_COLOR_UNDEFINED = 1;
-
- public static final int TEXT_STYLE_BOLD = 1<<0;
- public static final int TEXT_STYLE_ITALIC = 1<<1;
- public static final int TEXT_STYLE_UNDERLINE = 1<<2;
- public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
-
- int mId;
- String mIdPackage;
- String mIdType;
- String mIdEntry;
- int mX;
- int mY;
- int mScrollX;
- int mScrollY;
- int mWidth;
- int mHeight;
-
- static final int FLAGS_DISABLED = 0x00000001;
- static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
- static final int FLAGS_FOCUSABLE = 0x00000010;
- static final int FLAGS_FOCUSED = 0x00000020;
- static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
- static final int FLAGS_SELECTED = 0x00000040;
- static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
- static final int FLAGS_ACTIVATED = 0x40000000;
- static final int FLAGS_CHECKABLE = 0x00000100;
- static final int FLAGS_CHECKED = 0x00000200;
- static final int FLAGS_CLICKABLE = 0x00004000;
- static final int FLAGS_LONG_CLICKABLE = 0x00200000;
- static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000;
-
- int mFlags;
-
- String mClassName;
- CharSequence mContentDescription;
-
- ViewNodeText mText;
- Bundle mExtras;
-
- ViewNode[] mChildren;
-
- ViewNode() {
- }
-
- ViewNode(Parcel in, PooledStringReader preader) {
- mId = in.readInt();
- if (mId != 0) {
- mIdEntry = preader.readString();
- if (mIdEntry != null) {
- mIdType = preader.readString();
- mIdPackage = preader.readString();
- } else {
- mIdPackage = mIdType = null;
- }
- } else {
- mIdPackage = mIdType = mIdEntry = null;
- }
- mX = in.readInt();
- mY = in.readInt();
- mScrollX = in.readInt();
- mScrollY = in.readInt();
- mWidth = in.readInt();
- mHeight = in.readInt();
- mFlags = in.readInt();
- mClassName = preader.readString();
- mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- if (in.readInt() != 0) {
- mText = new ViewNodeText(in);
- } else {
- mText = null;
- }
- mExtras = in.readBundle();
- final int NCHILDREN = in.readInt();
- if (NCHILDREN > 0) {
- mChildren = new ViewNode[NCHILDREN];
- for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNode(in, preader);
- }
- } else {
- mChildren = null;
- }
- }
-
- void writeToParcel(Parcel out, PooledStringWriter pwriter) {
- out.writeInt(mId);
- if (mId != 0) {
- pwriter.writeString(mIdEntry);
- if (mIdEntry != null) {
- pwriter.writeString(mIdType);
- pwriter.writeString(mIdPackage);
- }
- }
- out.writeInt(mX);
- out.writeInt(mY);
- out.writeInt(mScrollX);
- out.writeInt(mScrollY);
- out.writeInt(mWidth);
- out.writeInt(mHeight);
- out.writeInt(mFlags);
- pwriter.writeString(mClassName);
- TextUtils.writeToParcel(mContentDescription, out, 0);
- if (mText != null) {
- out.writeInt(1);
- mText.writeToParcel(out);
- } else {
- out.writeInt(0);
- }
- out.writeBundle(mExtras);
- if (mChildren != null) {
- final int NCHILDREN = mChildren.length;
- out.writeInt(NCHILDREN);
- for (int i=0; i<NCHILDREN; i++) {
- mChildren[i].writeToParcel(out, pwriter);
- }
- } else {
- out.writeInt(0);
- }
- }
-
- /**
- * Returns the ID associated with this view, as per {@link View#getId() View.getId()}.
- */
- public int getId() {
- return mId;
- }
-
- /**
- * If {@link #getId()} is a resource identifier, this is the package name of that
- * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
- * for more information.
- */
- public String getIdPackage() {
- return mIdPackage;
- }
-
- /**
- * If {@link #getId()} is a resource identifier, this is the type name of that
- * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
- * for more information.
- */
- public String getIdType() {
- return mIdType;
- }
-
- /**
- * If {@link #getId()} is a resource identifier, this is the entry name of that
- * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
- * for more information.
- */
- public String getIdEntry() {
- return mIdEntry;
- }
-
- /**
- * Returns the left edge of this view, in pixels, relative to the left edge of its parent.
- */
- public int getLeft() {
- return mX;
- }
-
- /**
- * Returns the top edge of this view, in pixels, relative to the top edge of its parent.
- */
- public int getTop() {
- return mY;
- }
-
- /**
- * Returns the current X scroll offset of this view, as per
- * {@link android.view.View#getScrollX() View.getScrollX()}.
- */
- public int getScrollX() {
- return mScrollX;
- }
-
- /**
- * Returns the current Y scroll offset of this view, as per
- * {@link android.view.View#getScrollX() View.getScrollY()}.
- */
- public int getScrollY() {
- return mScrollY;
- }
-
- /**
- * Returns the width of this view, in pixels.
- */
- public int getWidth() {
- return mWidth;
- }
-
- /**
- * Returns the height of this view, in pixels.
- */
- public int getHeight() {
- return mHeight;
- }
-
- /**
- * Returns the visibility mode of this view, as per
- * {@link android.view.View#getVisibility() View.getVisibility()}.
- */
- public int getVisibility() {
- return mFlags&ViewNode.FLAGS_VISIBILITY_MASK;
- }
-
- /**
- * Returns true if assist data has been blocked starting at this node in the hierarchy.
- */
- public boolean isAssistBlocked() {
- return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0;
- }
-
- /**
- * Returns true if this node is in an enabled state.
- */
- public boolean isEnabled() {
- return (mFlags&ViewNode.FLAGS_DISABLED) == 0;
- }
-
- /**
- * Returns true if this node is clickable by the user.
- */
- public boolean isClickable() {
- return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0;
- }
-
- /**
- * Returns true if this node can take input focus.
- */
- public boolean isFocusable() {
- return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0;
- }
-
- /**
- * Returns true if this node currently had input focus at the time that the
- * structure was collected.
- */
- public boolean isFocused() {
- return (mFlags&ViewNode.FLAGS_FOCUSED) != 0;
- }
-
- /**
- * Returns true if this node currently had accessibility focus at the time that the
- * structure was collected.
- */
- public boolean isAccessibilityFocused() {
- return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
- }
-
- /**
- * Returns true if this node represents something that is checkable by the user.
- */
- public boolean isCheckable() {
- return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0;
- }
-
- /**
- * Returns true if this node is currently in a checked state.
- */
- public boolean isChecked() {
- return (mFlags&ViewNode.FLAGS_CHECKED) != 0;
- }
-
- /**
- * Returns true if this node has currently been selected by the user.
- */
- public boolean isSelected() {
- return (mFlags&ViewNode.FLAGS_SELECTED) != 0;
- }
-
- /**
- * Returns true if this node has currently been activated by the user.
- */
- public boolean isActivated() {
- return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0;
- }
-
- /**
- * Returns true if this node is something the user can perform a long click/press on.
- */
- public boolean isLongClickable() {
- return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0;
- }
-
- /**
- * Returns true if this node is something the user can perform a context click on.
- */
- public boolean isContextClickable() {
- return (mFlags&ViewNode.FLAGS_CONTEXT_CLICKABLE) != 0;
- }
-
- /**
- * Returns the class name of the node's implementation, indicating its behavior.
- * For example, a button will report "android.widget.Button" meaning it behaves
- * like a {@link android.widget.Button}.
- */
- public String getClassName() {
- return mClassName;
- }
-
- /**
- * Returns any content description associated with the node, which semantically describes
- * its purpose for accessibility and other uses.
- */
- public CharSequence getContentDescription() {
- return mContentDescription;
- }
-
- /**
- * Returns any text associated with the node that is displayed to the user, or null
- * if there is none.
- */
- public CharSequence getText() {
- return mText != null ? mText.mText : null;
- }
-
- /**
- * If {@link #getText()} is non-null, this is where the current selection starts.
- */
- public int getTextSelectionStart() {
- return mText != null ? mText.mTextSelectionStart : -1;
- }
-
- /**
- * If {@link #getText()} is non-null, this is where the current selection starts.
- * If there is no selection, returns the same value as {@link #getTextSelectionStart()},
- * indicating the cursor position.
- */
- public int getTextSelectionEnd() {
- return mText != null ? mText.mTextSelectionEnd : -1;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text color associated with it.
- * If there is no text color, {@link #TEXT_COLOR_UNDEFINED} is returned.
- * Note that the text may also contain style spans that modify the color of specific
- * parts of the text.
- */
- public int getTextColor() {
- return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text background color associated
- * with it.
- * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned.
- * Note that the text may also contain style spans that modify the color of specific
- * parts of the text.
- */
- public int getTextBackgroundColor() {
- return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text size (in pixels) associated
- * with it.
- * Note that the text may also contain style spans that modify the size of specific
- * parts of the text.
- */
- public float getTextSize() {
- return mText != null ? mText.mTextSize : 0;
- }
-
- /**
- * If {@link #getText()} is non-null, this is the main text style associated
- * with it, containing a bit mask of {@link #TEXT_STYLE_BOLD},
- * {@link #TEXT_STYLE_BOLD}, {@link #TEXT_STYLE_STRIKE_THRU}, and/or
- * {@link #TEXT_STYLE_UNDERLINE}.
- * Note that the text may also contain style spans that modify the style of specific
- * parts of the text.
- */
- public int getTextStyle() {
- return mText != null ? mText.mTextStyle : 0;
- }
-
- /**
- * Return additional hint text associated with the node; this is typically used with
- * a node that takes user input, describing to the user what the input means.
- */
- public String getHint() {
- return mText != null ? mText.mHint : null;
- }
-
- /**
- * Return a Bundle containing optional vendor-specific extension information.
- */
- public Bundle getExtras() {
- return mExtras;
- }
-
- /**
- * Return the number of children this node has.
- */
- public int getChildCount() {
- return mChildren != null ? mChildren.length : 0;
- }
-
- /**
- * Return a child of this node, given an index value from 0 to
- * {@link #getChildCount()}-1.
- */
- public ViewNode getChildAt(int index) {
- return mChildren[index];
- }
- }
-
- static class ViewNodeBuilder extends ViewAssistStructure {
- final AssistStructure mAssist;
- final ViewNode mNode;
- final boolean mAsync;
-
- ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) {
- mAssist = assist;
- mNode = node;
- mAsync = async;
- }
-
- @Override
- public void setId(int id, String packageName, String typeName, String entryName) {
- mNode.mId = id;
- mNode.mIdPackage = packageName;
- mNode.mIdType = typeName;
- mNode.mIdEntry = entryName;
- }
-
- @Override
- public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
- mNode.mX = left;
- mNode.mY = top;
- mNode.mScrollX = scrollX;
- mNode.mScrollY = scrollY;
- mNode.mWidth = width;
- mNode.mHeight = height;
- }
-
- @Override
- public void setVisibility(int visibility) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
- }
-
- @Override
- public void setAssistBlocked(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED)
- | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED);
- }
-
- @Override
- public void setEnabled(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_DISABLED)
- | (state ? 0 : ViewNode.FLAGS_DISABLED);
- }
-
- @Override
- public void setClickable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CLICKABLE)
- | (state ? ViewNode.FLAGS_CLICKABLE : 0);
- }
-
- @Override
- public void setLongClickable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_LONG_CLICKABLE)
- | (state ? ViewNode.FLAGS_LONG_CLICKABLE : 0);
- }
-
- @Override
- public void setContextClickable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CONTEXT_CLICKABLE)
- | (state ? ViewNode.FLAGS_CONTEXT_CLICKABLE : 0);
- }
-
- @Override
- public void setFocusable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE)
- | (state ? ViewNode.FLAGS_FOCUSABLE : 0);
- }
-
- @Override
- public void setFocused(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSED)
- | (state ? ViewNode.FLAGS_FOCUSED : 0);
- }
-
- @Override
- public void setAccessibilityFocused(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACCESSIBILITY_FOCUSED)
- | (state ? ViewNode.FLAGS_ACCESSIBILITY_FOCUSED : 0);
- }
-
- @Override
- public void setCheckable(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKABLE)
- | (state ? ViewNode.FLAGS_CHECKABLE : 0);
- }
-
- @Override
- public void setChecked(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKED)
- | (state ? ViewNode.FLAGS_CHECKED : 0);
- }
-
- @Override
- public void setSelected(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_SELECTED)
- | (state ? ViewNode.FLAGS_SELECTED : 0);
- }
-
- @Override
- public void setActivated(boolean state) {
- mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACTIVATED)
- | (state ? ViewNode.FLAGS_ACTIVATED : 0);
- }
-
- @Override
- public void setClassName(String className) {
- mNode.mClassName = className;
- }
-
- @Override
- public void setContentDescription(CharSequence contentDescription) {
- mNode.mContentDescription = contentDescription;
- }
-
- private final ViewNodeText getNodeText() {
- if (mNode.mText != null) {
- return mNode.mText;
- }
- mNode.mText = new ViewNodeText();
- return mNode.mText;
- }
-
- @Override
- public void setText(CharSequence text) {
- ViewNodeText t = getNodeText();
- t.mText = text;
- t.mTextSelectionStart = t.mTextSelectionEnd = -1;
- }
-
- @Override
- public void setText(CharSequence text, int selectionStart, int selectionEnd) {
- ViewNodeText t = getNodeText();
- t.mText = text;
- t.mTextSelectionStart = selectionStart;
- t.mTextSelectionEnd = selectionEnd;
- }
-
- @Override
- public void setTextStyle(float size, int fgColor, int bgColor, int style) {
- ViewNodeText t = getNodeText();
- t.mTextColor = fgColor;
- t.mTextBackgroundColor = bgColor;
- t.mTextSize = size;
- t.mTextStyle = style;
- }
-
- @Override
- public void setHint(CharSequence hint) {
- getNodeText().mHint = hint != null ? hint.toString() : null;
- }
-
- @Override
- public CharSequence getText() {
- return mNode.mText != null ? mNode.mText.mText : null;
- }
-
- @Override
- public int getTextSelectionStart() {
- return mNode.mText != null ? mNode.mText.mTextSelectionStart : -1;
- }
-
- @Override
- public int getTextSelectionEnd() {
- return mNode.mText != null ? mNode.mText.mTextSelectionEnd : -1;
- }
-
- @Override
- public CharSequence getHint() {
- return mNode.mText != null ? mNode.mText.mHint : null;
- }
-
- @Override
- public Bundle getExtras() {
- if (mNode.mExtras != null) {
- return mNode.mExtras;
- }
- mNode.mExtras = new Bundle();
- return mNode.mExtras;
- }
-
- @Override
- public boolean hasExtras() {
- return mNode.mExtras != null;
- }
-
- @Override
- public void setChildCount(int num) {
- mNode.mChildren = new ViewNode[num];
- }
-
- @Override
- public int addChildCount(int num) {
- if (mNode.mChildren == null) {
- setChildCount(num);
- return 0;
- }
- final int start = mNode.mChildren.length;
- ViewNode[] newArray = new ViewNode[start + num];
- System.arraycopy(mNode.mChildren, 0, newArray, 0, start);
- mNode.mChildren = newArray;
- return start;
- }
-
- @Override
- public int getChildCount() {
- return mNode.mChildren != null ? mNode.mChildren.length : 0;
- }
-
- @Override
- public ViewAssistStructure newChild(int index) {
- ViewNode node = new ViewNode();
- mNode.mChildren[index] = node;
- return new ViewNodeBuilder(mAssist, node, false);
- }
-
- @Override
- public ViewAssistStructure asyncNewChild(int index) {
- synchronized (mAssist) {
- ViewNode node = new ViewNode();
- mNode.mChildren[index] = node;
- ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true);
- mAssist.mPendingAsyncChildren.add(builder);
- return builder;
- }
- }
-
- @Override
- public void asyncCommit() {
- synchronized (mAssist) {
- if (!mAsync) {
- throw new IllegalStateException("Child " + this
- + " was not created with ViewAssistStructure.asyncNewChild");
- }
- if (!mAssist.mPendingAsyncChildren.remove(this)) {
- throw new IllegalStateException("Child " + this + " already committed");
- }
- mAssist.notifyAll();
- }
- }
-
- @Override
- public Rect getTempRect() {
- return mAssist.mTmpRect;
- }
- }
-
- /** @hide */
- public AssistStructure(Activity activity) {
- mHaveData = true;
- mActivityComponent = activity.getComponentName();
- ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
- activity.getActivityToken());
- for (int i=0; i<views.size(); i++) {
- ViewRootImpl root = views.get(i);
- mWindowNodes.add(new WindowNode(this, root));
- }
- }
-
- public AssistStructure() {
- mHaveData = true;
- mActivityComponent = null;
- }
-
- /** @hide */
- public AssistStructure(Parcel in) {
- mReceiveChannel = in.readStrongBinder();
- }
-
- /** @hide */
- public void dump() {
- Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
- final int N = getWindowNodeCount();
- for (int i=0; i<N; i++) {
- WindowNode node = getWindowNodeAt(i);
- Log.i(TAG, "Window #" + i + " [" + node.getLeft() + "," + node.getTop()
- + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getTitle());
- dump(" ", node.getRootViewNode());
- }
- }
-
- void dump(String prefix, ViewNode node) {
- Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop()
- + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName());
- int id = node.getId();
- if (id != 0) {
- StringBuilder sb = new StringBuilder();
- sb.append(prefix); sb.append(" ID: #"); sb.append(Integer.toHexString(id));
- String entry = node.getIdEntry();
- if (entry != null) {
- String type = node.getIdType();
- String pkg = node.getIdPackage();
- sb.append(" "); sb.append(pkg); sb.append(":"); sb.append(type);
- sb.append("/"); sb.append(entry);
- }
- Log.i(TAG, sb.toString());
- }
- int scrollX = node.getScrollX();
- int scrollY = node.getScrollY();
- if (scrollX != 0 || scrollY != 0) {
- Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY);
- }
- CharSequence contentDescription = node.getContentDescription();
- if (contentDescription != null) {
- Log.i(TAG, prefix + " Content description: " + contentDescription);
- }
- CharSequence text = node.getText();
- if (text != null) {
- Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
- + node.getTextSelectionEnd() + "): " + text);
- Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #"
- + node.getTextStyle());
- Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor())
- + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
- }
- String hint = node.getHint();
- if (hint != null) {
- Log.i(TAG, prefix + " Hint: " + hint);
- }
- Bundle extras = node.getExtras();
- if (extras != null) {
- Log.i(TAG, prefix + " Extras: " + extras);
- }
- final int NCHILDREN = node.getChildCount();
- if (NCHILDREN > 0) {
- Log.i(TAG, prefix + " Children:");
- String cprefix = prefix + " ";
- for (int i=0; i<NCHILDREN; i++) {
- ViewNode cnode = node.getChildAt(i);
- dump(cprefix, cnode);
- }
- }
- }
-
- /**
- * @hide
- * Retrieve the framework-generated AssistStructure that is stored within
- * the Bundle filled in by {@link Activity#onProvideAssistData}.
- */
- public static android.app.assist.AssistStructure getAssistStructure(Bundle assistBundle) {
- return assistBundle.getParcelable(ASSIST_KEY);
- }
-
- /**
- * Return the activity this AssistStructure came from.
- */
- public ComponentName getActivityComponent() {
- ensureData();
- return mActivityComponent;
- }
-
- /**
- * Return the number of window contents that have been collected in this assist data.
- */
- public int getWindowNodeCount() {
- ensureData();
- return mWindowNodes.size();
- }
-
- /**
- * Return one of the windows in the assist data.
- * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1.
- * @hide
- */
- public WindowNode getWindowNodeAt(int index) {
- ensureData();
- return mWindowNodes.get(index);
- }
-
- /** @hide */
- public void ensureData() {
- if (mHaveData) {
- return;
- }
- mHaveData = true;
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(DESCRIPTOR);
- try {
- mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0);
- } catch (RemoteException e) {
- Log.w(TAG, "Failure reading AssistStructure data", e);
- return;
- }
- readContentFromParcel(reply);
- data.recycle();
- reply.recycle();
- }
-
- void writeContentToParcel(Parcel out, int flags) {
- // First make sure all content has been created.
- boolean skipStructure = false;
- synchronized (this) {
- long endTime = SystemClock.uptimeMillis() + 5000;
- long now;
- while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) {
- try {
- wait(endTime-now);
- } catch (InterruptedException e) {
- }
- }
- if (mPendingAsyncChildren.size() > 0) {
- // We waited too long, assume none of the assist structure is valid.
- skipStructure = true;
- }
- }
- int start = out.dataPosition();
- PooledStringWriter pwriter = new PooledStringWriter(out);
- ComponentName.writeToParcel(mActivityComponent, out);
- final int N = skipStructure ? 0 : mWindowNodes.size();
- out.writeInt(N);
- for (int i=0; i<N; i++) {
- mWindowNodes.get(i).writeToParcel(out, pwriter);
- }
- pwriter.finish();
- Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
- }
-
- void readContentFromParcel(Parcel in) {
- PooledStringReader preader = new PooledStringReader(in);
- mActivityComponent = ComponentName.readFromParcel(in);
- final int N = in.readInt();
- for (int i=0; i<N; i++) {
- mWindowNodes.add(new WindowNode(in, preader));
- }
- //dump();
- }
-}
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 9cc399d..abb8244 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -225,6 +225,9 @@ public final class VoiceInteractor {
* Cancel this active request.
*/
public void cancel() {
+ if (mRequestInterface == null) {
+ throw new IllegalStateException("Request " + this + " is no longer active");
+ }
try {
mRequestInterface.cancel();
} catch (RemoteException e) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 125708a..4d1cff5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3972,6 +3972,7 @@ public class DevicePolicyManager {
* <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN}
* 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>
* </ul>
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -4349,6 +4350,12 @@ public class DevicePolicyManager {
* group that the runtime permission belongs to. This method can only be called
* by a profile or device owner.
*
+ * <p/>Setting the grant state to {@link #PERMISSION_GRANT_STATE_DEFAULT default} does not
+ * revoke the permission. It retains the previous grant, if any.
+ *
+ * <p/>Permissions can be granted or revoked only for applications built with a
+ * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later.
+ *
* @param admin Which profile or device owner this request is associated with.
* @param packageName The application to grant or revoke a permission to.
* @param permission The permission to grant or revoke.
diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java
index c7e7330..07b2d57 100644
--- a/core/java/android/app/assist/AssistContent.java
+++ b/core/java/android/app/assist/AssistContent.java
@@ -1,24 +1,184 @@
package android.app.assist;
+import android.content.ClipData;
import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * New home for AssistContent.
+ * Holds information about the content an application is viewing, to hand to an
+ * assistant at the user's request. This is filled in by
+ * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
*/
-public final class AssistContent extends android.app.AssistContent implements Parcelable {
+@Deprecated
+public class AssistContent implements Parcelable {
+ private boolean mIsAppProvidedIntent = false;
+ private Intent mIntent;
+ private String mStructuredData;
+ private ClipData mClipData;
+ private Uri mUri;
+ private final Bundle mExtras;
- /** @hide */
public AssistContent() {
+ mExtras = new Bundle();
}
- public AssistContent(Parcel in) {
- super(in);
+ /**
+ * @hide
+ * Called by {@link android.app.ActivityThread} to set the default Intent based on
+ * {@link android.app.Activity#getIntent Activity.getIntent}.
+ *
+ * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
+ * of a web (http or https scheme) URI.</p>
+ */
+ public void setDefaultIntent(Intent intent) {
+ mIntent = intent;
+ setWebUri(null);
+ if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ if (uri != null) {
+ if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
+ setWebUri(uri);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the Intent associated with the content, describing the current top-level context of
+ * the activity. If this contains a reference to a piece of data related to the activity,
+ * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
+ * service can access it.
+ */
+ public void setIntent(Intent intent) {
+ mIsAppProvidedIntent = true;
+ mIntent = intent;
}
+ /**
+ * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from
+ * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place.
+ */
public Intent getIntent() {
- return super.getIntent();
+ return mIntent;
+ }
+
+ /**
+ * Returns whether or not the current Intent was explicitly provided in
+ * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
+ * the Intent was automatically set based on
+ * {@link android.app.Activity#getIntent Activity.getIntent}.
+ */
+ public boolean isAppProvidedIntent() {
+ return mIsAppProvidedIntent;
+ }
+
+ /**
+ * Optional additional content items that are involved with
+ * the current UI. Access to this content will be granted to the assistant as if you
+ * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
+ */
+ public void setClipData(ClipData clip) {
+ mClipData = clip;
+ }
+
+ /**
+ * Return the current {@link #setClipData}, which you can modify in-place.
+ */
+ public ClipData getClipData() {
+ return mClipData;
+ }
+
+ /**
+ * Sets optional structured data regarding the content being viewed. The provided data
+ * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
+ * <a href="http://schema.org/">schema.org</a> vocabulary.
+ */
+ public void setStructuredData(String structuredData) {
+ mStructuredData = structuredData;
+ }
+
+ /**
+ * Returns the current {@link #setStructuredData}.
+ */
+ public String getStructuredData() {
+ return mStructuredData;
+ }
+
+ /**
+ * Set a web URI associated with the current data being shown to the user.
+ * This URI could be opened in a web browser, or in the app as an
+ * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
+ * being displayed by it. The URI here should be something that is transportable
+ * off the device into other environments to acesss the same data as is currently
+ * being shown in the app; if the app does not have such a representation, it should
+ * leave the null and only report the local intent and clip data.
+ */
+ public void setWebUri(Uri uri) {
+ mUri = uri;
+ }
+
+ /**
+ * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
+ * there is none.
+ */
+ public Uri getWebUri() {
+ return mUri;
+ }
+
+ /**
+ * Return Bundle for extra vendor-specific data that can be modified and examined.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ AssistContent(Parcel in) {
+ if (in.readInt() != 0) {
+ mIntent = Intent.CREATOR.createFromParcel(in);
+ }
+ if (in.readInt() != 0) {
+ mClipData = ClipData.CREATOR.createFromParcel(in);
+ }
+ if (in.readInt() != 0) {
+ mUri = Uri.CREATOR.createFromParcel(in);
+ }
+ if (in.readInt() != 0) {
+ mStructuredData = in.readString();
+ }
+ mIsAppProvidedIntent = in.readInt() == 1;
+ mExtras = in.readBundle();
+ }
+
+ void writeToParcelInternal(Parcel dest, int flags) {
+ if (mIntent != null) {
+ dest.writeInt(1);
+ mIntent.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mClipData != null) {
+ dest.writeInt(1);
+ mClipData.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mUri != null) {
+ dest.writeInt(1);
+ mUri.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
+ if (mStructuredData != null) {
+ dest.writeInt(1);
+ dest.writeString(mStructuredData);
+ } else {
+ dest.writeInt(0);
+ }
+ dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
+ dest.writeBundle(mExtras);
}
@Override
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 1677e95..1a04895 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1,28 +1,1038 @@
package android.app.assist;
import android.app.Activity;
+import android.content.ComponentName;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PooledStringReader;
+import android.os.PooledStringWriter;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewAssistStructure;
+import android.view.ViewRootImpl;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import java.util.ArrayList;
/**
- * New home for AssistStructure.
+ * Assist data automatically created by the platform's implementation
+ * of {@link android.app.Activity#onProvideAssistData}.
*/
-public final class AssistStructure extends android.app.AssistStructure implements Parcelable {
+public class AssistStructure implements Parcelable {
+ static final String TAG = "AssistStructure";
- public AssistStructure() {
+ boolean mHaveData;
+
+ ComponentName mActivityComponent;
+
+ final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
+
+ final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>();
+
+ SendChannel mSendChannel;
+ IBinder mReceiveChannel;
+
+ Rect mTmpRect = new Rect();
+
+ static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
+ static final String DESCRIPTOR = "android.app.AssistStructure";
+
+ final class SendChannel extends Binder {
+ @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ if (code == TRANSACTION_XFER) {
+ data.enforceInterface(DESCRIPTOR);
+ writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+ return true;
+ } else {
+ return super.onTransact(code, data, reply, flags);
+ }
+ }
+ }
+
+ final static class ViewNodeText {
+ CharSequence mText;
+ int mTextSelectionStart;
+ int mTextSelectionEnd;
+ int mTextColor;
+ int mTextBackgroundColor;
+ float mTextSize;
+ int mTextStyle;
+ String mHint;
+
+ ViewNodeText() {
+ }
+
+ ViewNodeText(Parcel in) {
+ mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mTextSelectionStart = in.readInt();
+ mTextSelectionEnd = in.readInt();
+ mTextColor = in.readInt();
+ mTextBackgroundColor = in.readInt();
+ mTextSize = in.readFloat();
+ mTextStyle = in.readInt();
+ mHint = in.readString();
+ }
+
+ void writeToParcel(Parcel out) {
+ TextUtils.writeToParcel(mText, out, 0);
+ out.writeInt(mTextSelectionStart);
+ out.writeInt(mTextSelectionEnd);
+ out.writeInt(mTextColor);
+ out.writeInt(mTextBackgroundColor);
+ out.writeFloat(mTextSize);
+ out.writeInt(mTextStyle);
+ out.writeString(mHint);
+ }
+ }
+
+ /**
+ * Describes a window in the assist data.
+ */
+ static public class WindowNode {
+ final int mX;
+ final int mY;
+ final int mWidth;
+ final int mHeight;
+ final CharSequence mTitle;
+ final int mDisplayId;
+ final ViewNode mRoot;
+
+ WindowNode(AssistStructure assist, ViewRootImpl root) {
+ View view = root.getView();
+ Rect rect = new Rect();
+ view.getBoundsOnScreen(rect);
+ mX = rect.left - view.getLeft();
+ mY = rect.top - view.getTop();
+ mWidth = rect.width();
+ mHeight = rect.height();
+ mTitle = root.getTitle();
+ mDisplayId = root.getDisplayId();
+ mRoot = new ViewNode();
+ ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false);
+ if ((root.getWindowFlags()& WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ // This is a secure window, so it doesn't want a screenshot, and that
+ // means we should also not copy out its view hierarchy.
+ view.onProvideStructure(builder);
+ builder.setAssistBlocked(true);
+ return;
+ }
+ view.dispatchProvideStructure(builder);
+ }
+
+ WindowNode(Parcel in, PooledStringReader preader) {
+ mX = in.readInt();
+ mY = in.readInt();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
+ mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mDisplayId = in.readInt();
+ mRoot = new ViewNode(in, preader);
+ }
+
+ void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ TextUtils.writeToParcel(mTitle, out, 0);
+ out.writeInt(mDisplayId);
+ mRoot.writeToParcel(out, pwriter);
+ }
+
+ /**
+ * Returns the left edge of the window, in pixels, relative to the left
+ * edge of the screen.
+ */
+ public int getLeft() {
+ return mX;
+ }
+
+ /**
+ * Returns the top edge of the window, in pixels, relative to the top
+ * edge of the screen.
+ */
+ public int getTop() {
+ return mY;
+ }
+
+ /**
+ * Returns the total width of the window in pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * Returns the total height of the window in pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Returns the title associated with the window, if it has one.
+ */
+ public CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Returns the ID of the display this window is on, for use with
+ * {@link android.hardware.display.DisplayManager#getDisplay DisplayManager.getDisplay()}.
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ /**
+ * Returns the {@link ViewNode} containing the root content of the window.
+ */
+ public ViewNode getRootViewNode() {
+ return mRoot;
+ }
+ }
+
+ /**
+ * Describes a single view in the assist data.
+ */
+ static public class ViewNode {
+ /**
+ * Magic value for text color that has not been defined, which is very unlikely
+ * to be confused with a real text color.
+ */
+ public static final int TEXT_COLOR_UNDEFINED = 1;
+
+ public static final int TEXT_STYLE_BOLD = 1<<0;
+ public static final int TEXT_STYLE_ITALIC = 1<<1;
+ public static final int TEXT_STYLE_UNDERLINE = 1<<2;
+ public static final int TEXT_STYLE_STRIKE_THRU = 1<<3;
+
+ int mId;
+ String mIdPackage;
+ String mIdType;
+ String mIdEntry;
+ int mX;
+ int mY;
+ int mScrollX;
+ int mScrollY;
+ int mWidth;
+ int mHeight;
+
+ static final int FLAGS_DISABLED = 0x00000001;
+ static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE;
+ static final int FLAGS_FOCUSABLE = 0x00000010;
+ static final int FLAGS_FOCUSED = 0x00000020;
+ static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000;
+ static final int FLAGS_SELECTED = 0x00000040;
+ static final int FLAGS_ASSIST_BLOCKED = 0x00000080;
+ static final int FLAGS_ACTIVATED = 0x40000000;
+ static final int FLAGS_CHECKABLE = 0x00000100;
+ static final int FLAGS_CHECKED = 0x00000200;
+ static final int FLAGS_CLICKABLE = 0x00004000;
+ static final int FLAGS_LONG_CLICKABLE = 0x00200000;
+ static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000;
+
+ int mFlags;
+
+ String mClassName;
+ CharSequence mContentDescription;
+
+ ViewNodeText mText;
+ Bundle mExtras;
+
+ ViewNode[] mChildren;
+
+ ViewNode() {
+ }
+
+ ViewNode(Parcel in, PooledStringReader preader) {
+ mId = in.readInt();
+ if (mId != 0) {
+ mIdEntry = preader.readString();
+ if (mIdEntry != null) {
+ mIdType = preader.readString();
+ mIdPackage = preader.readString();
+ } else {
+ mIdPackage = mIdType = null;
+ }
+ } else {
+ mIdPackage = mIdType = mIdEntry = null;
+ }
+ mX = in.readInt();
+ mY = in.readInt();
+ mScrollX = in.readInt();
+ mScrollY = in.readInt();
+ mWidth = in.readInt();
+ mHeight = in.readInt();
+ mFlags = in.readInt();
+ mClassName = preader.readString();
+ mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ if (in.readInt() != 0) {
+ mText = new ViewNodeText(in);
+ } else {
+ mText = null;
+ }
+ mExtras = in.readBundle();
+ final int NCHILDREN = in.readInt();
+ if (NCHILDREN > 0) {
+ mChildren = new ViewNode[NCHILDREN];
+ for (int i=0; i<NCHILDREN; i++) {
+ mChildren[i] = new ViewNode(in, preader);
+ }
+ } else {
+ mChildren = null;
+ }
+ }
+
+ void writeToParcel(Parcel out, PooledStringWriter pwriter) {
+ out.writeInt(mId);
+ if (mId != 0) {
+ pwriter.writeString(mIdEntry);
+ if (mIdEntry != null) {
+ pwriter.writeString(mIdType);
+ pwriter.writeString(mIdPackage);
+ }
+ }
+ out.writeInt(mX);
+ out.writeInt(mY);
+ out.writeInt(mScrollX);
+ out.writeInt(mScrollY);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ out.writeInt(mFlags);
+ pwriter.writeString(mClassName);
+ TextUtils.writeToParcel(mContentDescription, out, 0);
+ if (mText != null) {
+ out.writeInt(1);
+ mText.writeToParcel(out);
+ } else {
+ out.writeInt(0);
+ }
+ out.writeBundle(mExtras);
+ if (mChildren != null) {
+ final int NCHILDREN = mChildren.length;
+ out.writeInt(NCHILDREN);
+ for (int i=0; i<NCHILDREN; i++) {
+ mChildren[i].writeToParcel(out, pwriter);
+ }
+ } else {
+ out.writeInt(0);
+ }
+ }
+
+ /**
+ * Returns the ID associated with this view, as per {@link View#getId() View.getId()}.
+ */
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * If {@link #getId()} is a resource identifier, this is the package name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
+ public String getIdPackage() {
+ return mIdPackage;
+ }
+
+ /**
+ * If {@link #getId()} is a resource identifier, this is the type name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
+ public String getIdType() {
+ return mIdType;
+ }
+
+ /**
+ * If {@link #getId()} is a resource identifier, this is the entry name of that
+ * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
+ * for more information.
+ */
+ public String getIdEntry() {
+ return mIdEntry;
+ }
+
+ /**
+ * Returns the left edge of this view, in pixels, relative to the left edge of its parent.
+ */
+ public int getLeft() {
+ return mX;
+ }
+
+ /**
+ * Returns the top edge of this view, in pixels, relative to the top edge of its parent.
+ */
+ public int getTop() {
+ return mY;
+ }
+
+ /**
+ * Returns the current X scroll offset of this view, as per
+ * {@link android.view.View#getScrollX() View.getScrollX()}.
+ */
+ public int getScrollX() {
+ return mScrollX;
+ }
+
+ /**
+ * Returns the current Y scroll offset of this view, as per
+ * {@link android.view.View#getScrollX() View.getScrollY()}.
+ */
+ public int getScrollY() {
+ return mScrollY;
+ }
+
+ /**
+ * Returns the width of this view, in pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * Returns the height of this view, in pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Returns the visibility mode of this view, as per
+ * {@link android.view.View#getVisibility() View.getVisibility()}.
+ */
+ public int getVisibility() {
+ return mFlags&ViewNode.FLAGS_VISIBILITY_MASK;
+ }
+
+ /**
+ * Returns true if assist data has been blocked starting at this node in the hierarchy.
+ */
+ public boolean isAssistBlocked() {
+ return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0;
+ }
+
+ /**
+ * Returns true if this node is in an enabled state.
+ */
+ public boolean isEnabled() {
+ return (mFlags&ViewNode.FLAGS_DISABLED) == 0;
+ }
+
+ /**
+ * Returns true if this node is clickable by the user.
+ */
+ public boolean isClickable() {
+ return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node can take input focus.
+ */
+ public boolean isFocusable() {
+ return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node currently had input focus at the time that the
+ * structure was collected.
+ */
+ public boolean isFocused() {
+ return (mFlags&ViewNode.FLAGS_FOCUSED) != 0;
+ }
+
+ /**
+ * Returns true if this node currently had accessibility focus at the time that the
+ * structure was collected.
+ */
+ public boolean isAccessibilityFocused() {
+ return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0;
+ }
+
+ /**
+ * Returns true if this node represents something that is checkable by the user.
+ */
+ public boolean isCheckable() {
+ return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node is currently in a checked state.
+ */
+ public boolean isChecked() {
+ return (mFlags&ViewNode.FLAGS_CHECKED) != 0;
+ }
+
+ /**
+ * Returns true if this node has currently been selected by the user.
+ */
+ public boolean isSelected() {
+ return (mFlags&ViewNode.FLAGS_SELECTED) != 0;
+ }
+
+ /**
+ * Returns true if this node has currently been activated by the user.
+ */
+ public boolean isActivated() {
+ return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0;
+ }
+
+ /**
+ * Returns true if this node is something the user can perform a long click/press on.
+ */
+ public boolean isLongClickable() {
+ return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0;
+ }
+
+ /**
+ * Returns true if this node is something the user can perform a context click on.
+ */
+ public boolean isContextClickable() {
+ return (mFlags&ViewNode.FLAGS_CONTEXT_CLICKABLE) != 0;
+ }
+
+ /**
+ * Returns the class name of the node's implementation, indicating its behavior.
+ * For example, a button will report "android.widget.Button" meaning it behaves
+ * like a {@link android.widget.Button}.
+ */
+ public String getClassName() {
+ return mClassName;
+ }
+
+ /**
+ * Returns any content description associated with the node, which semantically describes
+ * its purpose for accessibility and other uses.
+ */
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * Returns any text associated with the node that is displayed to the user, or null
+ * if there is none.
+ */
+ public CharSequence getText() {
+ return mText != null ? mText.mText : null;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is where the current selection starts.
+ */
+ public int getTextSelectionStart() {
+ return mText != null ? mText.mTextSelectionStart : -1;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is where the current selection starts.
+ * If there is no selection, returns the same value as {@link #getTextSelectionStart()},
+ * indicating the cursor position.
+ */
+ public int getTextSelectionEnd() {
+ return mText != null ? mText.mTextSelectionEnd : -1;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text color associated with it.
+ * If there is no text color, {@link #TEXT_COLOR_UNDEFINED} is returned.
+ * Note that the text may also contain style spans that modify the color of specific
+ * parts of the text.
+ */
+ public int getTextColor() {
+ return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text background color associated
+ * with it.
+ * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned.
+ * Note that the text may also contain style spans that modify the color of specific
+ * parts of the text.
+ */
+ public int getTextBackgroundColor() {
+ return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text size (in pixels) associated
+ * with it.
+ * Note that the text may also contain style spans that modify the size of specific
+ * parts of the text.
+ */
+ public float getTextSize() {
+ return mText != null ? mText.mTextSize : 0;
+ }
+
+ /**
+ * If {@link #getText()} is non-null, this is the main text style associated
+ * with it, containing a bit mask of {@link #TEXT_STYLE_BOLD},
+ * {@link #TEXT_STYLE_BOLD}, {@link #TEXT_STYLE_STRIKE_THRU}, and/or
+ * {@link #TEXT_STYLE_UNDERLINE}.
+ * Note that the text may also contain style spans that modify the style of specific
+ * parts of the text.
+ */
+ public int getTextStyle() {
+ return mText != null ? mText.mTextStyle : 0;
+ }
+
+ /**
+ * Return additional hint text associated with the node; this is typically used with
+ * a node that takes user input, describing to the user what the input means.
+ */
+ public String getHint() {
+ return mText != null ? mText.mHint : null;
+ }
+
+ /**
+ * Return a Bundle containing optional vendor-specific extension information.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Return the number of children this node has.
+ */
+ public int getChildCount() {
+ return mChildren != null ? mChildren.length : 0;
+ }
+
+ /**
+ * Return a child of this node, given an index value from 0 to
+ * {@link #getChildCount()}-1.
+ */
+ public ViewNode getChildAt(int index) {
+ return mChildren[index];
+ }
+ }
+
+ static class ViewNodeBuilder extends ViewAssistStructure {
+ final AssistStructure mAssist;
+ final ViewNode mNode;
+ final boolean mAsync;
+
+ ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) {
+ mAssist = assist;
+ mNode = node;
+ mAsync = async;
+ }
+
+ @Override
+ public void setId(int id, String packageName, String typeName, String entryName) {
+ mNode.mId = id;
+ mNode.mIdPackage = packageName;
+ mNode.mIdType = typeName;
+ mNode.mIdEntry = entryName;
+ }
+
+ @Override
+ public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
+ mNode.mX = left;
+ mNode.mY = top;
+ mNode.mScrollX = scrollX;
+ mNode.mScrollY = scrollY;
+ mNode.mWidth = width;
+ mNode.mHeight = height;
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility;
+ }
+
+ @Override
+ public void setAssistBlocked(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED)
+ | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED);
+ }
+
+ @Override
+ public void setEnabled(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_DISABLED)
+ | (state ? 0 : ViewNode.FLAGS_DISABLED);
+ }
+
+ @Override
+ public void setClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CLICKABLE)
+ | (state ? ViewNode.FLAGS_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setLongClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_LONG_CLICKABLE)
+ | (state ? ViewNode.FLAGS_LONG_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setContextClickable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CONTEXT_CLICKABLE)
+ | (state ? ViewNode.FLAGS_CONTEXT_CLICKABLE : 0);
+ }
+
+ @Override
+ public void setFocusable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE)
+ | (state ? ViewNode.FLAGS_FOCUSABLE : 0);
+ }
+
+ @Override
+ public void setFocused(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSED)
+ | (state ? ViewNode.FLAGS_FOCUSED : 0);
+ }
+
+ @Override
+ public void setAccessibilityFocused(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACCESSIBILITY_FOCUSED)
+ | (state ? ViewNode.FLAGS_ACCESSIBILITY_FOCUSED : 0);
+ }
+
+ @Override
+ public void setCheckable(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKABLE)
+ | (state ? ViewNode.FLAGS_CHECKABLE : 0);
+ }
+
+ @Override
+ public void setChecked(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKED)
+ | (state ? ViewNode.FLAGS_CHECKED : 0);
+ }
+
+ @Override
+ public void setSelected(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_SELECTED)
+ | (state ? ViewNode.FLAGS_SELECTED : 0);
+ }
+
+ @Override
+ public void setActivated(boolean state) {
+ mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACTIVATED)
+ | (state ? ViewNode.FLAGS_ACTIVATED : 0);
+ }
+
+ @Override
+ public void setClassName(String className) {
+ mNode.mClassName = className;
+ }
+
+ @Override
+ public void setContentDescription(CharSequence contentDescription) {
+ mNode.mContentDescription = contentDescription;
+ }
+
+ private final ViewNodeText getNodeText() {
+ if (mNode.mText != null) {
+ return mNode.mText;
+ }
+ mNode.mText = new ViewNodeText();
+ return mNode.mText;
+ }
+
+ @Override
+ public void setText(CharSequence text) {
+ ViewNodeText t = getNodeText();
+ t.mText = text;
+ t.mTextSelectionStart = t.mTextSelectionEnd = -1;
+ }
+
+ @Override
+ public void setText(CharSequence text, int selectionStart, int selectionEnd) {
+ ViewNodeText t = getNodeText();
+ t.mText = text;
+ t.mTextSelectionStart = selectionStart;
+ t.mTextSelectionEnd = selectionEnd;
+ }
+
+ @Override
+ public void setTextStyle(float size, int fgColor, int bgColor, int style) {
+ ViewNodeText t = getNodeText();
+ t.mTextColor = fgColor;
+ t.mTextBackgroundColor = bgColor;
+ t.mTextSize = size;
+ t.mTextStyle = style;
+ }
+
+ @Override
+ public void setHint(CharSequence hint) {
+ getNodeText().mHint = hint != null ? hint.toString() : null;
+ }
+
+ @Override
+ public CharSequence getText() {
+ return mNode.mText != null ? mNode.mText.mText : null;
+ }
+
+ @Override
+ public int getTextSelectionStart() {
+ return mNode.mText != null ? mNode.mText.mTextSelectionStart : -1;
+ }
+
+ @Override
+ public int getTextSelectionEnd() {
+ return mNode.mText != null ? mNode.mText.mTextSelectionEnd : -1;
+ }
+
+ @Override
+ public CharSequence getHint() {
+ return mNode.mText != null ? mNode.mText.mHint : null;
+ }
+
+ @Override
+ public Bundle getExtras() {
+ if (mNode.mExtras != null) {
+ return mNode.mExtras;
+ }
+ mNode.mExtras = new Bundle();
+ return mNode.mExtras;
+ }
+
+ @Override
+ public boolean hasExtras() {
+ return mNode.mExtras != null;
+ }
+
+ @Override
+ public void setChildCount(int num) {
+ mNode.mChildren = new ViewNode[num];
+ }
+
+ @Override
+ public int addChildCount(int num) {
+ if (mNode.mChildren == null) {
+ setChildCount(num);
+ return 0;
+ }
+ final int start = mNode.mChildren.length;
+ ViewNode[] newArray = new ViewNode[start + num];
+ System.arraycopy(mNode.mChildren, 0, newArray, 0, start);
+ mNode.mChildren = newArray;
+ return start;
+ }
+
+ @Override
+ public int getChildCount() {
+ return mNode.mChildren != null ? mNode.mChildren.length : 0;
+ }
+
+ @Override
+ public ViewAssistStructure newChild(int index) {
+ ViewNode node = new ViewNode();
+ mNode.mChildren[index] = node;
+ return new ViewNodeBuilder(mAssist, node, false);
+ }
+
+ @Override
+ public ViewAssistStructure asyncNewChild(int index) {
+ synchronized (mAssist) {
+ ViewNode node = new ViewNode();
+ mNode.mChildren[index] = node;
+ ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true);
+ mAssist.mPendingAsyncChildren.add(builder);
+ return builder;
+ }
+ }
+
+ @Override
+ public void asyncCommit() {
+ synchronized (mAssist) {
+ if (!mAsync) {
+ throw new IllegalStateException("Child " + this
+ + " was not created with ViewAssistStructure.asyncNewChild");
+ }
+ if (!mAssist.mPendingAsyncChildren.remove(this)) {
+ throw new IllegalStateException("Child " + this + " already committed");
+ }
+ mAssist.notifyAll();
+ }
+ }
+
+ @Override
+ public Rect getTempRect() {
+ return mAssist.mTmpRect;
+ }
}
/** @hide */
public AssistStructure(Activity activity) {
- super(activity);
+ mHaveData = true;
+ mActivityComponent = activity.getComponentName();
+ ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
+ activity.getActivityToken());
+ for (int i=0; i<views.size(); i++) {
+ ViewRootImpl root = views.get(i);
+ mWindowNodes.add(new WindowNode(this, root));
+ }
+ }
+
+ public AssistStructure() {
+ mHaveData = true;
+ mActivityComponent = null;
}
- AssistStructure(Parcel in) {
- super(in);
+ /** @hide */
+ public AssistStructure(Parcel in) {
+ mReceiveChannel = in.readStrongBinder();
}
+ /** @hide */
+ public void dump() {
+ Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
+ final int N = getWindowNodeCount();
+ for (int i=0; i<N; i++) {
+ WindowNode node = getWindowNodeAt(i);
+ Log.i(TAG, "Window #" + i + " [" + node.getLeft() + "," + node.getTop()
+ + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getTitle());
+ dump(" ", node.getRootViewNode());
+ }
+ }
+
+ void dump(String prefix, ViewNode node) {
+ Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop()
+ + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName());
+ int id = node.getId();
+ if (id != 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(prefix); sb.append(" ID: #"); sb.append(Integer.toHexString(id));
+ String entry = node.getIdEntry();
+ if (entry != null) {
+ String type = node.getIdType();
+ String pkg = node.getIdPackage();
+ sb.append(" "); sb.append(pkg); sb.append(":"); sb.append(type);
+ sb.append("/"); sb.append(entry);
+ }
+ Log.i(TAG, sb.toString());
+ }
+ int scrollX = node.getScrollX();
+ int scrollY = node.getScrollY();
+ if (scrollX != 0 || scrollY != 0) {
+ Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY);
+ }
+ CharSequence contentDescription = node.getContentDescription();
+ if (contentDescription != null) {
+ Log.i(TAG, prefix + " Content description: " + contentDescription);
+ }
+ CharSequence text = node.getText();
+ if (text != null) {
+ Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
+ + node.getTextSelectionEnd() + "): " + text);
+ Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #"
+ + node.getTextStyle());
+ Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor())
+ + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
+ }
+ String hint = node.getHint();
+ if (hint != null) {
+ Log.i(TAG, prefix + " Hint: " + hint);
+ }
+ Bundle extras = node.getExtras();
+ if (extras != null) {
+ Log.i(TAG, prefix + " Extras: " + extras);
+ }
+ final int NCHILDREN = node.getChildCount();
+ if (NCHILDREN > 0) {
+ Log.i(TAG, prefix + " Children:");
+ String cprefix = prefix + " ";
+ for (int i=0; i<NCHILDREN; i++) {
+ ViewNode cnode = node.getChildAt(i);
+ dump(cprefix, cnode);
+ }
+ }
+ }
+
+ /**
+ * Return the activity this AssistStructure came from.
+ */
+ public ComponentName getActivityComponent() {
+ ensureData();
+ return mActivityComponent;
+ }
+
+ /**
+ * Return the number of window contents that have been collected in this assist data.
+ */
+ public int getWindowNodeCount() {
+ ensureData();
+ return mWindowNodes.size();
+ }
+
+ /**
+ * Return one of the windows in the assist data.
+ * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1.
+ */
public WindowNode getWindowNodeAt(int index) {
- return super.getWindowNodeAt(index);
+ ensureData();
+ return mWindowNodes.get(index);
+ }
+
+ /** @hide */
+ public void ensureData() {
+ if (mHaveData) {
+ return;
+ }
+ mHaveData = true;
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(DESCRIPTOR);
+ try {
+ mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failure reading AssistStructure data", e);
+ return;
+ }
+ readContentFromParcel(reply);
+ data.recycle();
+ reply.recycle();
+ }
+
+ void writeContentToParcel(Parcel out, int flags) {
+ // First make sure all content has been created.
+ boolean skipStructure = false;
+ synchronized (this) {
+ long endTime = SystemClock.uptimeMillis() + 5000;
+ long now;
+ while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) {
+ try {
+ wait(endTime-now);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (mPendingAsyncChildren.size() > 0) {
+ // We waited too long, assume none of the assist structure is valid.
+ skipStructure = true;
+ }
+ }
+ int start = out.dataPosition();
+ PooledStringWriter pwriter = new PooledStringWriter(out);
+ ComponentName.writeToParcel(mActivityComponent, out);
+ final int N = skipStructure ? 0 : mWindowNodes.size();
+ out.writeInt(N);
+ for (int i=0; i<N; i++) {
+ mWindowNodes.get(i).writeToParcel(out, pwriter);
+ }
+ pwriter.finish();
+ Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes");
+ }
+
+ void readContentFromParcel(Parcel in) {
+ PooledStringReader preader = new PooledStringReader(in);
+ mActivityComponent = ComponentName.readFromParcel(in);
+ final int N = in.readInt();
+ for (int i=0; i<N; i++) {
+ mWindowNodes.add(new WindowNode(in, preader));
+ }
+ //dump();
}
public int describeContents() {
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 8a31390..9113426 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -77,6 +77,12 @@ public abstract class UsageStatsManagerInternal {
public abstract boolean isAppIdle(String packageName, int userId);
/**
+ * @return True if currently app idle parole mode is on. This means all idle apps are allow to
+ * run for a short period of time.
+ */
+ public abstract boolean isAppIdleParoleOn();
+
+ /**
* Sets up a listener for changes to packages being accessed.
* @param listener A listener within the system process.
*/
@@ -90,8 +96,9 @@ public abstract class UsageStatsManagerInternal {
public abstract void removeAppIdleStateChangeListener(
AppIdleStateChangeListener listener);
- public interface AppIdleStateChangeListener {
- void onAppIdleStateChanged(String packageName, int userId, boolean idle);
+ public static abstract class AppIdleStateChangeListener {
+ public abstract void onAppIdleStateChanged(String packageName, int userId, boolean idle);
+ public abstract void onParoleStateChanged(boolean isParoleOn);
}
}
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 809f900..58bd5cd 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()}
@@ -261,6 +274,10 @@ public abstract class AbstractThreadedSyncAdapter {
} else {
syncResult.databaseError = true;
}
+ } catch (SecurityException e) {
+ AbstractThreadedSyncAdapter.this.onSecurityException(mAccount, mExtras,
+ mAuthority, syncResult);
+ syncResult.databaseError = true;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
@@ -306,6 +323,20 @@ public abstract class AbstractThreadedSyncAdapter {
String authority, ContentProviderClient provider, SyncResult syncResult);
/**
+ * Report that there was a security exception when opening the content provider
+ * prior to calling {@link #onPerformSync}. This will be treated as a sync
+ * database failure.
+ *
+ * @param account the account that attempted to sync
+ * @param extras SyncAdapter-specific parameters
+ * @param authority the authority of the failed sync request
+ * @param syncResult SyncAdapter-specific parameters
+ */
+ public void onSecurityException(Account account, Bundle extras,
+ String authority, SyncResult syncResult) {
+ }
+
+ /**
* Indicates that a sync operation has been canceled. This will be invoked on a separate
* thread than the sync thread and so you must consider the multi-threaded implications
* of the work that you do in this method.
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0c07bc3..cb68d74 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -31,6 +31,7 @@ import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
+import android.content.pm.IPackagesProvider;
import android.content.pm.IOnPermissionsChangeListener;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.InstrumentationInfo;
@@ -106,6 +107,8 @@ interface IPackageManager {
void updatePermissionFlags(String permissionName, String packageName, int flagMask,
int flagValues, int userId);
+ void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);
+
boolean shouldShowRequestPermissionRationale(String permissionName,
String packageName, int userId);
@@ -282,6 +285,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
@@ -299,18 +306,18 @@ interface IPackageManager {
* As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}.
*/
int getComponentEnabledSetting(in ComponentName componentName, int userId);
-
+
/**
* As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}.
*/
void setApplicationEnabledSetting(in String packageName, in int newState, int flags,
int userId, String callingPackage);
-
+
/**
* As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}.
*/
int getApplicationEnabledSetting(in String packageName, int userId);
-
+
/**
* Set whether the given package should be considered stopped, making
* it not visible to implicit intents that filter out stopped packages.
@@ -363,7 +370,7 @@ interface IPackageManager {
*/
void freeStorage(in String volumeUuid, in long freeStorageSize,
in IntentSender pi);
-
+
/**
* Delete all the cache files in an applications cache directory
* @param packageName The package name of the application whose cache
@@ -371,7 +378,7 @@ interface IPackageManager {
* @param observer a callback used to notify when the deletion is finished.
*/
void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer);
-
+
/**
* Clear the user data directory of an application.
* @param packageName The package name of the application whose cache
@@ -379,7 +386,7 @@ interface IPackageManager {
* @param observer a callback used to notify when the operation is completed.
*/
void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);
-
+
/**
* Get package statistics including the code, data and cache size for
* an already installed package
@@ -389,7 +396,7 @@ interface IPackageManager {
* retrieval of information is complete.
*/
void getPackageSizeInfo(in String packageName, int userHandle, IPackageStatsObserver observer);
-
+
/**
* Get a list of shared libraries that are available on the
* system.
@@ -403,7 +410,7 @@ interface IPackageManager {
FeatureInfo[] getSystemAvailableFeatures();
boolean hasSystemFeature(String name);
-
+
void enterSafeMode();
boolean isSafeMode();
void systemReady();
@@ -494,4 +501,7 @@ interface IPackageManager {
void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
+
+ void grantDefaultPermissions(int userId);
+ void setCarrierAppPackagesProvider(in IPackagesProvider provider);
}
diff --git a/core/java/android/content/pm/IPackagesProvider.aidl b/core/java/android/content/pm/IPackagesProvider.aidl
new file mode 100644
index 0000000..7d76c88
--- /dev/null
+++ b/core/java/android/content/pm/IPackagesProvider.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+/** {@hide} */
+interface IPackagesProvider {
+ String[] getPackages(int userId);
+}
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 4e7da48..04dbff2 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -109,6 +109,14 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_COSTS_MONEY = 1<<0;
/**
+ * Flag for {@link #protectionLevel}, corresponding
+ * to the <code>hide</code> value of
+ * {@link android.R.attr#permissionFlags}.
+ * @hide
+ */
+ public static final int PROTECTION_FLAG_HIDE = 1<<1;
+
+ /**
* Additional flags about this permission as given by
* {@link android.R.attr#permissionFlags}.
*/
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 27d14b3..a88b71c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -628,7 +628,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>List of available high speed video size, fps range and max batch size configurations
* supported by the camera device, in the format of (width, height, fps_min, fps_max, batch_size_max).</p>
- * <p>When CONSTRAINED_HIGH_SPEED_VIDEO is supported in android.control.availableCapabilities,
+ * <p>When CONSTRAINED_HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities},
* this metadata will list the supported high speed video size, fps range and max batch size
* configurations. All the sizes listed in this configuration will be a subset of the sizes
* reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes }
@@ -675,6 +675,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @hide
*/
public static final Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS =
@@ -2679,9 +2680,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 +2688,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 +2708,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 +2730,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..75289f7 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 =
@@ -1759,11 +1759,24 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to
* generate the thumbnail image. The thumbnail image will always have a smaller Field
* Of View (FOV) than the primary image when aspect ratios differ.</p>
+ * <p>When an {@link CaptureRequest#JPEG_ORIENTATION android.jpeg.orientation} of non-zero degree is requested,
+ * the camera device will handle thumbnail rotation in one of the following ways:</p>
+ * <ul>
+ * <li>Set the {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}
+ * and keep jpeg and thumbnail image data unrotated.</li>
+ * <li>Rotate the jpeg and thumbnail image data and not set
+ * {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this
+ * case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+ * capture result, so the width and height will be interchanged if 90 or 270 degree
+ * orientation is requested. LEGACY device will always report unrotated thumbnail
+ * size.</li>
+ * </ul>
* <p><b>Range of valid values:</b><br>
* {@link CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES android.jpeg.availableThumbnailSizes}</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES
+ * @see CaptureRequest#JPEG_ORIENTATION
*/
@PublicKey
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index b1fb615..1d31109 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2314,11 +2314,24 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to
* generate the thumbnail image. The thumbnail image will always have a smaller Field
* Of View (FOV) than the primary image when aspect ratios differ.</p>
+ * <p>When an {@link CaptureRequest#JPEG_ORIENTATION android.jpeg.orientation} of non-zero degree is requested,
+ * the camera device will handle thumbnail rotation in one of the following ways:</p>
+ * <ul>
+ * <li>Set the {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}
+ * and keep jpeg and thumbnail image data unrotated.</li>
+ * <li>Rotate the jpeg and thumbnail image data and not set
+ * {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this
+ * case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+ * capture result, so the width and height will be interchanged if 90 or 270 degree
+ * orientation is requested. LEGACY device will always report unrotated thumbnail
+ * size.</li>
+ * </ul>
* <p><b>Range of valid values:</b><br>
* {@link CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES android.jpeg.availableThumbnailSizes}</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES
+ * @see CaptureRequest#JPEG_ORIENTATION
*/
@PublicKey
public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE =
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..639ad60 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -20,14 +20,16 @@ import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraMetadata;
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 +81,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 +96,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 +125,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 +155,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 +253,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 +286,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 +390,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 +423,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 +453,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 +462,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,36 +480,40 @@ public final class StreamConfigurationMap {
* @see #getOutputFormats
*/
public Size[] getOutputSizes(int format) {
- return getPublicFormatSizes(format, /*output*/true);
+ return getPublicFormatSizes(format, /*output*/true, /*highRes*/ false);
}
/**
* Get a list of supported high speed video recording sizes.
- *
- * <p> When HIGH_SPEED_VIDEO is supported in
- * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this
- * method will list the supported high speed video size configurations. All the sizes listed
- * will be a subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling
- * formats (typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12)</p>
- *
- * <p> To enable high speed video recording, application must set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests and select the video size from this method and
+ * <p>
+ * When {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} is
+ * supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}, this method will
+ * list the supported high speed video size configurations. All the sizes listed will be a
+ * subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling formats
+ * (typically {@link ImageFormat#PRIVATE} {@link ImageFormat#YUV_420_888}, etc.)
+ * </p>
+ * <p>
+ * To enable high speed video recording, application must create a constrained create high speed
+ * capture session via {@link CameraDevice#createConstrainedHighSpeedCaptureSession}, and submit
+ * a CaptureRequest list created by {@link CameraDevice#createConstrainedHighSpeedRequestList}
+ * to this session. The application must select the video size from this method and
* {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from
- * {@link #getHighSpeedVideoFpsRangesFor} to configure the recording and preview streams and
- * setup the recording requests. For example, if the application intends to do high speed
- * recording, it can select the maximum size reported by this method to configure output
- * streams. Note that for the use case of multiple output streams, application must select one
- * unique size from this method to use. Otherwise a request error might occur. Once the size is
+ * {@link #getHighSpeedVideoFpsRangesFor} to configure the constrained high speed session and
+ * generate the high speed request list. For example, if the application intends to do high
+ * speed recording, it can select the maximum size reported by this method to create high speed
+ * capture session. Note that for the use case of multiple output streams, application must
+ * select one unique size from this method to use (e.g., preview and recording streams must have
+ * the same size). Otherwise, the high speed session creation will fail. Once the size is
* selected, application can get the supported FPS ranges by
* {@link #getHighSpeedVideoFpsRangesFor}, and use these FPS ranges to setup the recording
- * requests.</p>
- *
- * @return
- * an array of supported high speed video recording sizes
+ * request lists via {@link CameraDevice#createConstrainedHighSpeedRequestList}.
+ * </p>
*
+ * @return an array of supported high speed video recording sizes
* @see #getHighSpeedVideoFpsRangesFor(Size)
+ * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
+ * @see CameraDevice#createConstrainedHighSpeedCaptureSession
+ * @see CameraDevice#createConstrainedHighSpeedRequestList
*/
public Size[] getHighSpeedVideoSizes() {
Set<Size> keySet = mHighSpeedVideoSizeMap.keySet();
@@ -501,26 +522,25 @@ public final class StreamConfigurationMap {
/**
* Get the frame per second ranges (fpsMin, fpsMax) for input high speed video size.
- *
- * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p>
- *
- * <p> For normal video recording use case, where some application will NOT set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in
- * this method must not be used to setup capture requests, or it will cause request error.</p>
+ * <p>
+ * See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording.
+ * </p>
+ * <p>
+ * The {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in this method
+ * must not be used to setup capture requests that are submitted to unconstrained capture
+ * sessions, or it will result in {@link IllegalArgumentException IllegalArgumentExceptions}.
+ * </p>
+ * <p>
+ * See {@link #getHighSpeedVideoFpsRanges} for the characteristics of the returned FPS ranges.
+ * </p>
*
* @param size one of the sizes returned by {@link #getHighSpeedVideoSizes()}
- * @return
- * An array of FPS range to use with
- * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE TARGET_FPS_RANGE} when using
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene
- * mode.
- * The upper bound of returned ranges is guaranteed to be larger or equal to 60.
- *
+ * @return an array of supported high speed video recording FPS ranges The upper bound of
+ * returned ranges is guaranteed to be greater than or equal to 120.
* @throws IllegalArgumentException if input size does not exist in the return value of
- * getHighSpeedVideoSizes
+ * getHighSpeedVideoSizes
* @see #getHighSpeedVideoSizes()
+ * @see #getHighSpeedVideoFpsRanges()
*/
public Range<Integer>[] getHighSpeedVideoFpsRangesFor(Size size) {
Integer fpsRangeCount = mHighSpeedVideoSizeMap.get(size);
@@ -542,34 +562,46 @@ public final class StreamConfigurationMap {
/**
* Get a list of supported high speed video recording FPS ranges.
- *
- * <p> When HIGH_SPEED_VIDEO is supported in
- * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this
- * method will list the supported high speed video FPS range configurations. Application can
- * then use {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned
- * FPS range.</p>
- *
- * <p> To enable high speed video recording, application must set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests and select the video size from {@link #getHighSpeedVideoSizesFor} and
+ * <p>
+ * When {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} is
+ * supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}, this method will
+ * list the supported high speed video FPS range configurations. Application can then use
+ * {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned FPS range.
+ * </p>
+ * <p>
+ * To enable high speed video recording, application must create a constrained create high speed
+ * capture session via {@link CameraDevice#createConstrainedHighSpeedCaptureSession}, and submit
+ * a CaptureRequest list created by {@link CameraDevice#createConstrainedHighSpeedRequestList}
+ * to this session. The application must select the video size from this method and
* {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from
- * this method to configure the recording and preview streams and setup the recording requests.
- * For example, if the application intends to do high speed recording, it can select one FPS
- * range reported by this method, query the video sizes corresponding to this FPS range by
- * {@link #getHighSpeedVideoSizesFor} and select one of reported sizes to configure output
- * streams. Note that for the use case of multiple output streams, application must select one
- * unique size from {@link #getHighSpeedVideoSizesFor}, and use it for all output streams.
- * Otherwise a request error might occur when attempting to enable
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}.
- * Once the stream is configured, application can set the FPS range in the recording requests.
+ * {@link #getHighSpeedVideoFpsRangesFor} to configure the constrained high speed session and
+ * generate the high speed request list. For example, if the application intends to do high
+ * speed recording, it can select one FPS range reported by this method, query the video sizes
+ * corresponding to this FPS range by {@link #getHighSpeedVideoSizesFor} and use one of reported
+ * sizes to create a high speed capture session. Note that for the use case of multiple output
+ * streams, application must select one unique size from this method to use (e.g., preview and
+ * recording streams must have the same size). Otherwise, the high speed session creation will
+ * fail. Once the high speed capture session is created, the application can set the FPS range
+ * in the recording request lists via
+ * {@link CameraDevice#createConstrainedHighSpeedRequestList}.
+ * </p>
+ * <p>
+ * The FPS ranges reported by this method will have below characteristics:
+ * <li>The fpsMin and fpsMax will be a multiple 30fps.</li>
+ * <li>The fpsMin will be no less than 30fps, the fpsMax will be no less than 120fps.</li>
+ * <li>At least one range will be a fixed FPS range where fpsMin == fpsMax.</li>
+ * <li>For each fixed FPS range, there will be one corresponding variable FPS range [30,
+ * fps_max]. These kinds of FPS ranges are suitable for preview-only use cases where the
+ * application doesn't want the camera device always produce higher frame rate than the display
+ * refresh rate.</li>
* </p>
*
- * @return
- * an array of supported high speed video recording FPS ranges
- * The upper bound of returned ranges is guaranteed to be larger or equal to 60.
- *
+ * @return an array of supported high speed video recording FPS ranges The upper bound of
+ * returned ranges is guaranteed to be larger or equal to 120.
* @see #getHighSpeedVideoSizesFor
+ * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO
+ * @see CameraDevice#createConstrainedHighSpeedCaptureSession
+ * @see CameraDevice#createConstrainedHighSpeedRequestList
*/
@SuppressWarnings("unchecked")
public Range<Integer>[] getHighSpeedVideoFpsRanges() {
@@ -578,21 +610,13 @@ public final class StreamConfigurationMap {
}
/**
- * Get the supported video sizes for input FPS range.
+ * Get the supported video sizes for an input high speed FPS range.
*
- * <p> See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording.</p>
- *
- * <p> For normal video recording use case, where the application will NOT set
- * {@link CaptureRequest#CONTROL_SCENE_MODE} to
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture
- * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in
- * this method must not be used to setup capture requests, or it will cause request error.</p>
+ * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p>
*
* @param fpsRange one of the FPS range returned by {@link #getHighSpeedVideoFpsRanges()}
- * @return
- * An array of video sizes to configure output stream when using
- * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene
- * mode.
+ * @return An array of video sizes to create high speed capture sessions for high speed streaming
+ * use cases.
*
* @throws IllegalArgumentException if input FPS range does not exist in the return value of
* getHighSpeedVideoFpsRanges
@@ -616,6 +640,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 +917,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 +930,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 +1239,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 +1249,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 +1311,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 +1331,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 +1376,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 +1402,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 +1452,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 +1484,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 +1603,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 +1635,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 +1657,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/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index b9f7365..80476ea 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2110,6 +2110,8 @@ public class ConnectivityManager {
* can automatically log in to a captive portal without user intervention.
*
* @param network The {@link Network} of the network that is being evaluated.
+ *
+ * @hide
*/
public void onPreCheck(Network network) {}
@@ -2379,6 +2381,14 @@ public class ConnectivityManager {
* Status of the request can be followed by listening to the various
* callbacks described in {@link NetworkCallback}. The {@link Network}
* can be used to direct traffic to the network.
+ * <p>It is presently unsupported to request a network with mutable
+ * {@link NetworkCapabilities} such as
+ * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
+ * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
+ * as these {@code NetworkCapabilities} represent states that a particular
+ * network may never attain, and whether a network will attain these states
+ * is unknown prior to bringing up the network so the framework does not
+ * know how to go about satisfing a request with these capabilities.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
*
@@ -2386,6 +2396,8 @@ public class ConnectivityManager {
* @param networkCallback The {@link NetworkCallback} to be utilized for this
* request. Note the callback must not be shared - they
* uniquely specify this request.
+ * @throws IllegalArgumentException if {@code request} specifies any mutable
+ * {@code NetworkCapabilities}.
*/
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
@@ -2467,12 +2479,22 @@ public class ConnectivityManager {
* <p>
* The request may be released normally by calling
* {@link #releaseNetworkRequest(android.app.PendingIntent)}.
+ * <p>It is presently unsupported to request a network with either
+ * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
+ * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
+ * as these {@code NetworkCapabilities} represent states that a particular
+ * network may never attain, and whether a network will attain these states
+ * is unknown prior to bringing up the network so the framework does not
+ * know how to go about satisfing a request with these capabilities.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* @param request {@link NetworkRequest} describing this request.
* @param operation Action to perform when the network is available (corresponds
* to the {@link NetworkCallback#onAvailable} call. Typically
* comes from {@link PendingIntent#getBroadcast}. Cannot be null.
+ * @throws IllegalArgumentException if {@code request} contains either
+ * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
+ * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
*/
public void requestNetwork(NetworkRequest request, PendingIntent operation) {
checkPendingIntent(operation);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index cf747cf..658051c 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -173,12 +173,17 @@ public final class NetworkCapabilities implements Parcelable {
* Indicates that connectivity on this network was successfully validated. For example, for a
* network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
* detected.
- * @hide
*/
public static final int NET_CAPABILITY_VALIDATED = 16;
+ /**
+ * Indicates that this network was found to have a captive portal in place last time it was
+ * probed.
+ */
+ public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
+
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_VALIDATED;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL;
/**
* Adds the given capability to this {@code NetworkCapability} instance.
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/Debug.java b/core/java/android/os/Debug.java
index 87e8c5e..97b85e2 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1469,13 +1469,30 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo
* </tr>
* <tr>
* <td>art.gc.gc-count-rate-histogram</td>
- * <td>The histogram of the number of garbage collection runs per 10 seconds.</td>
+ * <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage
+ * collection runs that have occurred over the last 10
+ * seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate
+ * samples taken since the process began. The histogram can be used to identify
+ * instances of high rates of garbage collection runs. For example, a histogram
+ * of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time
+ * there are between 0 and 2 garbage collection runs every 10 seconds, but there
+ * were 8 distinct 10-second intervals in which 5 garbage collection runs
+ * occurred.</td>
* <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td>
* <td>23</td>
* </tr>
* <tr>
* <td>art.gc.blocking-gc-count-rate-histogram</td>
- * <td>The histogram of the number of garbage collection runs per 10 seconds.</td>
+ * <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of
+ * blocking garbage collection runs that have occurred over the last 10
+ * seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the
+ * blocking-gc-count-rate samples taken since the process began. The histogram
+ * can be used to identify instances of high rates of blocking garbage
+ * collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that
+ * most of the time there are zero blocking garbage collection runs every 10
+ * seconds, but there was one 10-second interval in which one blocking garbage
+ * collection run occurred, and there was one interval in which two blocking
+ * garbage collection runs occurred.</td>
* <td>{@code 0:99269,1:1,2:1}</td>
* <td>23</td>
* </tr>
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 1cc2d33..f10b982 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -1919,9 +1919,9 @@ public final class StrictMode {
for (int i = 0; i < numViolations; ++i) {
if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i);
ViolationInfo info = new ViolationInfo(p, !currentlyGathering);
- if (info.crashInfo.stackTrace != null && info.crashInfo.stackTrace.length() > 10000) {
+ if (info.crashInfo.stackTrace != null && info.crashInfo.stackTrace.length() > 30000) {
String front = info.crashInfo.stackTrace.substring(256);
- // 10000 characters is way too large for this to be any sane kind of
+ // 30000 characters is way too large for this to be any sane kind of
// strict mode collection of stacks. We've had a problem where we leave
// strict mode violations associated with the thread, and it keeps tacking
// more and more stacks on to the violations. Looks like we're in this casse,
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/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index aebe7f1..8ce1cbf 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1743,6 +1743,9 @@ public final class ContactsContract {
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItems implements StreamItemsColumns {
@@ -2831,6 +2834,9 @@ public final class ContactsContract {
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
@@ -3267,6 +3273,9 @@ public final class ContactsContract {
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
@@ -3365,6 +3374,9 @@ public final class ContactsContract {
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItemPhotos
@@ -3415,6 +3427,9 @@ public final class ContactsContract {
* @see ContactsContract.StreamItems
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
protected interface StreamItemsColumns {
@@ -3805,6 +3820,9 @@ public final class ContactsContract {
*
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns {
@@ -3843,6 +3861,9 @@ public final class ContactsContract {
* @see ContactsContract.StreamItemPhotos
* @deprecated - Do not use. This will not be supported in the future. In the future,
* cursors returned from related queries will be empty.
+ *
+ * @hide
+ * @removed
*/
@Deprecated
protected interface StreamItemPhotosColumns {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 56cd1a7..9b5fbfa 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6685,6 +6685,17 @@ public final class Settings {
"wifi_mobile_data_transition_wakelock_timeout_ms";
/**
+ * This setting controls whether WiFi configurations created by a Device Owner app
+ * should be locked down (that is, be editable or removable only by the Device Owner App,
+ * not even by Settings app).
+ * This setting takes integer values. Non-zero values mean DO created configurations
+ * are locked down. Value of zero means they are not. Default value in the absence of
+ * actual value to this setting is 0.
+ */
+ public static final String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN =
+ "wifi_device_owner_configs_lockdown";
+
+ /**
* The operational wifi frequency band
* Set to one of {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO},
* {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ} or
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index 82f65c7..363376c 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -85,6 +85,12 @@ public class KeymasterArguments implements Parcelable {
mArguments.add(new KeymasterDateArgument(tag, value));
}
+ public void addDateIfNotNull(int tag, Date value) {
+ if (value != null) {
+ mArguments.add(new KeymasterDateArgument(tag, value));
+ }
+ }
+
private KeymasterArgument getArgumentByTag(int tag) {
for (KeymasterArgument arg : mArguments) {
if (arg.tag == tag) {
diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java
index 225e70d..455e1b2 100644
--- a/core/java/android/service/carrier/CarrierService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -29,8 +29,8 @@ import com.android.internal.telephony.ITelephonyRegistry;
* <p>
* To extend this class, you must declare the service in your manifest file to require the
* {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent
- * filter with the {@link #CONFIG_SERVICE_INTERFACE} action if the service exposes carrier config
- * and the {@link #BIND_SERVICE_INTERFACE} action if the service should have a long-lived binding.
+ * filter with the {@link #CARRIER_SERVICE_INTERFACE}. If the service should have a long-lived
+ * binding, set android.service.carrier.LONG_LIVED_BINDING to true in the service's metadata.
* For example:
* </p>
*
@@ -39,16 +39,16 @@ import com.android.internal.telephony.ITelephonyRegistry;
* android:label="@string/service_name"
* android:permission="android.permission.BIND_CARRIER_SERVICES">
* <intent-filter>
- * <action android:name="android.service.carrier.ConfigService" />
- * <action android:name="android.service.carrier.BindService" />
+ * <action android:name="android.service.carrier.CarrierService" />
* </intent-filter>
+ * <meta-data android:name="android.service.carrier.LONG_LIVED_BINDING"
+ * android:value="true" />
* </service>
* }</pre>
*/
public abstract class CarrierService extends Service {
- public static final String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService";
- public static final String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService";
+ public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService";
private static ITelephonyRegistry sRegistry;
@@ -127,13 +127,7 @@ public abstract class CarrierService extends Service {
@Override
@CallSuper
public IBinder onBind(Intent intent) {
- switch (intent.getAction()) {
- case CONFIG_SERVICE_INTERFACE:
- case BIND_SERVICE_INTERFACE:
- return mStubWrapper;
- default:
- return null;
- }
+ return mStubWrapper;
}
/**
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 39dd29b..f9e216a 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1146,20 +1146,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
mContentFrame.requestApplyInsets();
}
- /** @hide */
- public void onHandleAssist(Bundle assistBundle) {
- }
-
public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
- if (data != null) {
- Bundle assistContext = data.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
- if (assistContext != null) {
- assistContext.putParcelable(AssistStructure.ASSIST_KEY, structure);
- assistContext.putParcelable(AssistContent.ASSIST_KEY, content);
- data.putBundle(Intent.EXTRA_ASSIST_CONTEXT, assistContext);
- }
- }
- onHandleAssist(data);
}
public void onHandleScreenshot(Bitmap screenshot) {
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/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 13a959e..47d5c79 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -16,6 +16,7 @@
package android.text.format;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.net.NetworkUtils;
@@ -52,7 +53,10 @@ public final class Formatter {
* @param sizeBytes size value to be formatted, in bytes
* @return formatted string with the number
*/
- public static String formatFileSize(Context context, long sizeBytes) {
+ public static String formatFileSize(@Nullable Context context, long sizeBytes) {
+ if (context == null) {
+ return "";
+ }
final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0);
return context.getString(com.android.internal.R.string.fileSizeSuffix,
res.value, res.units);
@@ -62,7 +66,10 @@ public final class Formatter {
* Like {@link #formatFileSize}, but trying to generate shorter numbers
* (showing fewer digits of precision).
*/
- public static String formatShortFileSize(Context context, long sizeBytes) {
+ public static String formatShortFileSize(@Nullable Context context, long sizeBytes) {
+ if (context == null) {
+ return "";
+ }
final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER);
return context.getString(com.android.internal.R.string.fileSizeSuffix,
res.value, res.units);
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 8b74a1e..585fc4e 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -504,13 +504,20 @@ public abstract class Visibility extends Transition {
private final boolean mIsForcedVisibility;
private final View mView;
private final int mFinalVisibility;
+ private final ViewGroup mParent;
+ private boolean mEnded;
boolean mCanceled = false;
public DisappearListener(View view, int finalVisibility, boolean isForcedVisibility) {
this.mView = view;
this.mIsForcedVisibility = isForcedVisibility;
this.mFinalVisibility = finalVisibility;
+ this.mParent = (ViewGroup) view.getParent();
+ if (!isForcedVisibility && mParent != null) {
+ // Prevent a layout from including mView in its calculation.
+ mParent.suppressLayout(true);
+ }
}
@Override
@@ -552,13 +559,39 @@ public abstract class Visibility extends Transition {
hideViewWhenNotCanceled();
}
+ @Override
+ public void onTransitionPause(Transition transition) {
+ if (mParent != null && !mIsForcedVisibility) {
+ mParent.suppressLayout(false);
+ }
+ }
+
+ @Override
+ public void onTransitionResume(Transition transition) {
+ if (mParent != null && !mIsForcedVisibility) {
+ mParent.suppressLayout(true);
+ }
+ }
+
private void hideViewWhenNotCanceled() {
- if (!mCanceled) {
- if (mIsForcedVisibility) {
- mView.setTransitionAlpha(0);
- } else {
- mView.setVisibility(mFinalVisibility);
+ if (!mEnded) {
+ if (!mCanceled) {
+ if (mIsForcedVisibility) {
+ mView.setTransitionAlpha(0);
+ } else {
+ // Recreate the parent's display list in case it includes mView.
+ mView.setTransitionVisibility(mFinalVisibility);
+ if (mParent != null) {
+ mParent.invalidate();
+ }
+ }
+ }
+ if (!mIsForcedVisibility && mParent != null) {
+ // Layout is allowed now that the View is in its final state
+ mParent.suppressLayout(false);
}
+ // Do this only once
+ mEnded = true;
}
}
}
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/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 4394cd8..6026d04 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1399,6 +1399,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
private static native int nativeGetButtonState(long nativePtr);
private static native void nativeSetButtonState(long nativePtr, int buttonState);
private static native int nativeGetActionButton(long nativePtr);
+ private static native void nativeSetActionButton(long nativePtr, int actionButton);
private static native void nativeOffsetLocation(long nativePtr, float deltaX, float deltaY);
private static native float nativeGetXOffset(long nativePtr);
private static native float nativeGetYOffset(long nativePtr);
@@ -2284,6 +2285,16 @@ public final class MotionEvent extends InputEvent implements Parcelable {
}
/**
+ * Sets the action button for the event.
+ *
+ * @see #getActionButton()
+ * @hide
+ */
+ public final void setActionButton(int button) {
+ nativeSetActionButton(mNativePtr, button);
+ }
+
+ /**
* Returns the original raw X coordinate of this event. For touch
* events on the screen, this is the original location of the event
* on the screen, before it had been adjusted for the containing window
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 4074529..5970c3f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -453,6 +453,19 @@ public class SurfaceControl {
}
}
+ /**
+ * Sets the security of the surface. Setting the flag is equivalent to creating the
+ * Surface with the {@link #SECURE} flag.
+ */
+ public void setSecure(boolean isSecure) {
+ checkNotReleased();
+ if (isSecure) {
+ nativeSetFlags(mNativeObject, SECURE, SECURE);
+ } else {
+ nativeSetFlags(mNativeObject, 0, SECURE);
+ }
+ }
+
/*
* set display parameters.
* needs to be inside open/closeTransaction block
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fd3ee4f..92dae2e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6032,7 +6032,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public AccessibilityNodeInfo createAccessibilityNodeInfoInternal() {
AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
if (provider != null) {
- return provider.createAccessibilityNodeInfo(View.NO_ID);
+ return provider.createAccessibilityNodeInfo(AccessibilityNodeProvider.HOST_VIEW_ID);
} else {
AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this);
onInitializeAccessibilityNodeInfo(info);
@@ -6326,6 +6326,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+ if (mAttachInfo == null) {
+ return;
+ }
+
Rect bounds = mAttachInfo.mTmpInvalRect;
getDrawingRect(bounds);
@@ -8774,7 +8778,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
- if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
return;
}
if (mSendViewStateChangedAccessibilityEvent == null) {
@@ -8796,7 +8800,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public void notifySubtreeAccessibilityStateChangedIfNeeded() {
- if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
return;
}
if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index d06cd83..3572f1e 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -150,7 +150,7 @@ public abstract class ViewStructure {
* @param size The size, in pixels, of the text.
* @param fgColor The foreground color, packed as 0xAARRGGBB.
* @param bgColor The background color, packed as 0xAARRGGBB.
- * @param style Style flags, as defined by {@link android.app.AssistStructure.ViewNode}.
+ * @param style Style flags, as defined by {@link android.app.assist.AssistStructure.ViewNode}.
*/
public abstract void setTextStyle(float size, int fgColor, int bgColor, int style);
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index ab793e0..87706ef 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -1115,7 +1115,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
record.mParcelableData = parcel.readParcelable(null);
parcel.readList(record.mText, null);
record.mSourceWindowId = parcel.readInt();
- record.mSourceNodeId = parcel.readLong();
+ record.mSourceNode = parcel.readParcelable(null);
record.mSealed = (parcel.readInt() == 1);
}
@@ -1167,7 +1167,10 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
parcel.writeParcelable(record.mParcelableData, flags);
parcel.writeList(record.mText);
parcel.writeInt(record.mSourceWindowId);
- parcel.writeLong(record.mSourceNodeId);
+ // create copy of the node here because the node would be recycled just after it is written
+ // to parcel
+ parcel.writeParcelable(record.mSourceNode != null ?
+ AccessibilityNodeInfo.obtain(record.mSourceNode) : null, flags);
parcel.writeInt(record.mSealed ? 1 : 0);
}
@@ -1191,7 +1194,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
builder.append("\n");
builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
builder.append("; sourceWindowId: ").append(mSourceWindowId);
- builder.append("; mSourceNodeId: ").append(mSourceNodeId);
+ if (mSourceNode != null) {
+ builder.append("; mSourceNodeId: ").append(mSourceNode.getSourceNodeId());
+ }
for (int i = 0; i < getRecordCount(); i++) {
final AccessibilityRecord record = getRecord(i);
builder.append(" Record ");
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 36de8f3..86ed499 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -2821,7 +2821,7 @@ public class AccessibilityNodeInfo implements Parcelable {
* @param parcel A parcel containing the state of a {@link AccessibilityNodeInfo}.
*/
private void initFromParcel(Parcel parcel) {
- mSealed = (parcel.readInt() == 1);
+ final boolean sealed = (parcel.readInt() == 1);
mSourceNodeId = parcel.readLong();
mWindowId = parcel.readInt();
mParentNodeId = parcel.readLong();
@@ -2911,6 +2911,8 @@ public class AccessibilityNodeInfo implements Parcelable {
parcel.readInt() == 1,
parcel.readInt() == 1);
}
+
+ mSealed = sealed;
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index cc6a71d..f99690a 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -90,7 +90,7 @@ public class AccessibilityRecord {
int mAddedCount= UNDEFINED;
int mRemovedCount = UNDEFINED;
- long mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED);
+ AccessibilityNodeInfo mSourceNode;
int mSourceWindowId = UNDEFINED;
CharSequence mClassName;
@@ -135,16 +135,24 @@ public class AccessibilityRecord {
*/
public void setSource(View root, int virtualDescendantId) {
enforceNotSealed();
- final boolean important;
- if (virtualDescendantId == UNDEFINED) {
- important = (root != null) ? root.isImportantForAccessibility() : true;
- } else {
- important = true;
+ boolean important = true;
+ mSourceWindowId = UNDEFINED;
+ clearSourceNode();
+ if (root != null) {
+ if (virtualDescendantId == UNDEFINED ||
+ virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ important = root.isImportantForAccessibility();
+ mSourceNode = root.createAccessibilityNodeInfo();
+ } else {
+ AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
+ if (provider != null) {
+ mSourceNode = provider.createAccessibilityNodeInfo(virtualDescendantId);
+ }
+ }
+
+ mSourceWindowId = root.getAccessibilityWindowId();
}
setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important);
- mSourceWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED;
- final int rootViewId = (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
- mSourceNodeId = AccessibilityNodeInfo.makeNodeId(rootViewId, virtualDescendantId);
}
/**
@@ -158,13 +166,11 @@ public class AccessibilityRecord {
*/
public AccessibilityNodeInfo getSource() {
enforceSealed();
- if (mConnectionId == UNDEFINED || mSourceWindowId == UNDEFINED
- || AccessibilityNodeInfo.getAccessibilityViewId(mSourceNodeId) == UNDEFINED) {
- return null;
+ if (mSourceNode != null) {
+ return AccessibilityNodeInfo.obtain(mSourceNode);
}
- AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
- return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId,
- mSourceNodeId, false, GET_SOURCE_PREFETCH_FLAGS);
+
+ return null;
}
/**
@@ -619,7 +625,7 @@ public class AccessibilityRecord {
* @hide
*/
public long getSourceNodeId() {
- return mSourceNodeId;
+ return mSourceNode != null ? mSourceNode.getSourceNodeId() : UNDEFINED;
}
/**
@@ -633,6 +639,9 @@ public class AccessibilityRecord {
public void setConnectionId(int connectionId) {
enforceNotSealed();
mConnectionId = connectionId;
+ if (mSourceNode != null) {
+ mSourceNode.setConnectionId(mConnectionId);
+ }
}
/**
@@ -644,6 +653,9 @@ public class AccessibilityRecord {
*/
public void setSealed(boolean sealed) {
mSealed = sealed;
+ if (mSourceNode != null) {
+ mSourceNode.setSealed(sealed);
+ }
}
/**
@@ -782,7 +794,9 @@ public class AccessibilityRecord {
mParcelableData = record.mParcelableData;
mText.addAll(record.mText);
mSourceWindowId = record.mSourceWindowId;
- mSourceNodeId = record.mSourceNodeId;
+ if (record.mSourceNode != null) {
+ mSourceNode = AccessibilityNodeInfo.obtain(record.mSourceNode);
+ }
mConnectionId = record.mConnectionId;
}
@@ -807,11 +821,18 @@ public class AccessibilityRecord {
mBeforeText = null;
mParcelableData = null;
mText.clear();
- mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED);
+ clearSourceNode();
mSourceWindowId = UNDEFINED;
mConnectionId = UNDEFINED;
}
+ private void clearSourceNode() {
+ if (mSourceNode != null) {
+ mSourceNode.recycle();
+ mSourceNode = null;
+ }
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
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/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 f733eab..e84ba99 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -25,7 +25,7 @@ import android.annotation.StringRes;
import android.annotation.StyleRes;
import android.annotation.XmlRes;
import android.app.Activity;
-import android.app.AssistStructure;
+import android.app.assist.AssistStructure;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -9443,10 +9443,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void onRtlPropertiesChanged(int layoutDirection) {
super.onRtlPropertiesChanged(layoutDirection);
- mTextDir = getTextDirectionHeuristic();
-
- if (mLayout != null) {
- checkForRelayout();
+ final TextDirectionHeuristic newTextDir = getTextDirectionHeuristic();
+ if (mTextDir != newTextDir) {
+ mTextDir = newTextDir;
+ if (mLayout != null) {
+ checkForRelayout();
+ }
}
}