From 88d11cfbfcde32d3212600d4e96a0c04b556c4d0 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 16 Oct 2009 16:17:58 -0700 Subject: [PATCH 01/10] one step towards fixing [2071412] work around mdp 32-bits fade limitation simplify the GL_MODULATE case and allow blending disabled with RGBA texture --- opengl/libagl/copybit.cpp | 85 ++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 867459d648813..73b2355aa8ecb 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -41,11 +41,12 @@ namespace android { static void textureToCopyBitImage( - const GGLSurface* surface, buffer_handle_t buffer, copybit_image_t* img) + const GGLSurface* surface, int32_t opFormat, + buffer_handle_t buffer, copybit_image_t* img) { img->w = surface->stride; img->h = surface->height; - img->format = surface->format; + img->format = opFormat; img->base = surface->data; img->handle = (native_handle_t *)buffer; } @@ -207,39 +208,13 @@ static bool copybit(GLint x, GLint y, int planeAlpha = 255; static const int tmu = 0; texture_t& tev(c->rasterizer.state.texture[tmu]); - bool srcTextureHasAlpha = hasAlpha(textureObject->surface.format); + int32_t opFormat = textureObject->surface.format; + const bool srcTextureHasAlpha = hasAlpha(opFormat); if (!srcTextureHasAlpha) { planeAlpha = fixedToByte(c->currentColorClamped.a); } - switch (tev.env) { - case GGL_REPLACE: - break; - case GGL_MODULATE: - if (! (c->currentColorClamped.r == FIXED_ONE && - c->currentColorClamped.g == FIXED_ONE && - c->currentColorClamped.b == FIXED_ONE)) { - LOGD_IF(DEBUG_COPYBIT, - "MODULATE and non white color (%08x, %08x, %08x)", - c->currentColorClamped.r, - c->currentColorClamped.g, - c->currentColorClamped.b); - return false; - } - if (srcTextureHasAlpha && c->currentColorClamped.a < FIXED_ONE) { - LOGD_IF(DEBUG_COPYBIT, - "MODULATE and texture w/alpha and alpha=%08x)", - c->currentColorClamped.a); - return false; - } - break; - - default: - // Incompatible texture environment. - LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment"); - return false; - } - + const bool cbHasAlpha = hasAlpha(cbSurface.format); bool blending = false; if ((enables & GGL_ENABLE_BLENDING) && !(c->rasterizer.state.blend.src == GL_ONE @@ -262,32 +237,60 @@ static bool copybit(GLint x, GLint y, } blending = true; } else { - // No blending is OK if we are not using alpha. - if (srcTextureHasAlpha || planeAlpha != 255) { - // Incompatible alpha - LOGD_IF(DEBUG_COPYBIT, "incompatible alpha"); - return false; + if (cbHasAlpha) { + // NOTE: the result will be slightly wrong in this case because + // the destination alpha channel will be set to 1.0 instead of + // the iterated alpha value. *shrug*. + } + // disable plane blending and src blending for supported formats + planeAlpha = 255; + if (opFormat == COPYBIT_FORMAT_RGBA_8888) { + opFormat = COPYBIT_FORMAT_RGBX_8888; + } else { + if (srcTextureHasAlpha) { + LOGD_IF(DEBUG_COPYBIT, "texture format requires blending"); + return false; + } } } - if (srcTextureHasAlpha && planeAlpha != 255) { - // Can't do two types of alpha at once. - LOGD_IF(DEBUG_COPYBIT, "src alpha and plane alpha"); + switch (tev.env) { + case GGL_REPLACE: + break; + case GGL_MODULATE: + // only cases allowed is: + // RGB source, color={1,1,1,a} -> can be done with GL_REPLACE + // RGBA source, color={1,1,1,1} -> can be done with GL_REPLACE + if (blending) { + if (c->currentColorClamped.r == c->currentColorClamped.a && + c->currentColorClamped.g == c->currentColorClamped.a && + c->currentColorClamped.b == c->currentColorClamped.a) { + // TODO: Need to emulate: RGBA source, color={a,a,a,a} / premult + // and RGBA source, color={1,1,1,a} / regular-blending + // (both are equivalent) + } + } + LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE"); + return false; + default: + // Incompatible texture environment. + LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment"); return false; } + // LOGW("calling copybits"); copybit_device_t* copybit = c->copybits.blitEngine; copybit_image_t dst; buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer; - textureToCopyBitImage(&cbSurface, target_hnd, &dst); + textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; copybit_image_t src; buffer_handle_t source_hnd = textureObject->buffer->handle; - textureToCopyBitImage(&textureObject->surface, source_hnd, &src); + textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src); copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); From 007a429f09fb9e4e4fbd4205d03878874c9f7957 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 19 Oct 2009 12:42:28 -0700 Subject: [PATCH 02/10] Update 5.xml with last minute changes. Change-Id: I520ca879d31cb4581556138a73b542c070de3c00 --- api/5.xml | 1142 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1142 insertions(+) diff --git a/api/5.xml b/api/5.xml index ca2cceb52a7f1..614804708a48a 100644 --- a/api/5.xml +++ b/api/5.xml @@ -112806,6 +112806,58 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Mon, 19 Oct 2009 12:42:28 -0700 Subject: [PATCH 03/10] Update 5.xml with last minute changes. --- api/5.xml | 1142 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1142 insertions(+) diff --git a/api/5.xml b/api/5.xml index ca2cceb52a7f1..614804708a48a 100644 --- a/api/5.xml +++ b/api/5.xml @@ -112806,6 +112806,58 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Fri, 16 Oct 2009 18:34:31 -0700 Subject: [PATCH 04/10] fix [2151588] glTexSubImage2D() allows pixel format conversion --- opengl/libagl/texture.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 90e6d2946a722..13d078e2a3d86 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -1252,6 +1252,11 @@ void glTexSubImage2D( ogles_error(c, GL_INVALID_OPERATION); return; } + + if (format != tex->internalformat) { + ogles_error(c, GL_INVALID_OPERATION); + return; + } if ((xoffset + width > GLsizei(surface.width)) || (yoffset + height > GLsizei(surface.height))) { ogles_error(c, GL_INVALID_VALUE); From 0953c1d5e1c295c84fa02237bf70c779e45c83ae Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 19 Oct 2009 14:46:27 -0700 Subject: [PATCH 05/10] fix [2153873] EGL-1.4 software implementation misses surface attributes --- opengl/libagl/egl.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 37628b7ea0d7d..d04900e870541 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -953,12 +953,17 @@ static config_pair_t const config_base_attribute_list[] = { { EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE }, { EGL_MIN_SWAP_INTERVAL, 1 }, { EGL_MAX_SWAP_INTERVAL, 1 }, + { EGL_LUMINANCE_SIZE, 0 }, + { EGL_ALPHA_MASK_SIZE, 0 }, + { EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER }, { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT }, + { EGL_CONFORMANT, 0 } }; // These configs can override the base attribute list // NOTE: when adding a config here, don't forget to update eglCreate*Surface() + static config_pair_t const config_0_attribute_list[] = { { EGL_BUFFER_SIZE, 16 }, { EGL_ALPHA_SIZE, 0 }, @@ -1062,10 +1067,18 @@ static config_management_t const gConfigManagement[] = { { EGL_BIND_TO_TEXTURE_RGB, config_management_t::exact }, { EGL_MIN_SWAP_INTERVAL, config_management_t::exact }, { EGL_MAX_SWAP_INTERVAL, config_management_t::exact }, + { EGL_LUMINANCE_SIZE, config_management_t::atLeast }, + { EGL_ALPHA_MASK_SIZE, config_management_t::atLeast }, + { EGL_COLOR_BUFFER_TYPE, config_management_t::exact }, + { EGL_RENDERABLE_TYPE, config_management_t::mask }, + { EGL_CONFORMANT, config_management_t::mask } }; + static config_pair_t const config_defaults[] = { - { EGL_SURFACE_TYPE, EGL_WINDOW_BIT }, + // attributes that are not specified are simply ignored, if a particular + // one needs not be ignored, it must be specified here, eg: + // { EGL_SURFACE_TYPE, EGL_WINDOW_BIT }, }; // ---------------------------------------------------------------------------- @@ -1513,7 +1526,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, numAttributes++; EGLint attr = *attrib_list++; EGLint val = *attrib_list++; - for (int i=0 ; i( (config_pair_t const*)attrib_list, 0, numAttributes-1, config_defaults[j].key) < 0) { - for (int i=0 ; i Date: Thu, 8 Oct 2009 18:28:01 -0700 Subject: [PATCH 06/10] Proper fix for zero signal strength and no_service. Fixes #2176141 Track phone service state changes and use a separate timer for out-of-service since the hunting can timeout on some devices. Store the timeout value in the config.xml, as it is device/network specific. Settings App will also change to use the hunting duration to compute the cost of zero signal. --- core/java/android/os/BatteryStats.java | 20 +++- .../android/internal/app/IBatteryStats.aidl | 2 +- .../android/internal/os/BatteryStatsImpl.java | 100 ++++++++++++++---- .../com/android/internal/os/PowerProfile.java | 5 + core/res/res/values/config.xml | 4 + core/res/res/xml/power_profile.xml | 4 +- .../com/android/server/TelephonyRegistry.java | 2 +- .../server/am/BatteryStatsService.java | 7 +- 8 files changed, 117 insertions(+), 27 deletions(-) diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index a49a27a06368b..b706c5c1cae40 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -130,6 +130,7 @@ public abstract class BatteryStats implements Parcelable { private static final String MISC_DATA = "m"; private static final String SCREEN_BRIGHTNESS_DATA = "br"; private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt"; + private static final String SIGNAL_SCANNING_TIME_DATA = "sst"; private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc"; private static final String DATA_CONNECTION_TIME_DATA = "dct"; private static final String DATA_CONNECTION_COUNT_DATA = "dcc"; @@ -439,6 +440,15 @@ public abstract class BatteryStats implements Parcelable { public abstract long getPhoneSignalStrengthTime(int strengthBin, long batteryRealtime, int which); + /** + * Returns the time in microseconds that the phone has been trying to + * acquire a signal. + * + * {@hide} + */ + public abstract long getPhoneSignalScanningTime( + long batteryRealtime, int which); + /** * Returns the number of times the phone has entered the given signal strength. * @@ -823,6 +833,8 @@ public abstract class BatteryStats implements Parcelable { args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000; } dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args); + dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA, + getPhoneSignalScanningTime(batteryRealtime, which) / 1000); for (int i=0; i timerPool, ArrayList unpluggables, Parcel in) { super(type, unpluggables, in); @@ -694,6 +701,10 @@ public final class BatteryStatsImpl extends BatteryStats { mTimerPool = timerPool; } + void setTimeout(long timeout) { + mTimeout = timeout; + } + public void writeToParcel(Parcel out, long batteryRealtime) { super.writeToParcel(out, batteryRealtime); out.writeLong(mUpdateTime); @@ -797,6 +808,9 @@ public final class BatteryStatsImpl extends BatteryStats { @Override protected long computeRunTimeLocked(long curBatteryRealtime) { + if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { + curBatteryRealtime = mUpdateTime + mTimeout; + } return mTotalTime + (mNesting > 0 ? (curBatteryRealtime - mUpdateTime) / (mTimerPool != null ? mTimerPool.size() : 1) @@ -1123,34 +1137,59 @@ public final class BatteryStatsImpl extends BatteryStats { } } - public void noteAirplaneModeLocked(boolean isAirplaneMode) { - final int bin = mPhoneSignalStrengthBin; - if (bin >= 0) { - if (!isAirplaneMode) { - if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) { - mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); - } - } else { - for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) { - while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { - mPhoneSignalStrengthsTimer[i].stopRunningLocked(this); - } + /** + * Telephony stack updates the phone state. + * @param state phone state from ServiceState.getState() + */ + public void notePhoneStateLocked(int state) { + int bin = mPhoneSignalStrengthBin; + boolean isAirplaneMode = state == ServiceState.STATE_POWER_OFF; + // Stop all timers + if (isAirplaneMode || state == ServiceState.STATE_OUT_OF_SERVICE) { + for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) { + while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { + mPhoneSignalStrengthsTimer[i].stopRunningLocked(this); } } } + // Stop Signal Scanning timer, in case we're going into service + while (mPhoneSignalScanningTimer.isRunningLocked()) { + mPhoneSignalScanningTimer.stopRunningLocked(this); + } + + // If we're back in service or continuing in service, restart the old timer. + if (state == ServiceState.STATE_IN_SERVICE) { + if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) { + mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); + } + } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { + mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) { + mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this); + } + if (!mPhoneSignalScanningTimer.isRunningLocked()) { + mPhoneSignalScanningTimer.startRunningLocked(this); + } + } + mPhoneServiceState = state; } public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { // Bin the strength. int bin; - + if (mPhoneServiceState == ServiceState.STATE_POWER_OFF + || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) { + // Ignore any signal strength changes when radio was turned off or out of service. + return; + } if (!signalStrength.isGsm()) { int dBm = signalStrength.getCdmaDbm(); - if (dBm >= -75) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; - else if (dBm >= -85) bin = SIGNAL_STRENGTH_GREAT; - else if (dBm >= -95) bin = SIGNAL_STRENGTH_GOOD; - else if (dBm >= -100) bin = SIGNAL_STRENGTH_MODERATE; - else bin = SIGNAL_STRENGTH_POOR; + if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT; + else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD; + else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE; + else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR; + else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } else { int asu = signalStrength.getGsmSignalStrength(); if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; @@ -1328,7 +1367,13 @@ public final class BatteryStatsImpl extends BatteryStats { return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( batteryRealtime, which); } - + + @Override public long getPhoneSignalScanningTime( + long batteryRealtime, int which) { + return mPhoneSignalScanningTimer.getTotalTimeLocked( + batteryRealtime, which); + } + @Override public int getPhoneSignalStrengthCount(int dataType, int which) { return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); } @@ -2653,6 +2698,7 @@ public final class BatteryStatsImpl extends BatteryStats { for (int i=0; i 400 + + 0 + diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml index 710b71ea7e75c..ce623e8d4d359 100644 --- a/core/res/res/xml/power_profile.xml +++ b/core/res/res/xml/power_profile.xml @@ -29,10 +29,12 @@ 0.1 0.1 1 + + 0.5 1 - 1 + 0.2 0.1 false + + + + + + + + + + + + + + + + diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index 99e008cef4392..a63d3fc81691c 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.res.Resources; import android.database.Cursor; import android.hardware.Sensor; import android.hardware.SensorEvent; @@ -89,6 +90,9 @@ class PowerManagerService extends IPowerManager.Stub private static final int LONG_KEYLIGHT_DELAY = 6000; // t+6 sec private static final int LONG_DIM_TIME = 7000; // t+N-5 sec + // How long to wait to debounce light sensor changes. + private static final int LIGHT_SENSOR_DELAY = 1000; + // trigger proximity if distance is less than 5 cm private static final float PROXIMITY_THRESHOLD = 5.0f; @@ -193,6 +197,8 @@ class PowerManagerService extends IPowerManager.Stub private Sensor mLightSensor; private boolean mLightSensorEnabled; private float mLightSensorValue = -1; + private float mLightSensorPendingValue = -1; + private int mLightSensorBrightness = -1; private boolean mDimScreen = true; private long mNextTimeout; private volatile int mPokey = 0; @@ -205,6 +211,10 @@ class PowerManagerService extends IPowerManager.Stub private int mScreenBrightnessOverride = -1; private boolean mHasHardwareAutoBrightness; private boolean mAutoBrightessEnabled; + private int[] mAutoBrightnessLevels; + private int[] mLcdBacklightValues; + private int[] mButtonBacklightValues; + private int[] mKeyboardBacklightValues; // Used when logging number and duration of touch-down cycles private long mTotalTouchDownTime; @@ -425,8 +435,19 @@ class PowerManagerService extends IPowerManager.Stub mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - mHasHardwareAutoBrightness = mContext.getResources().getBoolean( + Resources resources = mContext.getResources(); + mHasHardwareAutoBrightness = resources.getBoolean( com.android.internal.R.bool.config_hardware_automatic_brightness_available); + if (!mHasHardwareAutoBrightness) { + mAutoBrightnessLevels = resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessLevels); + mLcdBacklightValues = resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); + mButtonBacklightValues = resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessButtonBacklightValues); + mKeyboardBacklightValues = resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues); + } ContentResolver resolver = mContext.getContentResolver(); Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null, @@ -553,7 +574,7 @@ class PowerManagerService extends IPowerManager.Stub switch (wl.flags & LOCK_MASK) { case PowerManager.FULL_WAKE_LOCK: - wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); + wl.minState = SCREEN_BRIGHT; break; case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: wl.minState = SCREEN_BRIGHT; @@ -851,6 +872,12 @@ class PowerManagerService extends IPowerManager.Stub pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock); pw.println(" mStayOnWhilePluggedInPartialLock=" + mStayOnWhilePluggedInPartialLock); pw.println(" mPreventScreenOnPartialLock=" + mPreventScreenOnPartialLock); + pw.println(" mProximitySensorActive=" + mProximitySensorActive); + pw.println(" mLightSensorEnabled=" + mLightSensorEnabled); + pw.println(" mLightSensorValue=" + mLightSensorValue); + pw.println(" mLightSensorPendingValue=" + mLightSensorPendingValue); + pw.println(" mHasHardwareAutoBrightness=" + mHasHardwareAutoBrightness); + pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled); mScreenBrightness.dump(pw, " mScreenBrightness: "); mKeyboardBrightness.dump(pw, " mKeyboardBrightness: "); mButtonBrightness.dump(pw, " mButtonBrightness: "); @@ -1254,6 +1281,11 @@ class PowerManagerService extends IPowerManager.Stub int err = Power.setScreenState(on); if (err == 0) { enableLightSensor(on && mAutoBrightessEnabled); + if (!on) { + // make sure button and key backlights are off too + mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, 0); + mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD, 0); + } } return err; } @@ -1712,6 +1744,8 @@ class PowerManagerService extends IPowerManager.Stub try { if (mScreenBrightnessOverride >= 0) { return mScreenBrightnessOverride; + } else if (mLightSensorBrightness >= 0) { + return mLightSensorBrightness; } final int brightness = Settings.System.getInt(mContext.getContentResolver(), SCREEN_BRIGHTNESS); @@ -1795,8 +1829,9 @@ class PowerManagerService extends IPowerManager.Stub if (mLastEventTime <= time || force) { mLastEventTime = time; if ((mUserActivityAllowed && !mProximitySensorActive) || force) { - // Only turn on button backlights if a button was pressed. - if (eventType == BUTTON_EVENT) { + // Only turn on button backlights if a button was pressed + // and auto brightness is disabled + if (eventType == BUTTON_EVENT && !mAutoBrightessEnabled) { mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT); } else { // don't clear button/keyboard backlights when the screen is touched. @@ -1821,12 +1856,75 @@ class PowerManagerService extends IPowerManager.Stub } } - private void lightSensorChangedLocked(float value) { + private int getAutoBrightnessValue(int sensorValue, int[] values) { + try { + int i; + for (i = 0; i < mAutoBrightnessLevels.length; i++) { + if (sensorValue < mAutoBrightnessLevels[i]) { + break; + } + } + return values[i]; + } catch (Exception e) { + // guard against null pointer or index out of bounds errors + Log.e(TAG, "getAutoBrightnessValue", e); + return 255; + } + } + + private Runnable mAutoBrightnessTask = new Runnable() { + public void run() { + int value = (int)mLightSensorPendingValue; + if (value >= 0) { + mLightSensorPendingValue = -1; + lightSensorChangedLocked(value); + } + } + }; + + private void lightSensorChangedLocked(int value) { if (mDebugLightSensor) { Log.d(TAG, "lightSensorChangedLocked " + value); } - mLightSensorValue = value; - // more to do here + + if (mLightSensorValue != value) { + mLightSensorValue = value; + if ((mPowerState & BATTERY_LOW_BIT) == 0) { + int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues); + int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues); + int keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues); + mLightSensorBrightness = lcdValue; + + if (mDebugLightSensor) { + Log.d(TAG, "lcdValue " + lcdValue); + Log.d(TAG, "buttonValue " + buttonValue); + Log.d(TAG, "keyboardValue " + keyboardValue); + } + + if (mScreenBrightnessOverride < 0) { + mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BACKLIGHT, + lcdValue); + } + mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, + buttonValue); + mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD, + keyboardValue); + + // update our animation state + if (ANIMATE_SCREEN_LIGHTS) { + mScreenBrightness.curValue = lcdValue; + mScreenBrightness.animating = false; + } + if (ANIMATE_BUTTON_LIGHTS) { + mButtonBrightness.curValue = buttonValue; + mButtonBrightness.animating = false; + } + if (ANIMATE_KEYBOARD_LIGHTS) { + mKeyboardBrightness.curValue = keyboardValue; + mKeyboardBrightness.animating = false; + } + } + } } /** @@ -1914,6 +2012,8 @@ class PowerManagerService extends IPowerManager.Stub private void setScreenBrightnessMode(int mode) { mAutoBrightessEnabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + // reset computed brightness + mLightSensorBrightness = -1; if (mHasHardwareAutoBrightness) { // When setting auto-brightness, must reset the brightness afterwards @@ -2217,7 +2317,13 @@ class PowerManagerService extends IPowerManager.Stub if (mDebugLightSensor) { Log.d(TAG, "onSensorChanged: light value: " + value); } - lightSensorChangedLocked(value); + mHandler.removeCallbacks(mAutoBrightnessTask); + if (mLightSensorValue != value) { + mLightSensorPendingValue = value; + mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY); + } else { + mLightSensorPendingValue = -1; + } } } From 6c97fcabbc4592a115afa5f3357b3172c4791855 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Tue, 20 Oct 2009 08:10:00 -0400 Subject: [PATCH 10/10] Power Manager light sensor fixes: Fix problem with ignored sensor events right after screen turns on. Do not flash button backlights when device is booting. Process the first light sensor change after waking the screen immediately rather than debouncing. Cancel mAutoBrightnessTask when light sensor is disabled. Change-Id: Iffc5e090b239432b7643812fa8ecb5f69da1679d Signed-off-by: Mike Lockwood --- .../android/server/PowerManagerService.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index a63d3fc81691c..3e134535512d5 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -477,8 +477,13 @@ class PowerManagerService extends IPowerManager.Stub // And explicitly do the initial update of our cached settings updateGservicesValues(); - // turn everything on - setPowerState(ALL_BRIGHT); + if (mAutoBrightessEnabled) { + // turn the screen on + setPowerState(SCREEN_BRIGHT); + } else { + // turn everything on + setPowerState(ALL_BRIGHT); + } synchronized (mHandlerThread) { mInitComplete = true; @@ -1285,6 +1290,9 @@ class PowerManagerService extends IPowerManager.Stub // make sure button and key backlights are off too mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, 0); mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD, 0); + // clear current value so we will update based on the new conditions + // when the sensor is reenabled. + mLightSensorValue = -1; } } return err; @@ -1323,7 +1331,7 @@ class PowerManagerService extends IPowerManager.Stub return; } - if (!mDoneBooting) { + if (!mDoneBooting && !mAutoBrightessEnabled) { newState |= ALL_BRIGHT; } @@ -2275,6 +2283,7 @@ class PowerManagerService extends IPowerManager.Stub SensorManager.SENSOR_DELAY_NORMAL); } else { mSensorManager.unregisterListener(mLightListener); + mHandler.removeCallbacks(mAutoBrightnessTask); } } } @@ -2319,8 +2328,14 @@ class PowerManagerService extends IPowerManager.Stub } mHandler.removeCallbacks(mAutoBrightnessTask); if (mLightSensorValue != value) { - mLightSensorPendingValue = value; - mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY); + if (mLightSensorValue == -1) { + // process the value immediately + lightSensorChangedLocked(value); + } else { + // delay processing to debounce the sensor + mLightSensorPendingValue = value; + mHandler.postDelayed(mAutoBrightnessTask, LIGHT_SENSOR_DELAY); + } } else { mLightSensorPendingValue = -1; }