Merge "Refactor DisplayManagerService to be functional." into jb-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index bf33b79..cf2fb22 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5825,7 +5825,7 @@
     field public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
     field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
     field public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
-    field public static final java.lang.String EXTRA_ORIGINATING_URL = "android.intent.extra.ORIGINATING_URL";
+    field public static final java.lang.String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
     field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
     field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
     field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 4cb5270..4311c06 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -782,6 +782,7 @@
         String macAlgo = null;
         byte[] macKey = null;
         byte[] tag = null;
+        String referrer = null;
 
         while ((opt=nextOption()) != null) {
             if (opt.equals("-l")) {
@@ -845,6 +846,13 @@
                     showUsage();
                     return;
                 }
+            } else if (opt.equals("--referrer")) {
+                referrer = nextOptionData();
+                if (referrer == null) {
+                    System.err.println("Error: must supply argument for --referrer");
+                    showUsage();
+                    return;
+                }
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 showUsage();
@@ -892,6 +900,13 @@
 
         final Uri apkURI;
         final Uri verificationURI;
+        final Uri referrerURI;
+
+        if (referrer != null) {
+            referrerURI = Uri.parse(referrer);
+        } else {
+            referrerURI = null;
+        }
 
         // Populate apkURI, must be present
         final String apkFilePath = nextArg();
@@ -916,7 +931,7 @@
         PackageInstallObserver obs = new PackageInstallObserver();
         try {
             mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,
-                    verificationURI, null, encryptionParams);
+                    verificationURI, null, encryptionParams, apkURI, referrerURI);
 
             synchronized (obs) {
                 while (!obs.finished) {
@@ -1436,7 +1451,8 @@
         System.err.println("       pm list libraries");
         System.err.println("       pm path PACKAGE");
         System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
-        System.err.println("                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH");
+        System.err.println("                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
+        System.err.println("                  [--referrer <URI>] PATH");
         System.err.println("       pm uninstall [-k] PACKAGE");
         System.err.println("       pm clear PACKAGE");
         System.err.println("       pm enable PACKAGE_OR_COMPONENT");
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 9a50a41..9aa2505 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -972,12 +972,24 @@
     }
 
     @Override
+    public void installPackageWithOrigin(Uri packageURI, IPackageInstallObserver observer,
+            int flags, String installerPackageName, Uri originatingURI, Uri referrer) {
+        try {
+            mPM.installPackageWithOrigin(packageURI, observer, flags, null, originatingURI,
+                    referrer);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+    }
+
+    @Override
     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
-            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
+            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams,
+            Uri originatingURI, Uri referrer) {
         try {
             mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
-                    verificationURI, manifestDigest, encryptionParams);
+                    verificationURI, manifestDigest, encryptionParams, originatingURI, referrer);
         } catch (RemoteException e) {
             // Should never happen!
         }
diff --git a/core/java/android/app/MediaRouteActionProvider.java b/core/java/android/app/MediaRouteActionProvider.java
index 5b5506d..63b641c 100644
--- a/core/java/android/app/MediaRouteActionProvider.java
+++ b/core/java/android/app/MediaRouteActionProvider.java
@@ -81,6 +81,7 @@
         }
         mMenuItem = item;
         mView = new MediaRouteButton(mContext);
+        mView.setCheatSheetEnabled(true);
         mView.setRouteTypes(mRouteTypes);
         mView.setExtendedSettingsClickListener(mExtendedSettingsListener);
         mView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index b0bfe74..cfc8bbd 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -23,14 +23,19 @@
 import android.content.ContextWrapper;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.media.MediaRouter;
 import android.media.MediaRouter.RouteGroup;
 import android.media.MediaRouter.RouteInfo;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.Gravity;
+import android.view.HapticFeedbackConstants;
 import android.view.SoundEffectConstants;
 import android.view.View;
+import android.widget.Toast;
 
 public class MediaRouteButton extends View {
     private static final String TAG = "MediaRouteButton";
@@ -44,6 +49,7 @@
     private Drawable mRemoteIndicator;
     private boolean mRemoteActive;
     private boolean mToggleMode;
+    private boolean mCheatSheetEnabled;
 
     private int mMinWidth;
     private int mMinHeight;
@@ -82,6 +88,7 @@
         a.recycle();
 
         setClickable(true);
+        setLongClickable(true);
 
         setRouteTypes(routeTypes);
     }
@@ -129,6 +136,52 @@
         return handled;
     }
 
+    void setCheatSheetEnabled(boolean enable) {
+        mCheatSheetEnabled = enable;
+    }
+
+    @Override
+    public boolean performLongClick() {
+        if (super.performLongClick()) {
+            return true;
+        }
+
+        if (!mCheatSheetEnabled) {
+            return false;
+        }
+
+        final CharSequence contentDesc = getContentDescription();
+        if (TextUtils.isEmpty(contentDesc)) {
+            // Don't show the cheat sheet if we have no description
+            return false;
+        }
+
+        final int[] screenPos = new int[2];
+        final Rect displayFrame = new Rect();
+        getLocationOnScreen(screenPos);
+        getWindowVisibleDisplayFrame(displayFrame);
+
+        final Context context = getContext();
+        final int width = getWidth();
+        final int height = getHeight();
+        final int midy = screenPos[1] + height / 2;
+        final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
+
+        Toast cheatSheet = Toast.makeText(context, contentDesc, Toast.LENGTH_SHORT);
+        if (midy < displayFrame.height()) {
+            // Show along the top; follow action buttons
+            cheatSheet.setGravity(Gravity.TOP | Gravity.END,
+                    screenWidth - screenPos[0] - width / 2, height);
+        } else {
+            // Show along the bottom center
+            cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
+        }
+        cheatSheet.show();
+        performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+
+        return true;
+    }
+
     public void setRouteTypes(int types) {
         if (types == mRouteTypes) {
             // Already registered; nothing to do.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d325186..6d2de8e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -571,7 +571,7 @@
  *     <li> {@link #EXTRA_INITIAL_INTENTS}
  *     <li> {@link #EXTRA_INTENT}
  *     <li> {@link #EXTRA_KEY_EVENT}
- *     <li> {@link #EXTRA_ORIGINATING_URL}
+ *     <li> {@link #EXTRA_ORIGINATING_URI}
  *     <li> {@link #EXTRA_PHONE_NUMBER}
  *     <li> {@link #EXTRA_REFERRER}
  *     <li> {@link #EXTRA_REMOTE_INTENT_TOKEN}
@@ -1288,17 +1288,17 @@
             = "android.intent.extra.NOT_UNKNOWN_SOURCE";
 
     /**
-     * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
-     * {@link #ACTION_VIEW} to indicate the URL from which the local APK in the Intent
+     * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and
+     * {@link #ACTION_VIEW} to indicate the URI from which the local APK in the Intent
      * data field originated from.
      */
-    public static final String EXTRA_ORIGINATING_URL
-            = "android.intent.extra.ORIGINATING_URL";
+    public static final String EXTRA_ORIGINATING_URI
+            = "android.intent.extra.ORIGINATING_URI";
 
     /**
-     * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
-     * {@link #ACTION_VIEW} to indicate the HTTP referrer associated with the Intent
-     * data field or {@link #EXTRA_ORIGINATING_URL}.
+     * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and
+     * {@link #ACTION_VIEW} to indicate the HTTP referrer URI associated with the Intent
+     * data field or {@link #EXTRA_ORIGINATING_URI}.
      */
     public static final String EXTRA_REFERRER
             = "android.intent.extra.REFERRER";
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0d87df5..1b28a33 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -352,7 +352,7 @@
     String nextPackageToClean(String lastPackage);
 
     void movePackage(String packageName, IPackageMoveObserver observer, int flags);
-    
+
     boolean addPermissionAsync(in PermissionInfo info);
 
     boolean setInstallLocation(int loc);
@@ -363,9 +363,14 @@
     void setUserName(int userId, String name);
     ParcelFileDescriptor setUserIcon(int userId);
 
+    void installPackageWithOrigin(in Uri packageURI, in IPackageInstallObserver observer,
+            int flags, in String installerPackageName, in Uri originatingURI,
+            in Uri referrer);
+
     void installPackageWithVerification(in Uri packageURI, in IPackageInstallObserver observer,
             int flags, in String installerPackageName, in Uri verificationURI,
-            in ManifestDigest manifestDigest, in ContainerEncryptionParams encryptionParams);
+            in ManifestDigest manifestDigest, in ContainerEncryptionParams encryptionParams,
+            in Uri originatingURI, in Uri referrer);
 
     void verifyPendingInstall(int id, int verificationCode);
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index cd7ef0e..f745c89 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2196,6 +2196,33 @@
     /**
      * Similar to
      * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
+     * with references to the location of where the package originated from.
+     *
+     * @param packageURI The location of the package file to install. This can
+     *            be a 'file:' or a 'content:' URI.
+     * @param observer An observer callback to get notified when the package
+     *            installation is complete.
+     *            {@link IPackageInstallObserver#packageInstalled(String, int)}
+     *            will be called when that happens. observer may be null to
+     *            indicate that no callback is desired.
+     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+     *            {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}
+     * @param installerPackageName Optional package name of the application that
+     *            is performing the installation. This identifies which market
+     *            the package came from.
+     * @param originatingURI URI referencing where the package was downloaded
+     *            from. May be {@code null}.
+     * @param referrer HTTP referrer URI associated with the originatingURI.
+     *            May be {@code null}.
+     * @hide
+     */
+    public abstract void installPackageWithOrigin(
+            Uri packageURI, IPackageInstallObserver observer, int flags,
+            String installerPackageName, Uri originatingURI, Uri referrer);
+
+    /**
+     * Similar to
+     * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
      * with an extra verification file provided.
      *
      * @param packageURI The location of the package file to install. This can
@@ -2219,12 +2246,17 @@
      * @param encryptionParams if the package to be installed is encrypted,
      *            these parameters describing the encryption and authentication
      *            used. May be {@code null}.
+     * @param originatingURI URI referencing where the package was downloaded
+     *            from. May be {@code null}.
+     * @param referrer HTTP referrer URI associated with the originatingURI.
+     *            May be {@code null}.
      * @hide
      */
     public abstract void installPackageWithVerification(Uri packageURI,
             IPackageInstallObserver observer, int flags, String installerPackageName,
             Uri verificationURI, ManifestDigest manifestDigest,
-            ContainerEncryptionParams encryptionParams);
+            ContainerEncryptionParams encryptionParams, Uri originatingURI,
+            Uri referrer);
 
     /**
      * Allows a package listening to the
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index bef6db9..5b8764b 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -278,7 +278,6 @@
             super.setComposingText(limitedText, newCursorPosition);
             updateSelection();
             if (limitedText != text) {
-                restartInput();
                 int lastCaret = start + limitedText.length();
                 finishComposingText();
                 setSelection(lastCaret, lastCaret);
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a39d98d..b757fe8 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3606,4 +3606,8 @@
 
     <!-- "Done" button for MediaRouter chooser dialog when grouping routes. [CHAR LIMIT=NONE] -->
     <string name="media_route_chooser_grouping_done">Done</string>
+
+    <!-- Content description of a MediaRouteButton for accessibility support -->
+    <string name="media_route_button_content_description">Media output</string>
+
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index c490a2f..a6236f7 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2448,6 +2448,8 @@
         <item name="android:externalRouteEnabledDrawable">@drawable/ic_media_route_holo_dark</item>
         <item name="android:minWidth">56dp</item>
         <item name="android:minHeight">48dp</item>
+        <item name="android:focusable">true</item>
+        <item name="android:contentDescription">@android:string/media_route_button_content_description</item>
     </style>
 
     <style name="Widget.Holo.Light.MediaRouteButton">
@@ -2455,6 +2457,8 @@
         <item name="android:externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
         <item name="android:minWidth">56dp</item>
         <item name="android:minHeight">48dp</item>
+        <item name="android:focusable">true</item>
+        <item name="android:contentDescription">@android:string/media_route_button_content_description</item>
     </style>
 
 </resources>
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 5cd5ff5..0d7b45e 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1463,24 +1463,42 @@
     }
 
     FileEntry makeEntryFor(String path) {
-        String key = path;
         String where;
         String[] selectionArgs;
-        if (mCaseInsensitivePaths) {
-            // the 'like' makes it use the index, the 'lower()' makes it correct
-            // when the path contains sqlite wildcard characters
-            where = "_data LIKE ?1 AND lower(_data)=lower(?1)";
-            selectionArgs = new String[] { path };
-        } else {
-            where = Files.FileColumns.DATA + "=?";
-            selectionArgs = new String[] { path };
-        }
 
         Cursor c = null;
         try {
+            boolean hasWildCards = path.contains("_") || path.contains("%");
+
+            if (hasWildCards || !mCaseInsensitivePaths) {
+                // if there are wildcard characters in the path, the "like" match
+                // will be slow, and it's worth trying an "=" comparison
+                // first, since in most cases the case will match.
+                // Also, we shouldn't do a "like" match on case-sensitive filesystems
+                where = Files.FileColumns.DATA + "=?";
+                selectionArgs = new String[] { path };
+            } else {
+                // if there are no wildcard characters in the path, then the "like"
+                // match will be just as fast as the "=" case, because of the index
+                where = "_data LIKE ?1 AND lower(_data)=lower(?1)";
+                selectionArgs = new String[] { path };
+            }
             c = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
                     where, selectionArgs, null, null);
-            if (c.moveToNext()) {
+            if (!c.moveToFirst() && hasWildCards && mCaseInsensitivePaths) {
+                // Try again with case-insensitive match. This will be slower, especially
+                // if the path contains wildcard characters.
+                // The 'like' makes it use the index, the 'lower()' makes it correct
+                // when the path contains sqlite wildcard characters,
+                where = "_data LIKE ?1 AND lower(_data)=lower(?1)";
+                selectionArgs = new String[] { path };
+                c.close();
+                c = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
+                        where, selectionArgs, null, null);
+                // TODO update the path in the db with the correct case so the fast
+                // path works next time?
+            }
+            if (c.moveToFirst()) {
                 long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX);
                 int format = c.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX);
                 long lastModified = c.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX);
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index eed8e77..6fc79c5 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -152,5 +152,5 @@
     <dimen name="carrier_label_height">24dp</dimen>
 
     <!-- The distance you can pull a notificaiton before it pops open -->
-    <dimen name="one_finger_pop_limit">96dp</dimen>
+    <dimen name="one_finger_pop_limit">32dp</dimen>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 10dcd9e..6aa7dcd 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -38,7 +38,6 @@
     public interface Callback {
         View getChildAtRawPosition(float x, float y);
         View getChildAtPosition(float x, float y);
-        View getPreviousChild(View currentChild);
         boolean canChildBeExpanded(View v);
         boolean setUserExpandedChild(View v, boolean userxpanded);
     }
@@ -142,17 +141,6 @@
         }
     }
 
-    class PopState {
-        View mCurrView;
-        View mCurrViewTopGlow;
-        View mCurrViewBottomGlow;
-        float mOldHeight;
-        float mNaturalHeight;
-        float mInitialTouchY;
-    }
-
-    private Stack<PopState> popStack;
-
     /**
      * Handle expansion gestures to expand and contract children of the callback.
      *
@@ -168,7 +156,6 @@
         mLargeSize = large;
         mContext = context;
         mCallback = callback;
-        popStack = new Stack<PopState>();
         mScaler = new ViewScaler();
         mGravity = Gravity.TOP;
         mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
@@ -416,45 +403,40 @@
         switch (action) {
             case MotionEvent.ACTION_MOVE: {
                 if (mPullingWithOneFinger) {
-                    float target = ev.getY() - mInitialTouchY + mOldHeight;
-                    float newHeight = clamp(target);
-                    if (mHasPopped || target > mPopLimit) {
+                    final float rawHeight = ev.getY() - mInitialTouchY + mOldHeight;
+                    final float newHeight = clamp(rawHeight);
+                    final boolean wasClosed = (mOldHeight == mSmallSize);
+                    boolean isFinished = false;
+                    if (rawHeight > mNaturalHeight) {
+                        isFinished = true;
+                    }
+                    if (rawHeight < mSmallSize) {
+                        isFinished = true;
+                    }
+
+                    final float pull = Math.abs(ev.getY() - mInitialTouchY);
+                    if (mHasPopped || pull > mPopLimit) {
                         if (!mHasPopped) {
                             vibrate(mPopDuration);
                             mHasPopped = true;
                         }
+                    }
+
+                    if (mHasPopped) {
                         mScaler.setHeight(newHeight);
-                        // glow if overscale
-                        if (target > mNaturalHeight) {
-                            View previous = mCallback.getPreviousChild(mCurrView);
-                            if (previous != null) {
-                                setGlow(0f);
-                                pushView(previous);
-                                initScale(previous);
-                                mInitialTouchY = ev.getY();
-                                target = mOldHeight;
-                                newHeight = clamp(target);
-                                mHasPopped = false;
-                            } else {
-                                setGlow(calculateGlow(target, newHeight));
-                            }
-                        } else if (target < mSmallSize && !popStack.empty()) {
-                            setGlow(0f);
-                            initScale(popView());
-                            mInitialTouchY = ev.getY();
-                            setGlow(GLOW_BASE);
-                        } else {
-                            setGlow(calculateGlow(target, newHeight));
-                        }
+                        setGlow(GLOW_BASE);
                     } else {
-                         if (target < mSmallSize && !popStack.empty()) {
-                            setGlow(0f);
-                            initScale(popView());
-                            mInitialTouchY = ev.getY();
-                            setGlow(GLOW_BASE);
-                         } else {
-                             setGlow(calculateGlow(4f * target, mSmallSize));
-                         }
+                        setGlow(calculateGlow(4f * pull, 0f));
+                    }
+
+                    final int x = (int) ev.getX();
+                    final int y = (int) ev.getY();
+                    View underPointer = findView(x, y);
+                    if (isFinished && underPointer != null && underPointer != mCurrView) {
+                        setGlow(0f);
+                        initScale(underPointer);
+                        mInitialTouchY = ev.getY();
+                        mHasPopped = false;
                     }
                     return true;
                 }
@@ -516,9 +498,6 @@
     }
 
     private void clearView() {
-        while (!popStack.empty()) {
-            popStack.pop();
-        }
         mCurrView = null;
         mCurrViewTopGlow = null;
         mCurrViewBottomGlow = null;
@@ -539,33 +518,6 @@
         }
     }
 
-    private void pushView(View v) {
-        PopState state = new PopState();
-        state.mCurrView = mCurrView;
-        state.mCurrViewTopGlow = mCurrViewTopGlow;
-        state.mCurrViewBottomGlow = mCurrViewBottomGlow;
-        state.mOldHeight = mOldHeight;
-        state.mNaturalHeight = mNaturalHeight;
-        state.mInitialTouchY = mInitialTouchY;
-        popStack.push(state);
-    }
-
-    private View popView() {
-        if (popStack.empty()) {
-            return null;
-        }
-
-        PopState state = popStack.pop();
-        mCurrView = state.mCurrView;
-        mCurrViewTopGlow = state.mCurrViewTopGlow;
-        mCurrViewBottomGlow = state.mCurrViewBottomGlow;
-        mOldHeight = state.mOldHeight;
-        mNaturalHeight = state.mNaturalHeight;
-        mInitialTouchY = state.mInitialTouchY;
-
-        return mCurrView;
-    }
-
     @Override
     public void onClick(View v) {
         initScale(v);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index a10b6c6..61e5ab6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -204,20 +204,6 @@
         return null;
     }
 
-    public View getPreviousChild(View currentChild) {
-        final int count = getChildCount();
-        for (int childIdx = 0; childIdx < count; childIdx++) {
-            if (getChildAt(childIdx) == currentChild) {
-                if (childIdx == 0) {
-                    return null;
-                } else {
-                    return getChildAt(childIdx - 1);
-                }
-            }
-        }
-        return null;
-    }
-
     public View getChildContentView(View v) {
         return v;
     }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 180081b..cbc3c51 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -5335,13 +5335,21 @@
             final Uri packageURI, final IPackageInstallObserver observer, final int flags,
             final String installerPackageName) {
         installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
-                null, null);
+                null, null, null, null);
+    }
+
+    public void installPackageWithOrigin(
+            Uri packageURI, IPackageInstallObserver observer, int flags,
+            String installerPackageName, Uri originatingURI, Uri referrer) {
+        installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
+                null, null, originatingURI, referrer);
     }
 
     @Override
     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
-            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
+            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams,
+            Uri originatingURI, Uri referrer) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
 
         final int uid = Binder.getCallingUid();
@@ -5359,7 +5367,7 @@
 
         final Message msg = mHandler.obtainMessage(INIT_COPY);
         msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
-                verificationURI, manifestDigest, encryptionParams);
+                verificationURI, manifestDigest, encryptionParams, originatingURI, referrer);
         mHandler.sendMessage(msg);
     }
 
@@ -5795,11 +5803,13 @@
         private int mRet;
         private File mTempPackage;
         final ContainerEncryptionParams encryptionParams;
+        final Uri originatingURI;
+        final Uri referrer;
 
         InstallParams(Uri packageURI,
                 IPackageInstallObserver observer, int flags,
                 String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest,
-                ContainerEncryptionParams encryptionParams) {
+                ContainerEncryptionParams encryptionParams, Uri originatingURI, Uri referrer) {
             this.mPackageURI = packageURI;
             this.flags = flags;
             this.observer = observer;
@@ -5807,6 +5817,8 @@
             this.verificationURI = verificationURI;
             this.manifestDigest = manifestDigest;
             this.encryptionParams = encryptionParams;
+            this.originatingURI = originatingURI;
+            this.referrer = referrer;
         }
 
         private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
@@ -6002,6 +6014,14 @@
                                 verificationURI);
                     }
 
+                    if (originatingURI != null) {
+                        verification.putExtra(Intent.EXTRA_ORIGINATING_URI, originatingURI);
+                    }
+
+                    if (referrer != null) {
+                        verification.putExtra(Intent.EXTRA_REFERRER, referrer);
+                    }
+
                     final PackageVerificationState verificationState = new PackageVerificationState(
                             requiredUid, args);
 
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 0399b3b..b1224d3 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -563,7 +563,17 @@
     @Override
     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
-            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
+            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams,
+            Uri originatingURI, Uri referrer) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void installPackageWithOrigin(Uri packageURI, IPackageInstallObserver observer,
+            int flags, String installerPackageName, Uri originatingURI, Uri referrer) {
         throw new UnsupportedOperationException();
     }