Merge "Change to new binder implementation for OBB" into gingerbread
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index ef7716e..1fd31a3 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -77,6 +77,7 @@
     public final static int FLAG_VIRTUAL = 0x00000100;
 
     public final static int FLAG_INJECTED = 0x01000000;
+    public final static int FLAG_TRUSTED = 0x02000000;
 
     public final static int FLAG_WOKE_HERE = 0x10000000;
     public final static int FLAG_BRIGHT_HERE = 0x20000000;
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 340e23c..c3cbf07 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -148,6 +148,9 @@
     <!-- Flag indicating whether the we should enable the automatic brightness in Settings.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
+
+    <!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
+    <bool name="config_unplugTurnsOnScreen">false</bool>
     
     <!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
 
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 66061fd..8c6018b 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -95,6 +95,10 @@
     // Indicates that the input event was injected.
     POLICY_FLAG_INJECTED = 0x01000000,
 
+    // Indicates that the input event is from a trusted source such as a directly attached
+    // input device or an application with system-wide event injection permission.
+    POLICY_FLAG_TRUSTED = 0x02000000,
+
     /* These flags are set by the input reader policy as it intercepts each event. */
 
     // Indicates that the screen was off when the event was received and the event
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index 0834e86..3599163 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -913,7 +913,6 @@
     void drainInboundQueueLocked();
     void releasePendingEventLocked();
     void releaseInboundEventLocked(EventEntry* entry);
-    bool isEventFromTrustedSourceLocked(EventEntry* entry);
 
     // Dispatch state.
     bool mDispatchEnabled;
@@ -960,10 +959,10 @@
             nsecs_t currentTime, ConfigurationChangedEntry* entry);
     bool dispatchKeyLocked(
             nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
-            bool dropEvent, nsecs_t* nextWakeupTime);
+            DropReason* dropReason, nsecs_t* nextWakeupTime);
     bool dispatchMotionLocked(
             nsecs_t currentTime, MotionEntry* entry,
-            bool dropEvent, nsecs_t* nextWakeupTime);
+            DropReason* dropReason, nsecs_t* nextWakeupTime);
     void dispatchEventToCurrentInputTargetsLocked(
             nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
 
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 58c2cdf..41b6ff3 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -370,7 +370,7 @@
             }
         }
         done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
-                dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
+                &dropReason, nextWakeupTime);
         break;
     }
 
@@ -380,7 +380,7 @@
             dropReason = DROP_REASON_APP_SWITCH;
         }
         done = dispatchMotionLocked(currentTime, typedEntry,
-                dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
+                &dropReason, nextWakeupTime);
         break;
     }
 
@@ -431,6 +431,9 @@
     const char* reason;
     switch (dropReason) {
     case DROP_REASON_POLICY:
+#if DEBUG_INBOUND_EVENT_DETAILS
+        LOGD("Dropped event because policy requested that it not be delivered to the application.");
+#endif
         reason = "inbound event was dropped because the policy requested that it not be "
                 "delivered to the application";
         break;
@@ -473,7 +476,7 @@
 bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
     return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
             && isAppSwitchKeyCode(keyEntry->keyCode)
-            && isEventFromTrustedSourceLocked(keyEntry)
+            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
             && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
 }
 
@@ -541,12 +544,6 @@
     mAllocator.releaseEventEntry(entry);
 }
 
-bool InputDispatcher::isEventFromTrustedSourceLocked(EventEntry* entry) {
-    InjectionState* injectionState = entry->injectionState;
-    return ! injectionState
-            || hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid);
-}
-
 void InputDispatcher::resetKeyRepeatLocked() {
     if (mKeyRepeatState.lastKeyEntry) {
         mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
@@ -559,7 +556,8 @@
     KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
 
     // Reuse the repeated key entry if it is otherwise unreferenced.
-    uint32_t policyFlags = entry->policyFlags & (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER);
+    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
+            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
     if (entry->refCount == 1) {
         mAllocator.recycleKeyEntry(entry);
         entry->eventTime = currentTime;
@@ -608,19 +606,13 @@
 
 bool InputDispatcher::dispatchKeyLocked(
         nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
-        bool dropEvent, nsecs_t* nextWakeupTime) {
+        DropReason* dropReason, nsecs_t* nextWakeupTime) {
     // Give the policy a chance to intercept the key.
     if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
-        bool trusted;
-        if (! dropEvent && mFocusedWindow) {
-            trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
-        } else {
-            trusted = isEventFromTrustedSourceLocked(entry);
-        }
-        if (trusted) {
+        if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
             CommandEntry* commandEntry = postCommandLocked(
                     & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
-            if (! dropEvent && mFocusedWindow) {
+            if (mFocusedWindow) {
                 commandEntry->inputChannel = mFocusedWindow->inputChannel;
             }
             commandEntry->keyEntry = entry;
@@ -630,13 +622,16 @@
             entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
         }
     } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
+        if (*dropReason == DROP_REASON_NOT_DROPPED) {
+            *dropReason = DROP_REASON_POLICY;
+        }
         resetTargetsLocked();
         setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
         return true;
     }
 
     // Clean up if dropping the event.
-    if (dropEvent) {
+    if (*dropReason != DROP_REASON_NOT_DROPPED) {
         resetTargetsLocked();
         setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
         return true;
@@ -648,7 +643,8 @@
 
         if (entry->repeatCount == 0
                 && entry->action == AKEY_EVENT_ACTION_DOWN
-                && ! entry->isInjected()) {
+                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
+                && !entry->isInjected()) {
             if (mKeyRepeatState.lastKeyEntry
                     && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
                 // We have seen two identical key downs in a row which indicates that the device
@@ -713,9 +709,9 @@
 }
 
 bool InputDispatcher::dispatchMotionLocked(
-        nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
+        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
     // Clean up if dropping the event.
-    if (dropEvent) {
+    if (*dropReason != DROP_REASON_NOT_DROPPED) {
         resetTargetsLocked();
         setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
         return true;
@@ -2085,6 +2081,7 @@
         return;
     }
 
+    policyFlags |= POLICY_FLAG_TRUSTED;
     mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
             keyCode, scanCode, /*byref*/ policyFlags);
 
@@ -2130,6 +2127,7 @@
         return;
     }
 
+    policyFlags |= POLICY_FLAG_TRUSTED;
     mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
 
     bool needWake;
@@ -2263,6 +2261,7 @@
             switchCode, switchValue, policyFlags);
 #endif
 
+    policyFlags |= POLICY_FLAG_TRUSTED;
     mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
 }
 
@@ -2275,7 +2274,11 @@
 #endif
 
     nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
-    bool trusted = hasInjectionPermission(injectorPid, injectorUid);
+
+    uint32_t policyFlags = POLICY_FLAG_INJECTED;
+    if (hasInjectionPermission(injectorPid, injectorUid)) {
+        policyFlags |= POLICY_FLAG_TRUSTED;
+    }
 
     EventEntry* injectedEntry;
     switch (event->getType()) {
@@ -2291,11 +2294,8 @@
         int32_t flags = keyEvent->getFlags();
         int32_t keyCode = keyEvent->getKeyCode();
         int32_t scanCode = keyEvent->getScanCode();
-        uint32_t policyFlags = POLICY_FLAG_INJECTED;
-        if (trusted) {
-            mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
-                    keyCode, scanCode, /*byref*/ policyFlags);
-        }
+        mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
+                keyCode, scanCode, /*byref*/ policyFlags);
 
         mLock.lock();
         injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
@@ -2314,10 +2314,7 @@
         }
 
         nsecs_t eventTime = motionEvent->getEventTime();
-        uint32_t policyFlags = POLICY_FLAG_INJECTED;
-        if (trusted) {
-            mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
-        }
+        mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
 
         mLock.lock();
         const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
index f3da2a3..b1c6ad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -294,6 +294,7 @@
         mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
         mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);
 
+        mExpandedView.setVisibility(View.GONE);
         mOngoingTitle.setVisibility(View.GONE);
         mLatestTitle.setVisibility(View.GONE);
 
@@ -335,7 +336,7 @@
                 PixelFormat.RGBX_8888);
         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
         lp.setTitle("StatusBar");
-        // TODO lp.windowAnimations = R.style.Animation_StatusBar;
+        lp.windowAnimations = com.android.internal.R.style.Animation_StatusBar;
 
         WindowManagerImpl.getDefault().addView(view, lp);
     }
@@ -691,6 +692,7 @@
         mExpandedDialog.getWindow().setAttributes(mExpandedParams);
         mExpandedView.requestFocus(View.FOCUS_FORWARD);
         mTrackingView.setVisibility(View.VISIBLE);
+        mExpandedView.setVisibility(View.VISIBLE);
 
         if (!mTicking) {
             setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
@@ -767,6 +769,7 @@
         mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         mExpandedDialog.getWindow().setAttributes(mExpandedParams);
         mTrackingView.setVisibility(View.GONE);
+        mExpandedView.setVisibility(View.GONE);
 
         if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
             setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
@@ -1323,29 +1326,26 @@
             mExpandedContents.getLocationInWindow(mPositionTmp);
             final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
 
-            mExpandedParams.y = pos + mTrackingView.getHeight()
-                    - (mTrackingParams.height-closePos) - contentsBottom;
-            int max = h;
-            if (mExpandedParams.y > max) {
-                mExpandedParams.y = max;
-            }
-            int min = mTrackingPosition;
-            if (mExpandedParams.y < min) {
-                mExpandedParams.y = min;
-            }
-
-            boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h;
-            if (!visible) {
-                // if the contents aren't visible, move the expanded view way off screen
-                // because the window itself extends below the content view.
-                mExpandedParams.y = -disph;
-            }
-            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
-
-            // As long as this isn't just a repositioning that's not supposed to affect
-            // the user's perception of what's showing, call to say that the visibility
-            // has changed. (Otherwise, someone else will call to do that).
             if (expandedPosition != EXPANDED_LEAVE_ALONE) {
+                mExpandedParams.y = pos + mTrackingView.getHeight()
+                        - (mTrackingParams.height-closePos) - contentsBottom;
+                int max = h;
+                if (mExpandedParams.y > max) {
+                    mExpandedParams.y = max;
+                }
+                int min = mTrackingPosition;
+                if (mExpandedParams.y < min) {
+                    mExpandedParams.y = min;
+                }
+
+                boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h;
+                if (!visible) {
+                    // if the contents aren't visible, move the expanded view way off screen
+                    // because the window itself extends below the content view.
+                    mExpandedParams.y = -disph;
+                }
+                mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+
                 if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")");
                 visibilityChanged(visible);
             }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index f21d357..d9bceec 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1057,6 +1057,10 @@
     @Override
     public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
             int keyCode, int metaState, int repeatCount, int policyFlags) {
+        if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
+            return false;
+        }
+
         final boolean keyguardOn = keyguardOn();
         final boolean down = (action == KeyEvent.ACTION_DOWN);
         final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
@@ -1083,7 +1087,7 @@
                 if (!down) {
                     mHomePressed = false;
                     
-                    if (! canceled) {
+                    if (!canceled) {
                         // If an incoming call is ringing, HOME is totally disabled.
                         // (The user is already on the InCallScreen at this point,
                         // and his ONLY options are to answer or reject the call.)
@@ -1735,7 +1739,14 @@
     public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
             int policyFlags, boolean isScreenOn) {
         int result = ACTION_PASS_TO_USER;
-        
+        if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
+            return result;
+        }
+
+        if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
+            performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
+        }
+
         final boolean isWakeKey = (policyFlags
                 & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
         
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index aa87f29..50b3abe 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -84,7 +84,7 @@
 
 class BackupManagerService extends IBackupManager.Stub {
     private static final String TAG = "BackupManagerService";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
 
     // How often we perform a backup pass.  Privileged external callers can
     // trigger an immediate pass.
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index ed1243a..df41264 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -359,11 +359,6 @@
         private static final String CALIBRATION_DIR_PATH = "usr/idc/";
         
         @SuppressWarnings("unused")
-        public void virtualKeyDownFeedback() {
-            mWindowManagerService.mInputMonitor.virtualKeyDownFeedback();
-        }
-        
-        @SuppressWarnings("unused")
         public void notifyConfigurationChanged(long whenNanos) {
             mWindowManagerService.sendNewConfiguration();
         }
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 37b4c1d..bc802a8 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -186,9 +186,11 @@
     static final int SCAN_UPDATE_TIME = 1<<6;
 
     static final int REMOVE_CHATTY = 1<<16;
-    
+
+    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
+
     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
-            "com.android.defcontainer",
+            DEFAULT_CONTAINER_PACKAGE,
             "com.android.defcontainer.DefaultContainerService");
 
     private static final String LIB_DIR_NAME = "lib";
@@ -4774,7 +4776,15 @@
                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
             } else {
                 // Remote call to find out default install location
-                PackageInfoLite pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags);
+                final PackageInfoLite pkgLite;
+                try {
+                    mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
+                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                    pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags);
+                } finally {
+                    mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                }
+
                 int loc = pkgLite.recommendedInstallLocation;
                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){
                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
@@ -4989,8 +4999,14 @@
             libraryPath = new File(dataDir, LIB_DIR_NAME).getPath();
         }
 
-        boolean  checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
-            return imcs.checkFreeStorage(false, packageURI);
+        boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
+            try {
+                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                return imcs.checkFreeStorage(false, packageURI);
+            } finally {
+                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            }
         }
 
         String getCodePath() {
@@ -5034,11 +5050,14 @@
             // Copy the resource now
             int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
             try {
+                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
                 if (imcs.copyResource(packageURI, out)) {
                     ret = PackageManager.INSTALL_SUCCEEDED;
                 }
             } finally {
                 try { if (out != null) out.close(); } catch (IOException e) {}
+                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
             }
 
             return ret;
@@ -5209,17 +5228,31 @@
             cid = getTempContainerId();
         }
 
-        boolean  checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
-            return imcs.checkFreeStorage(true, packageURI);
+        boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
+            try {
+                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                return imcs.checkFreeStorage(true, packageURI);
+            } finally {
+                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            }
         }
 
         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
             if (temp) {
                 createCopyFile();
             }
-            String newCachePath = imcs.copyResourceToContainer(
-                    packageURI, cid,
-                    getEncryptKey(), RES_FILE_NAME);
+
+            final String newCachePath;
+            try {
+                mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                newCachePath = imcs.copyResourceToContainer(packageURI, cid,
+                        getEncryptKey(), RES_FILE_NAME);
+            } finally {
+                mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            }
+
             if (newCachePath != null) {
                 setCachePath(newCachePath);
                 return PackageManager.INSTALL_SUCCEEDED;
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 496c665..88a4c90 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -245,6 +245,9 @@
     private int[] mButtonBacklightValues;
     private int[] mKeyboardBacklightValues;
     private int mLightSensorWarmupTime;
+    boolean mUnplugTurnsOnScreen;
+    private int mWarningSpewThrottleCount;
+    private long mWarningSpewThrottleTime;
 
     // Used when logging number and duration of touch-down cycles
     private long mTotalTouchDownTime;
@@ -364,8 +367,12 @@
                     // user activity when screen was already on.
                     // temporarily set mUserActivityAllowed to true so this will work
                     // even when the keyguard is on.
+                    // However, you can also set config_unplugTurnsOnScreen to have it
+                    // turn on.  Some devices want this because they don't have a
+                    // charging LED.
                     synchronized (mLocks) {
-                        if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0) {
+                        if (!wasPowered || (mPowerState & SCREEN_ON_BIT) != 0 ||
+                                mUnplugTurnsOnScreen) {
                             forceUserActivityLocked();
                         }
                     }
@@ -524,6 +531,9 @@
 
         Resources resources = mContext.getResources();
 
+        mUnplugTurnsOnScreen = resources.getBoolean(
+                com.android.internal.R.bool.config_unplugTurnsOnScreen);
+
         // read settings for auto-brightness
         mUseSoftwareAutoBrightness = resources.getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
@@ -2095,6 +2105,21 @@
         return (mScreenBrightness.animating && mScreenBrightness.targetValue == 0);
     }
 
+    private boolean shouldLog(long time) {
+        synchronized (mLocks) {
+            if (time > (mWarningSpewThrottleTime + (60*60*1000))) {
+                mWarningSpewThrottleTime = time;
+                mWarningSpewThrottleCount = 0;
+                return true;
+            } else if (mWarningSpewThrottleCount < 30) {
+                mWarningSpewThrottleCount++;
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
     private void forceUserActivityLocked() {
         if (isScreenTurningOffLocked()) {
             // cancel animation so userActivity will succeed
@@ -2112,7 +2137,15 @@
     }
 
     public void userActivity(long time, boolean noChangeLights) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
+                != PackageManager.PERMISSION_GRANTED) {
+            if (shouldLog(time)) {
+                Slog.w(TAG, "Caller does not have DEVICE_POWER permission.  pid="
+                        + Binder.getCallingPid() + " uid=" + Binder.getCallingUid());
+            }
+            return;
+        }
+
         userActivity(time, -1, noChangeLights, OTHER_EVENT, false);
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a7785e2..26071ae 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -578,6 +578,10 @@
     static Timer timer;
     static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr
 
+    // The earliest supported time.  We pick one day into 1970, to
+    // give any timezone code room without going into negative time.
+    private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
+
     /**
      * This method is called from Zygote to initialize the system. This will cause the native
      * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
@@ -586,14 +590,14 @@
     native public static void init1(String[] args);
 
     public static void main(String[] args) {
-        if (System.currentTimeMillis() < 0) {
+        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
             // If a device's clock is before 1970 (before 0), a lot of
             // APIs crash dealing with negative numbers, notably
             // java.io.File#setLastModified, so instead we fake it and
             // hope that time from cell towers or NTP fixes it
             // shortly.
             Slog.w(TAG, "System clock is before 1970; setting to 1970.");
-            SystemClock.setCurrentTimeMillis(1);  // 0 isn't allowed
+            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
         }
 
         if (SamplingProfilerIntegration.isEnabled()) {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 0de57ab..42fffb0 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -5243,13 +5243,6 @@
             mTempInputWindows.clear();
         }
         
-        /* Provides feedback for a virtual key down. */
-        public void virtualKeyDownFeedback() {
-            synchronized (mWindowMap) {
-                mPolicy.performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
-            }
-        }
-        
         /* Notifies that the lid switch changed state. */
         public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
             mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 18037e4..a0b0aba 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -50,7 +50,6 @@
     jmethodID notifyLidSwitchChanged;
     jmethodID notifyInputChannelBroken;
     jmethodID notifyANR;
-    jmethodID virtualKeyDownFeedback;
     jmethodID interceptKeyBeforeQueueing;
     jmethodID interceptKeyBeforeDispatching;
     jmethodID checkInjectEventsPermission;
@@ -192,6 +191,8 @@
 
     /* --- InputDispatcherPolicyInterface implementation --- */
 
+    virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+            uint32_t policyFlags);
     virtual void notifyConfigurationChanged(nsecs_t when);
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
             const sp<InputChannel>& inputChannel);
@@ -205,8 +206,6 @@
     virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
     virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
             const KeyEvent* keyEvent, uint32_t policyFlags);
-    virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
-            uint32_t policyFlags);
     virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
     virtual bool checkInjectEventsPermissionNonReentrant(
             int32_t injectorPid, int32_t injectorUid);
@@ -255,7 +254,6 @@
 
     static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
 
-    static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
     static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
 
     static inline JNIEnv* jniEnv() {
@@ -291,37 +289,6 @@
     dump.append("\n");
 }
 
-bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
-    // Special keys that the WindowManagerPolicy might care about.
-    switch (keyCode) {
-    case AKEYCODE_VOLUME_UP:
-    case AKEYCODE_VOLUME_DOWN:
-    case AKEYCODE_ENDCALL:
-    case AKEYCODE_POWER:
-    case AKEYCODE_CALL:
-    case AKEYCODE_HOME:
-    case AKEYCODE_MENU:
-    case AKEYCODE_SEARCH:
-        // media keys
-    case AKEYCODE_HEADSETHOOK:
-    case AKEYCODE_MEDIA_PLAY_PAUSE:
-    case AKEYCODE_MEDIA_STOP:
-    case AKEYCODE_MEDIA_NEXT:
-    case AKEYCODE_MEDIA_PREVIOUS:
-    case AKEYCODE_MEDIA_REWIND:
-    case AKEYCODE_MEDIA_FAST_FORWARD:
-        // The policy always cares about these keys.
-        return true;
-    default:
-        // We need to pass all keys to the policy in the following cases:
-        // - screen is off
-        // - keyguard is visible
-        // - policy is performing key chording
-        //return ! isScreenOn || keyguardVisible || chording;
-        return true; // XXX stubbed out for now
-    }
-}
-
 bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
     if (env->ExceptionCheck()) {
         LOGE("An exception was thrown by callback '%s'.", methodName);
@@ -454,115 +421,6 @@
     return result;
 }
 
-bool NativeInputManager::isScreenOn() {
-    return android_server_PowerManagerService_isScreenOn();
-}
-
-bool NativeInputManager::isScreenBright() {
-    return android_server_PowerManagerService_isScreenBright();
-}
-
-void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
-        int32_t deviceId, int32_t action, int32_t &flags,
-        int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-    LOGD("interceptKeyBeforeQueueing - when=%lld, deviceId=%d, action=%d, flags=%d, "
-            "keyCode=%d, scanCode=%d, policyFlags=0x%x",
-            when, deviceId, action, flags, keyCode, scanCode, policyFlags);
-#endif
-
-    bool down = action == AKEY_EVENT_ACTION_DOWN;
-    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
-        policyFlags |= POLICY_FLAG_VIRTUAL;
-        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
-
-        if (down) {
-            JNIEnv* env = jniEnv();
-            env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
-            checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
-        }
-    }
-
-    const int32_t WM_ACTION_PASS_TO_USER = 1;
-    const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
-    const int32_t WM_ACTION_GO_TO_SLEEP = 4;
-
-    bool isScreenOn = this->isScreenOn();
-    bool isScreenBright = this->isScreenBright();
-
-    jint wmActions = 0;
-    if (isPolicyKey(keyCode, isScreenOn)) {
-        JNIEnv* env = jniEnv();
-
-        wmActions = env->CallIntMethod(mCallbacksObj,
-                gCallbacksClassInfo.interceptKeyBeforeQueueing,
-                when, keyCode, down, policyFlags, isScreenOn);
-        if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
-            wmActions = 0;
-        }
-    } else {
-        wmActions = WM_ACTION_PASS_TO_USER;
-    }
-
-    if (! isScreenOn) {
-        // Key presses and releases wake the device.
-        policyFlags |= POLICY_FLAG_WOKE_HERE;
-        flags |= AKEY_EVENT_FLAG_WOKE_HERE;
-    }
-
-    if (! isScreenBright) {
-        // Key presses and releases brighten the screen if dimmed.
-        policyFlags |= POLICY_FLAG_BRIGHT_HERE;
-    }
-
-    if (wmActions & WM_ACTION_GO_TO_SLEEP) {
-        android_server_PowerManagerService_goToSleep(when);
-    }
-
-    if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
-        android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
-    }
-
-    if (wmActions & WM_ACTION_PASS_TO_USER) {
-        policyFlags |= POLICY_FLAG_PASS_TO_USER;
-    }
-}
-
-void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-    LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
-#endif
-
-    if (isScreenOn()) {
-        // Only dispatch events when the device is awake.
-        // Do not wake the device.
-        policyFlags |= POLICY_FLAG_PASS_TO_USER;
-
-        if (! isScreenBright()) {
-            // Brighten the screen if dimmed.
-            policyFlags |= POLICY_FLAG_BRIGHT_HERE;
-        }
-    }
-}
-
-void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
-        int32_t switchValue, uint32_t policyFlags) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-    LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
-            when, switchCode, switchValue, policyFlags);
-#endif
-
-    JNIEnv* env = jniEnv();
-
-    switch (switchCode) {
-    case SW_LID:
-        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
-                when, switchValue == 0);
-        checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
-        break;
-    }
-}
-
 bool NativeInputManager::filterTouchEvents() {
     if (mFilterTouchEvents < 0) {
         JNIEnv* env = jniEnv();
@@ -692,6 +550,24 @@
     }
 }
 
+void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
+        int32_t switchValue, uint32_t policyFlags) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+    LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
+            when, switchCode, switchValue, policyFlags);
+#endif
+
+    JNIEnv* env = jniEnv();
+
+    switch (switchCode) {
+    case SW_LID:
+        env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
+                when, switchValue == 0);
+        checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
+        break;
+    }
+}
+
 void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
     LOGD("notifyConfigurationChanged - when=%lld", when);
@@ -944,13 +820,88 @@
     mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
 }
 
-bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
-        const KeyEvent* keyEvent, uint32_t policyFlags) {
-    bool isScreenOn = this->isScreenOn();
-    if (! isPolicyKey(keyEvent->getKeyCode(), isScreenOn)) {
-        return false;
+bool NativeInputManager::isScreenOn() {
+    return android_server_PowerManagerService_isScreenOn();
+}
+
+bool NativeInputManager::isScreenBright() {
+    return android_server_PowerManagerService_isScreenBright();
+}
+
+void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
+        int32_t deviceId, int32_t action, int32_t &flags,
+        int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+    LOGD("interceptKeyBeforeQueueing - when=%lld, deviceId=%d, action=%d, flags=%d, "
+            "keyCode=%d, scanCode=%d, policyFlags=0x%x",
+            when, deviceId, action, flags, keyCode, scanCode, policyFlags);
+#endif
+
+    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
+        policyFlags |= POLICY_FLAG_VIRTUAL;
+        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
     }
 
+    const int32_t WM_ACTION_PASS_TO_USER = 1;
+    const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
+    const int32_t WM_ACTION_GO_TO_SLEEP = 4;
+
+    bool isScreenOn = this->isScreenOn();
+    bool isScreenBright = this->isScreenBright();
+
+    JNIEnv* env = jniEnv();
+    jint wmActions = env->CallIntMethod(mCallbacksObj,
+            gCallbacksClassInfo.interceptKeyBeforeQueueing,
+            when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
+    if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
+        wmActions = 0;
+    }
+
+    if (policyFlags & POLICY_FLAG_TRUSTED) {
+        if (! isScreenOn) {
+            // Key presses and releases wake the device.
+            policyFlags |= POLICY_FLAG_WOKE_HERE;
+            flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+        }
+
+        if (! isScreenBright) {
+            // Key presses and releases brighten the screen if dimmed.
+            policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+        }
+
+        if (wmActions & WM_ACTION_GO_TO_SLEEP) {
+            android_server_PowerManagerService_goToSleep(when);
+        }
+
+        if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
+            android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
+        }
+    }
+
+    if (wmActions & WM_ACTION_PASS_TO_USER) {
+        policyFlags |= POLICY_FLAG_PASS_TO_USER;
+    }
+}
+
+void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+    LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
+#endif
+
+    if (isScreenOn()) {
+        // Only dispatch events when the device is awake.
+        // Do not wake the device.
+        policyFlags |= POLICY_FLAG_PASS_TO_USER;
+
+        if ((policyFlags & POLICY_FLAG_TRUSTED) && !isScreenBright()) {
+            // Brighten the screen if dimmed.
+            policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+        }
+    }
+}
+
+bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
+        const KeyEvent* keyEvent, uint32_t policyFlags) {
     JNIEnv* env = jniEnv();
 
     // Note: inputChannel may be null.
@@ -1365,9 +1316,6 @@
     GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
             "notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
 
-    GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
-            "virtualKeyDownFeedback", "()V");
-
     GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
             "interceptKeyBeforeQueueing", "(JIZIZ)I");
 
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 758b408..069b85a 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -444,11 +444,11 @@
     }
     if (transform & HAL_TRANSFORM_FLIP_V) {
         swap(vLT, vLB);
-        swap(vRB, vRT);
+        swap(vRT, vRB);
     }
     if (transform & HAL_TRANSFORM_FLIP_H) {
-        swap(vLT, vRB);
-        swap(vLB, vRT);
+        swap(vLT, vRT);
+        swap(vLB, vRB);
     }
 
     TexCoords texCoords[4];
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index 4fb1e61..aebe1b8 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -72,14 +72,6 @@
             nsecs_t now = systemTime();
             nsecs_t nextEventTime = -1;
 
-            // invalidate messages are always handled first
-            if (mInvalidate) {
-                mInvalidate = false;
-                mInvalidateMessage->when = now;
-                result = mInvalidateMessage;
-                break;
-            }
-
             LIST::iterator cur(mMessages.begin());
             if (cur != mMessages.end()) {
                 result = *cur;
@@ -95,6 +87,14 @@
                 result = 0;
             }
 
+            // see if we have an invalidate message
+            if (mInvalidate) {
+                mInvalidate = false;
+                mInvalidateMessage->when = now;
+                result = mInvalidateMessage;
+                break;
+            }
+
             if (timeout >= 0) {
                 if (timeoutTime < now) {
                     // we timed-out, return a NULL message