Merge "Migrate 'csp_enabled' to CarrierConfigManager." into mnc-dev
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 1461380..e178087 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -35,6 +35,9 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
+import android.os.TransactionTooLargeException;
+import android.util.Log;
+
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.content.ReferrerIntent;
 
@@ -921,8 +924,13 @@
         info.writeToParcel(data, 0);
         compatInfo.writeToParcel(data, 0);
         data.writeInt(processState);
-        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
-                IBinder.FLAG_ONEWAY);
+        try {
+            mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
+                    IBinder.FLAG_ONEWAY);
+        } catch (TransactionTooLargeException e) {
+            Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
+            throw e;
+        }
         data.recycle();
     }
 
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index f928a555..bc80fc1 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -630,8 +630,6 @@
                 holder.width = surfaceSize.getWidth();
                 holder.height = surfaceSize.getHeight();
                 if (LegacyCameraDevice.needsConversion(s)) {
-                    // Always override to YV12 output for YUV surface formats.
-                    LegacyCameraDevice.setSurfaceFormat(s, ImageFormat.YV12);
                     mConversionSurfaces.add(holder);
                 } else {
                     mSurfaces.add(holder);
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index dbb5146..f9c50f3 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -635,8 +635,8 @@
             if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
                 argsForZygote.add("--enable-jit");
             }
-            if ((debugFlags & Zygote.DEBUG_GENERATE_CFI) != 0) {
-                argsForZygote.add("--generate-cfi");
+            if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
+                argsForZygote.add("--generate-debug-info");
             }
             if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
                 argsForZygote.add("--enable-assert");
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 2f5c9e2..7db88af 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -298,14 +298,27 @@
      * Notify the host application to handle a SSL client certificate
      * request. The host application is responsible for showing the UI
      * if desired and providing the keys. There are three ways to
-     * respond: proceed(), cancel() or ignore(). Webview remembers the
-     * response if proceed() or cancel() is called and does not
-     * call onReceivedClientCertRequest() again for the same host and port
-     * pair. Webview does not remember the response if ignore() is called.
+     * respond: proceed(), cancel() or ignore(). Webview stores the response
+     * in memory (for the life of the application) if proceed() or cancel() is
+     * called and does not call onReceivedClientCertRequest() again for the
+     * same host and port pair. Webview does not store the response if ignore()
+     * is called.
      *
      * This method is called on the UI thread. During the callback, the
      * connection is suspended.
      *
+     * For most use cases, the application program should implement the
+     * {@link android.security.KeyChainAliasCallback} interface and pass it to
+     * {@link android.security.KeyChain.choosePrivateKeyAlias} to start an
+     * activity for the user to choose the proper alias. The keychain activity will
+     * provide the alias through the callback method in the implemented interface. Next
+     * the application should create an async task to call
+     * {@link android.security.KeyChain.getPrivateKey} to receive the key.
+     *
+     * An example implementation of client certificates can be seen at
+     * <A href="https://android.googlesource.com/platform/packages/apps/Browser/+/android-5.1.1_r1/src/com/android/browser/Tab.java">
+     * AOSP Browser</a>
+     *
      * The default behavior is to cancel, returning no client certificate.
      *
      * @param view The WebView that is initiating the callback
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index afc683a..534bfad 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -105,7 +105,7 @@
     private final ListSelectorHider mHideSelector = new ListSelectorHider();
     private Runnable mShowDropDownRunnable;
 
-    private Handler mHandler = new Handler();
+    private final Handler mHandler;
 
     private Rect mTempRect = new Rect();
 
@@ -212,6 +212,7 @@
      */
     public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         mContext = context;
+        mHandler = new Handler(context.getMainLooper());
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPopupWindow,
                 defStyleAttr, defStyleRes);
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 339038e..affc5da 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -522,7 +522,7 @@
         View baselineView = null;
         LayoutParams baselineParams = null;
         for (int i = 0; i < count; i++) {
-            final View child = views[i];
+            final View child = getChildAt(i);
             if (child.getVisibility() != GONE) {
                 final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
                 if (baselineView == null || baselineParams == null
@@ -548,9 +548,9 @@
 
             if (offsetHorizontalAxis) {
                 for (int i = 0; i < count; i++) {
-                    final View child = views[i];
+                    View child = getChildAt(i);
                     if (child.getVisibility() != GONE) {
-                        final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                        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 @@
 
             if (offsetVerticalAxis) {
                 for (int i = 0; i < count; i++) {
-                    final View child = views[i];
+                    View child = getChildAt(i);
                     if (child.getVisibility() != GONE) {
-                        final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                        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 @@
             final int verticalOffset = contentBounds.top - top;
             if (horizontalOffset != 0 || verticalOffset != 0) {
                 for (int i = 0; i < count; i++) {
-                    final View child = views[i];
+                    View child = getChildAt(i);
                     if (child.getVisibility() != GONE && child != ignore) {
-                        final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                        LayoutParams params = (LayoutParams) child.getLayoutParams();
                         if (horizontalGravity) {
                             params.mLeft += horizontalOffset;
                             params.mRight += horizontalOffset;
@@ -626,9 +626,9 @@
         if (isLayoutRtl()) {
             final int offsetWidth = myWidth - width;
             for (int i = 0; i < count; i++) {
-                final View child = views[i];
+                View child = getChildAt(i);
                 if (child.getVisibility() != GONE) {
-                    final LayoutParams params = (LayoutParams) child.getLayoutParams();
+                    LayoutParams params = (LayoutParams) child.getLayoutParams();
                     params.mLeft -= offsetWidth;
                     params.mRight -= offsetWidth;
                 }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 4f6d781..c97fdf4 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -41,8 +41,8 @@
     public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
     /** enable the JIT compiler */
     public static final int DEBUG_ENABLE_JIT         = 1 << 5;
-    /** Force generation of CFI code */
-    public static final int DEBUG_GENERATE_CFI       = 1 << 6;
+    /** Force generation of native debugging information. */
+    public static final int DEBUG_GENERATE_DEBUG_INFO = 1 << 6;
 
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = 0;
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 1a0345b..fa870b9 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -322,7 +322,7 @@
 
         /**
          * From --enable-debugger, --enable-checkjni, --enable-assert,
-         * --enable-safemode, --enable-jit, --generate-cfi and --enable-jni-logging.
+         * --enable-safemode, --enable-jit, --generate-debug-info and --enable-jni-logging.
          */
         int debugFlags;
 
@@ -434,8 +434,8 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
                 } else if (arg.equals("--enable-jit")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
-                } else if (arg.equals("--generate-cfi")) {
-                    debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+                } else if (arg.equals("--generate-debug-info")) {
+                    debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
                 } else if (arg.equals("--enable-jni-logging")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
                 } else if (arg.equals("--enable-assert")) {
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 9f99f62..0732add 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -64,5 +64,7 @@
      *        bar caused by this app transition in millis
      */
     void appTransitionStarting(long statusBarAnimationsStartTime, long statusBarAnimationsDuration);
+
+    void showAssistDisclosure();
 }
 
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 65f2f53f..523663c 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -546,25 +546,25 @@
         private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
             refreshViewPort();
 
-            int availableHeightAboveContent =
-                    contentRect.top - mViewPort.top - 2 * mMarginVertical;
-            int availableHeightBelowContent =
-                    mViewPort.bottom - contentRect.bottom - 2 * mMarginVertical;
-            int availableHeightThroughContent =
-                    mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
-
             int x = contentRect.centerX() - getWidth() / 2;
             // Update x so that the toolbar isn't rendered behind the nav bar in landscape.
             x = Math.max(0, Math.min(x, mViewPort.right - getWidth()));
 
             int y;
+
+            int availableHeightAboveContent = contentRect.top - mViewPort.top;
+            int availableHeightBelowContent = mViewPort.bottom - contentRect.bottom;
+
             if (mOverflowPanel == null) {  // There is no overflow.
-                if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()) {
+                if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()) {
                     // There is enough space at the top of the content.
                     y = contentRect.top - getToolbarHeightWithVerticalMargin();
-                } else if (availableHeightBelowContent > getToolbarHeightWithVerticalMargin()) {
+                } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) {
                     // There is enough space at the bottom of the content.
                     y = contentRect.bottom;
+                } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(getContext())) {
+                    // Just enough space to fit the toolbar with no vertical margins.
+                    y = contentRect.bottom - mMarginVertical;
                 } else {
                     // Not enough space. Prefer to position as high as possible.
                     y = Math.max(
@@ -572,32 +572,47 @@
                             contentRect.top - getToolbarHeightWithVerticalMargin());
                 }
             } else {  // There is an overflow.
-                if (availableHeightAboveContent > mOverflowPanel.getMinimumHeight()) {
+                int margin = 2 * mMarginVertical;
+                int minimumOverflowHeightWithMargin = mOverflowPanel.getMinimumHeight() + margin;
+                int availableHeightThroughContentDown =
+                        mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
+                int availableHeightThroughContentUp =
+                        contentRect.bottom - mViewPort.top + getToolbarHeightWithVerticalMargin();
+
+                if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) {
                     // There is enough space at the top of the content rect for the overflow.
                     // Position above and open upwards.
-                    updateOverflowHeight(availableHeightAboveContent);
+                    updateOverflowHeight(availableHeightAboveContent - margin);
                     y = contentRect.top - getHeight();
                     mOverflowDirection = OVERFLOW_DIRECTION_UP;
-                } else if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()
-                        && availableHeightThroughContent > mOverflowPanel.getMinimumHeight()) {
+                } else if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()
+                        && availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) {
                     // There is enough space at the top of the content rect for the main panel
                     // but not the overflow.
                     // Position above but open downwards.
-                    updateOverflowHeight(availableHeightThroughContent);
+                    updateOverflowHeight(availableHeightThroughContentDown - margin);
                     y = contentRect.top - getToolbarHeightWithVerticalMargin();
                     mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
-                } else if (availableHeightBelowContent > mOverflowPanel.getMinimumHeight()) {
+                } else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) {
                     // There is enough space at the bottom of the content rect for the overflow.
                     // Position below and open downwards.
-                    updateOverflowHeight(availableHeightBelowContent);
+                    updateOverflowHeight(availableHeightBelowContent - margin);
                     y = contentRect.bottom;
                     mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
+                } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()
+                        && mViewPort.height() >= minimumOverflowHeightWithMargin) {
+                    // There is enough space at the bottom of the content rect for the main panel
+                    // but not the overflow.
+                    // Position below but open upwards.
+                    updateOverflowHeight(availableHeightThroughContentUp - margin);
+                    y = contentRect.bottom + getToolbarHeightWithVerticalMargin() - getHeight();
+                    mOverflowDirection = OVERFLOW_DIRECTION_UP;
                 } else {
                     // Not enough space.
-                    // Position at the bottom of the view port and open upwards.
-                    updateOverflowHeight(mViewPort.height());
-                    y = mViewPort.bottom - getHeight();
-                    mOverflowDirection = OVERFLOW_DIRECTION_UP;
+                    // Position at the top of the view port and open downwards.
+                    updateOverflowHeight(mViewPort.height() - margin);
+                    y = mViewPort.top;
+                    mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
                 }
                 mOverflowPanel.setOverflowDirection(mOverflowDirection);
             }
@@ -1422,7 +1437,6 @@
         PopupWindow popupWindow = new PopupWindow(popupContentHolder);
         popupWindow.setWindowLayoutType(
                 WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
-        popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
         popupWindow.setAnimationStyle(0);
         popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
         content.setLayoutParams(new ViewGroup.LayoutParams(
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7c2b28d..2c35a8b 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -876,16 +876,16 @@
                        "-Xzygote-max-boot-retry=");
 
     /*
-     * When running with debug.gencfi, add --include-cfi to the compiler options so that the boot
-     * image, if it is compiled on device, will include CFI info, as well as other compilations
-     * started by the runtime.
+     * When running with debug.generate-debug-info, add --generate-debug-info to
+     * the compiler options so that the boot image, if it is compiled on device,
+     * will include native debugging information.
      */
-    property_get("debug.gencfi", propBuf, "");
+    property_get("debug.generate-debug-info", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
         addOption("-Xcompiler-option");
-        addOption("--include-cfi");
+        addOption("--generate-debug-info");
         addOption("-Ximage-compiler-option");
-        addOption("--include-cfi");
+        addOption("--generate-debug-info");
     }
 
     initArgs.version = JNI_VERSION_1_4;
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 635fa11..0034b07 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -1240,8 +1240,11 @@
         return static_cast<jint>(PublicFormat::PRIVATE);
     } else {
         CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+        int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat(
+                static_cast<PublicFormat>(readerFormat));
+        int32_t fmt = applyFormatOverrides(buffer->flexFormat, readerHalFormat);
         PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat(
-                buffer->flexFormat, buffer->dataSpace);
+                fmt, buffer->dataSpace);
         return static_cast<jint>(publicFmt);
     }
 }
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7af8b80..869b03a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -578,4 +578,10 @@
 
     <!-- Padding between icon and text for managed profile toast -->
     <dimen name="managed_profile_toast_padding">4dp</dimen>
+
+    <!-- Thickness of the assist disclosure beams -->
+    <dimen name="assist_disclosure_thickness">4dp</dimen>
+
+    <!-- Thickness of the shadows of the assist disclosure beams -->
+    <dimen name="assist_disclosure_shadow_thickness">1.5dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
new file mode 100644
index 0000000..234a699
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
@@ -0,0 +1,251 @@
+/*
+ * 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 com.android.systemui.assist;
+
+import com.android.systemui.R;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.os.Handler;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
+
+/**
+ * Visually discloses that contextual data was provided to an assistant.
+ */
+public class AssistDisclosure {
+    private final Context mContext;
+    private final WindowManager mWm;
+    private final Handler mHandler;
+
+    private AssistDisclosureView mView;
+    private boolean mViewAdded;
+
+    public AssistDisclosure(Context context, Handler handler) {
+        mContext = context;
+        mHandler = handler;
+        mWm = mContext.getSystemService(WindowManager.class);
+    }
+
+    public void postShow() {
+        mHandler.removeCallbacks(mShowRunnable);
+        mHandler.post(mShowRunnable);
+    }
+
+    private void show() {
+        if (mView == null) {
+            mView = new AssistDisclosureView(mContext);
+        }
+        if (!mViewAdded) {
+            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                    WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                            | WindowManager.LayoutParams.FLAG_FULLSCREEN
+                            | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
+                    PixelFormat.TRANSLUCENT);
+            lp.setTitle("AssistDisclosure");
+
+            mWm.addView(mView, lp);
+            mViewAdded = true;
+        }
+    }
+
+    private void hide() {
+        if (mViewAdded) {
+            mWm.removeView(mView);
+            mViewAdded = false;
+        }
+    }
+
+    private Runnable mShowRunnable = new Runnable() {
+        @Override
+        public void run() {
+            show();
+        }
+    };
+
+    private class AssistDisclosureView extends View
+            implements ValueAnimator.AnimatorUpdateListener {
+
+        public static final int TRACING_ANIMATION_DURATION = 300;
+        public static final int ALPHA_ANIMATION_DURATION = 200;
+
+        private float mThickness;
+        private float mShadowThickness;
+        private final Paint mPaint = new Paint();
+        private final Paint mShadowPaint = new Paint();
+
+        private final ValueAnimator mTracingAnimator;
+        private final ValueAnimator mAlphaAnimator;
+        private final AnimatorSet mAnimator;
+
+        private float mTracingProgress = 0;
+        private int mAlpha = 255;
+
+        public AssistDisclosureView(Context context) {
+            super(context);
+
+            mTracingAnimator = ValueAnimator.ofFloat(0, 1).setDuration(TRACING_ANIMATION_DURATION);
+            mTracingAnimator.addUpdateListener(this);
+            mTracingAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
+                    android.R.interpolator.fast_out_slow_in));
+            mAlphaAnimator = ValueAnimator.ofInt(255, 0).setDuration(ALPHA_ANIMATION_DURATION);
+            mAlphaAnimator.addUpdateListener(this);
+            mAlphaAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext,
+                    android.R.interpolator.fast_out_linear_in));
+            mAnimator = new AnimatorSet();
+            mAnimator.play(mTracingAnimator).before(mAlphaAnimator);
+            mAnimator.addListener(new AnimatorListenerAdapter() {
+                boolean mCancelled;
+
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    mCancelled = false;
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mCancelled = true;
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (!mCancelled) {
+                        hide();
+                    }
+                }
+            });
+
+            PorterDuffXfermode srcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
+            mPaint.setColor(Color.WHITE);
+            mPaint.setXfermode(srcMode);
+            mShadowPaint.setColor(Color.DKGRAY);
+            mShadowPaint.setXfermode(srcMode);
+
+            mThickness = getResources().getDimension(R.dimen.assist_disclosure_thickness);
+            mShadowThickness = getResources().getDimension(
+                    R.dimen.assist_disclosure_shadow_thickness);
+        }
+
+        @Override
+        protected void onAttachedToWindow() {
+            super.onAttachedToWindow();
+
+            startAnimation();
+        }
+
+        @Override
+        protected void onDetachedFromWindow() {
+            super.onDetachedFromWindow();
+
+            mAnimator.cancel();
+
+            mTracingProgress = 0;
+            mAlpha = 255;
+        }
+
+        private void startAnimation() {
+            mAnimator.cancel();
+            mAnimator.start();
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            mPaint.setAlpha(mAlpha);
+            mShadowPaint.setAlpha(mAlpha / 4);
+
+            drawGeometry(canvas, mShadowPaint, mShadowThickness);
+            drawGeometry(canvas, mPaint, 0);
+        }
+
+        private void drawGeometry(Canvas canvas, Paint paint, float padding) {
+            final int width = getWidth();
+            final int height = getHeight();
+            float thickness = mThickness;
+            final float pixelProgress = mTracingProgress * (width + height - 2 * thickness);
+
+            float bottomProgress = Math.min(pixelProgress, width / 2f);
+            if (bottomProgress > 0) {
+                drawBeam(canvas,
+                        width / 2f - bottomProgress,
+                        height - thickness,
+                        width / 2f + bottomProgress,
+                        height, paint, padding);
+            }
+
+            float sideProgress = Math.min(pixelProgress - bottomProgress, height - thickness);
+            if (sideProgress > 0) {
+                drawBeam(canvas,
+                        0,
+                        (height - thickness) - sideProgress,
+                        thickness,
+                        height - thickness, paint, padding);
+                drawBeam(canvas,
+                        width - thickness,
+                        (height - thickness) - sideProgress,
+                        width,
+                        height - thickness, paint, padding);
+            }
+
+            float topProgress = Math.min(pixelProgress - bottomProgress - sideProgress,
+                    width / 2 - thickness);
+            if (sideProgress > 0 && topProgress > 0) {
+                drawBeam(canvas,
+                        thickness,
+                        0,
+                        thickness + topProgress,
+                        thickness, paint, padding);
+                drawBeam(canvas,
+                        (width - thickness) - topProgress,
+                        0,
+                        width - thickness,
+                        thickness, paint, padding);
+            }
+        }
+
+        private void drawBeam(Canvas canvas, float left, float top, float right, float bottom,
+                Paint paint, float padding) {
+            canvas.drawRect(left - padding,
+                    top - padding,
+                    right + padding,
+                    bottom + padding,
+                    paint);
+        }
+
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            if (animation == mAlphaAnimator) {
+                mAlpha = (int) mAlphaAnimator.getAnimatedValue();
+            } else if (animation == mTracingAnimator) {
+                mTracingProgress = (float) mTracingAnimator.getAnimatedValue();
+            }
+            invalidate();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 445ecb6..674356b 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -55,6 +55,8 @@
 
     private final Context mContext;
     private final WindowManager mWindowManager;
+    private final AssistDisclosure mAssistDisclosure;
+
     private AssistOrbContainer mView;
     private final PhoneStatusBar mBar;
     private final AssistUtils mAssistUtils;
@@ -100,6 +102,7 @@
                 Settings.Secure.getUriFor(Settings.Secure.ASSISTANT), false,
                 mAssistSettingsObserver);
         mAssistSettingsObserver.onChange(false);
+        mAssistDisclosure = new AssistDisclosure(context, new Handler());
     }
 
     public void onConfigurationChanged() {
@@ -187,8 +190,11 @@
         mBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL |
                 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL);
 
+        boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
+
         final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+                .getAssistIntent(mContext, structureEnabled, UserHandle.USER_CURRENT);
         if (intent == null) {
             return;
         }
@@ -196,6 +202,10 @@
             intent.setComponent(mAssistComponent);
         }
 
+        if (structureEnabled) {
+            showDisclosure();
+        }
+
         try {
             final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
                     R.anim.search_launch_enter, R.anim.search_launch_exit);
@@ -297,4 +307,8 @@
         pw.println("AssistManager state:");
         pw.print("  mAssistComponent="); pw.println(mAssistComponent);
     }
+
+    public void showDisclosure() {
+        mAssistDisclosure.postShow();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 9761cd1..4b1453d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -390,7 +390,7 @@
             mDetailSettingsButton.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {
-                    mHost.startSettingsActivity(settingsIntent);
+                    mHost.startActivityDismissingKeyguard(settingsIntent);
                 }
             });
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 72bb136..38fade2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -306,7 +306,7 @@
     }
 
     public interface Host {
-        void startSettingsActivity(Intent intent);
+        void startActivityDismissingKeyguard(Intent intent);
         void warn(String message, Throwable t);
         void collapsePanels();
         Looper getLooper();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index a9e8b38..07406b9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -82,7 +82,7 @@
         if (mDataController.isMobileDataSupported()) {
             showDetail(true);
         } else {
-            mHost.startSettingsActivity(CELLULAR_SETTINGS);
+            mHost.startActivityDismissingKeyguard(CELLULAR_SETTINGS);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index f97f519..1b74eb6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -263,7 +263,7 @@
     private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
         @Override
         public void onPrioritySettings() {
-            mHost.startSettingsActivity(ZEN_PRIORITY_SETTINGS);
+            mHost.startActivityDismissingKeyguard(ZEN_PRIORITY_SETTINGS);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index 19f4df6..f7f7acb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -96,7 +96,11 @@
     private void sendIntent(String type, PendingIntent pi, String uri) {
         try {
             if (pi != null) {
-                pi.send();
+                if (pi.isActivity()) {
+                    getHost().startActivityDismissingKeyguard(pi.getIntent());
+                } else {
+                    pi.send();
+                }
             } else if (uri != null) {
                 final Intent intent = Intent.parseUri(uri, Intent.URI_INTENT_SCHEME);
                 mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 9bc5b75..c33ef7c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -104,7 +104,7 @@
     @Override
     protected void handleSecondaryClick() {
         if (!mWifiController.canConfigWifi()) {
-            mHost.startSettingsActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+            mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_WIFI_SETTINGS));
             return;
         }
         if (!mState.enabled) {
@@ -290,7 +290,7 @@
 
         @Override
         public void onSettingsActivityTriggered(Intent settingsIntent) {
-            mHost.startSettingsActivity(settingsIntent);
+            mHost.startActivityDismissingKeyguard(settingsIntent);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f8a1385..295fdc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -2101,4 +2101,11 @@
         }
         return mStatusBarKeyguardViewManager.isSecure();
     }
+
+    @Override
+    public void showAssistDisclosure() {
+        if (mAssistManager != null) {
+            mAssistManager.showDisclosure();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 80fdd28..0deff08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -61,6 +61,7 @@
     private static final int MSG_APP_TRANSITION_PENDING     = 19 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_CANCELLED   = 20 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_STARTING    = 21 << MSG_SHIFT;
+    private static final int MSG_ASSIST_DISCLOSURE          = 22 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -104,6 +105,7 @@
         public void appTransitionPending();
         public void appTransitionCancelled();
         public void appTransitionStarting(long startTime, long duration);
+        public void showAssistDisclosure();
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -274,6 +276,13 @@
         }
     }
 
+    public void showAssistDisclosure() {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_ASSIST_DISCLOSURE);
+            mHandler.obtainMessage(MSG_ASSIST_DISCLOSURE).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -366,6 +375,9 @@
                     Pair<Long, Long> data = (Pair<Long, Long>) msg.obj;
                     mCallbacks.appTransitionStarting(data.first, data.second);
                     break;
+                case MSG_ASSIST_DISCLOSURE:
+                    mCallbacks.showAssistDisclosure();
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index cd90d27..ade40e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3101,16 +3101,16 @@
                 || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
-    public void postStartSettingsActivity(final Intent intent, int delay) {
+    public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
         mHandler.postDelayed(new Runnable() {
             @Override
             public void run() {
-                handleStartSettingsActivity(intent, true /*onlyProvisioned*/);
+                handleStartActivityDismissingKeyguard(intent, true /*onlyProvisioned*/);
             }
         }, delay);
     }
 
-    private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) {
+    private void handleStartActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned) {
         startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 25a93dd..12434ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -129,8 +129,8 @@
     }
 
     @Override
-    public void startSettingsActivity(final Intent intent) {
-        mStatusBar.postStartSettingsActivity(intent, 0);
+    public void startActivityDismissingKeyguard(final Intent intent) {
+        mStatusBar.postStartActivityDismissingKeyguard(intent, 0);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2a67248..1134556c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3264,9 +3264,9 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
                 }
             }
-            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
-            if ("true".equals(genCFIDebugProperty)) {
-                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
+            if ("true".equals(genDebugInfoProperty)) {
+                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
             }
             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index cd50946..4b36581 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2098,7 +2098,7 @@
                 }
 
                 final ApplicationInfo ai = pkg.pkg.applicationInfo;
-                final String dataPath = ai.dataDir;
+                final String dataPath = new File(ai.dataDir).getCanonicalPath();
                 final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
                 final int[] gids = pkg.getPermissionsState().computeGids(userIds);
 
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 58c3ea1..4692403 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -24,4 +24,5 @@
     void notificationLightPulse(int argb, int onMillis, int offMillis);
     void notificationLightOff();
     void showScreenPinningRequest();
+    void showAssistDisclosure();
 }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 5669f30..a754379 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -154,6 +154,16 @@
                 }
             }
         }
+
+        @Override
+        public void showAssistDisclosure() {
+            if (mBar != null) {
+                try {
+                    mBar.showAssistDisclosure();
+                } catch (RemoteException e) {
+                }
+            }
+        }
     };
 
     // ================================================================================
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index acd484d..af0ddbe 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -139,7 +139,7 @@
             IVoiceInteractionSessionShowCallback showCallback) {
         if (mActiveSession == null) {
             mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName,
-                    mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid);
+                    mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid, mHandler);
         }
         return mActiveSession.showLocked(args, flags, showCallback);
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 47a230a..cc6a9c5 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -32,6 +32,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -48,6 +49,8 @@
 import com.android.internal.app.IVoiceInteractionSessionShowCallback;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.os.IResultReceiver;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -63,6 +66,7 @@
     final Context mContext;
     final Callback mCallback;
     final int mCallingUid;
+    final Handler mHandler;
     final IActivityManager mAm;
     final IWindowManager mIWindowManager;
     final AppOpsManager mAppOps;
@@ -141,13 +145,14 @@
     };
 
     public VoiceInteractionSessionConnection(Object lock, ComponentName component, int user,
-            Context context, Callback callback, int callingUid) {
+            Context context, Callback callback, int callingUid, Handler handler) {
         mLock = lock;
         mSessionComponentName = component;
         mUser = user;
         mContext = context;
         mCallback = callback;
         mCallingUid = callingUid;
+        mHandler = handler;
         mAm = ActivityManagerNative.getDefault();
         mIWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
@@ -193,11 +198,13 @@
             mShowArgs = args;
             mShowFlags = flags;
             mHaveAssistData = false;
+            boolean needDisclosure = false;
             if ((flags& VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) {
                 if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid,
                         mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
                         && allDataEnabled) {
                     try {
+                        needDisclosure = true;
                         mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
                                 mAssistReceiver);
                     } catch (RemoteException e) {
@@ -215,6 +222,7 @@
                         mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
                         && allDataEnabled) {
                     try {
+                        needDisclosure = true;
                         mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
                     } catch (RemoteException e) {
                     }
@@ -225,6 +233,9 @@
             } else {
                 mScreenshot = null;
             }
+            if (needDisclosure) {
+                mHandler.post(mShowAssistDisclosureRunnable);
+            }
             if (mSession != null) {
                 try {
                     mSession.show(mShowArgs, mShowFlags, showCallback);
@@ -483,4 +494,15 @@
             pw.print(prefix); pw.print("mAssistData="); pw.println(mAssistData);
         }
     }
+
+    private Runnable mShowAssistDisclosureRunnable = new Runnable() {
+        @Override
+        public void run() {
+            StatusBarManagerInternal statusBarInternal = LocalServices.getService(
+                    StatusBarManagerInternal.class);
+            if (statusBarInternal != null) {
+                statusBarInternal.showAssistDisclosure();
+            }
+        }
+    };
 };