merge in klp-release history after reset to klp-dev
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index af605de..555d843 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -686,21 +686,6 @@
       ALOGE("flush called on Significant Motion sensor");
       return INVALID_OPERATION;
   }
-  SensorDevice& dev(SensorDevice::getInstance());
-
-  if (dev.getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
-      // For older devices increment pending flush count, which will send a trivial flush complete
-      // event for all the connections which are registered for updates on this sensor.
-      const SortedVector< wp<SensorEventConnection> > activeConnections(
-                                      getActiveConnections());
-      for (size_t i=0 ; i<activeConnections.size() ; i++) {
-          sp<SensorEventConnection> connection(activeConnections[i].promote());
-          if (connection != 0) {
-              connection->incrementPendingFlushCount(handle);
-          }
-      }
-      return NO_ERROR;
-  }
   return sensor->flush(connection.get(), handle);
 }
 // ---------------------------------------------------------------------------
@@ -805,15 +790,6 @@
     }
 }
 
-void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
-    Mutex::Autolock _l(mConnectionLock);
-    ssize_t index = mSensorInfo.indexOfKey(handle);
-    if (index >= 0) {
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
-        flushInfo.mPendingFlushEventsToSend++;
-    }
-}
-
 status_t SensorService::SensorEventConnection::sendEvents(
         sensors_event_t const* buffer, size_t numEvents,
         sensors_event_t* scratch)
@@ -872,7 +848,7 @@
                 ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
                 if (size < 0) {
                     // ALOGW("dropping %d events on the floor", count);
-                    countFlushCompleteEvents(scratch, count);
+                    countFlushCompleteEventsLocked(scratch, count);
                     return size;
                 }
                 ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
@@ -889,17 +865,17 @@
         // the destination doesn't accept events anymore, it's probably
         // full. For now, we just drop the events on the floor.
         // ALOGW("dropping %d events on the floor", count);
-        countFlushCompleteEvents(scratch, count);
+        Mutex::Autolock _l(mConnectionLock);
+        countFlushCompleteEventsLocked(scratch, count);
         return size;
     }
 
     return size < 0 ? status_t(size) : status_t(NO_ERROR);
 }
 
-void SensorService::SensorEventConnection::countFlushCompleteEvents(
+void SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
                 sensors_event_t* scratch, const int numEventsDropped) {
     ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
-    Mutex::Autolock _l(mConnectionLock);
     // Count flushComplete events in the events that are about to the dropped. These will be sent
     // separately before the next batch of events.
     for (int j = 0; j < numEventsDropped; ++j) {
@@ -939,15 +915,25 @@
 }
 
 status_t  SensorService::SensorEventConnection::flush() {
+    SensorDevice& dev(SensorDevice::getInstance());
+    const int halVersion = dev.getHalDeviceVersion();
     Mutex::Autolock _l(mConnectionLock);
     status_t err(NO_ERROR);
+    // Loop through all sensors for this connection and call flush on each of them.
     for (size_t i = 0; i < mSensorInfo.size(); ++i) {
         const int handle = mSensorInfo.keyAt(i);
-        status_t err_flush = mService->flushSensor(this, handle);
-        if (err_flush != NO_ERROR) {
-            ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_1) {
+            // For older devices just increment pending flush count which will send a trivial
+            // flush complete event.
+            FlushInfo& flushInfo = mSensorInfo.editValueFor(handle);
+            flushInfo.mPendingFlushEventsToSend++;
+        } else {
+            status_t err_flush = mService->flushSensor(this, handle);
+            if (err_flush != NO_ERROR) {
+                ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
+            }
+            err = (err_flush != NO_ERROR) ? err_flush : err;
         }
-        err = (err_flush != NO_ERROR) ? err_flush : err;
     }
     return err;
 }
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 2d40071..6c1691a 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -83,7 +83,7 @@
         // Count the number of flush complete events which are about to be dropped in the buffer.
         // Increment mPendingFlushEventsToSend in mSensorInfo. These flush complete events will be
         // sent separately before the next batch of events.
-        void countFlushCompleteEvents(sensors_event_t* scratch, int numEventsDropped);
+        void countFlushCompleteEventsLocked(sensors_event_t* scratch, int numEventsDropped);
 
         sp<SensorService> const mService;
         sp<BitTube> mChannel;
@@ -112,7 +112,6 @@
         bool addSensor(int32_t handle);
         bool removeSensor(int32_t handle);
         void setFirstFlushPending(int32_t handle, bool value);
-        void incrementPendingFlushCount(int32_t handle);
         void dump(String8& result);
 
         uid_t getUid() const { return mUid; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4a1373e..bc8cfb8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -147,6 +147,7 @@
         mLastTransactionTime(0),
         mBootFinished(false),
         mPrimaryHWVsyncEnabled(false),
+        mHWVsyncAvailable(false),
         mDaltonize(false)
 {
     ALOGI("SurfaceFlinger is starting");
@@ -752,16 +753,23 @@
 
 void SurfaceFlinger::enableHardwareVsync() {
     Mutex::Autolock _l(mHWVsyncLock);
-    if (!mPrimaryHWVsyncEnabled) {
+    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
         mPrimaryDispSync.beginResync();
         eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
         mPrimaryHWVsyncEnabled = true;
     }
 }
 
-void SurfaceFlinger::resyncToHardwareVsync() {
+void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
     Mutex::Autolock _l(mHWVsyncLock);
 
+    if (makeAvailable) {
+        mHWVsyncAvailable = true;
+    } else if (!mHWVsyncAvailable) {
+        ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
+        return;
+    }
+
     const nsecs_t period =
             getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
 
@@ -775,13 +783,16 @@
     }
 }
 
-void SurfaceFlinger::disableHardwareVsync() {
+void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
     Mutex::Autolock _l(mHWVsyncLock);
     if (mPrimaryHWVsyncEnabled) {
         eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, false);
         mPrimaryDispSync.endResync();
         mPrimaryHWVsyncEnabled = false;
     }
+    if (makeUnavailable) {
+        mHWVsyncAvailable = false;
+    }
 }
 
 void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
@@ -791,7 +802,7 @@
         if (needsHwVsync) {
             enableHardwareVsync();
         } else {
-            disableHardwareVsync();
+            disableHardwareVsync(false);
         }
     }
 }
@@ -933,7 +944,7 @@
         if (mPrimaryDispSync.addPresentFence(presentFence)) {
             enableHardwareVsync();
         } else {
-            disableHardwareVsync();
+            disableHardwareVsync(false);
         }
     }
 
@@ -2178,7 +2189,7 @@
             // FIXME: eventthread only knows about the main display right now
             mEventThread->onScreenAcquired();
 
-            resyncToHardwareVsync();
+            resyncToHardwareVsync(true);
         }
     }
     mVisibleRegionsDirty = true;
@@ -2196,6 +2207,8 @@
     int32_t type = hw->getDisplayType();
     if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
         if (type == DisplayDevice::DISPLAY_PRIMARY) {
+            disableHardwareVsync(true); // also cancels any in-progress resync
+
             // FIXME: eventthread only knows about the main display right now
             mEventThread->onScreenReleased();
         }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f1c19c2..353e7ba 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -383,8 +383,8 @@
      * VSync
      */
      void enableHardwareVsync();
-     void disableHardwareVsync();
-     void resyncToHardwareVsync();
+     void disableHardwareVsync(bool makeUnavailable);
+     void resyncToHardwareVsync(bool makeAvailable);
 
     /* ------------------------------------------------------------------------
      * Debugging & dumpsys
@@ -467,6 +467,7 @@
     // protected by mHWVsyncLock
     Mutex mHWVsyncLock;
     bool mPrimaryHWVsyncEnabled;
+    bool mHWVsyncAvailable;
 
     /* ------------------------------------------------------------------------
      * Feature prototyping