summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/BatteryStats.java20
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java100
-rw-r--r--core/java/com/android/internal/os/PowerProfile.java5
-rw-r--r--core/res/res/layout/media_controller.xml2
-rw-r--r--core/res/res/values/config.xml38
-rw-r--r--core/res/res/xml/power_profile.xml4
-rw-r--r--opengl/libagl/copybit.cpp85
-rw-r--r--opengl/libagl/egl.cpp23
-rw-r--r--opengl/libagl/texture.cpp5
-rw-r--r--opengl/libs/Android.mk12
-rw-r--r--opengl/libs/GLES2/gl2.cpp14
-rw-r--r--opengl/libs/GLES_CM/gl.cpp14
-rw-r--r--services/java/com/android/server/PowerManagerService.java145
-rw-r--r--services/java/com/android/server/TelephonyRegistry.java2
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java7
-rw-r--r--telephony/java/com/android/internal/telephony/SMSDispatcher.java1
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java1
18 files changed, 389 insertions, 91 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index a49a27a0..b706c5c 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";
@@ -440,6 +441,15 @@ public abstract class BatteryStats implements Parcelable {
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.
*
* {@hide}
@@ -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<NUM_SIGNAL_STRENGTH_BINS; i++) {
args[i] = getPhoneSignalStrengthCount(i, which);
}
@@ -1130,7 +1142,13 @@ public abstract class BatteryStats implements Parcelable {
}
if (!didOne) sb.append("No activity");
pw.println(sb.toString());
-
+
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Signal scanning time: ");
+ formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
+ pw.println(sb.toString());
+
sb.setLength(0);
sb.append(prefix);
sb.append(" Radio types: ");
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 4bac593..d5ccdeb 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -37,7 +37,7 @@ interface IBatteryStats {
void notePhoneOff();
void notePhoneSignalStrength(in SignalStrength signalStrength);
void notePhoneDataConnectionState(int dataType, boolean hasData);
- void noteAirplaneMode(boolean isAirplaneMode);
+ void notePhoneState(int phoneState);
void noteWifiOn(int uid);
void noteWifiOff(int uid);
void noteWifiRunning();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4b26b8f..8698cb7 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -24,6 +24,7 @@ import android.os.ParcelFormatException;
import android.os.Parcelable;
import android.os.Process;
import android.os.SystemClock;
+import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -56,7 +57,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 40;
+ private static final int VERSION = 41;
private static int sNumSpeedSteps;
@@ -117,7 +118,9 @@ public final class BatteryStatsImpl extends BatteryStats {
int mPhoneSignalStrengthBin = -1;
final StopwatchTimer[] mPhoneSignalStrengthsTimer =
new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
-
+
+ StopwatchTimer mPhoneSignalScanningTimer;
+
int mPhoneDataConnectionType = -1;
final StopwatchTimer[] mPhoneDataConnectionsTimer =
new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
@@ -169,6 +172,8 @@ public final class BatteryStatsImpl extends BatteryStats {
private int mBluetoothPingCount;
private int mBluetoothPingStart = -1;
+ private int mPhoneServiceState = -1;
+
/*
* Holds a SamplingTimer associated with each kernel wakelock name being tracked.
*/
@@ -681,6 +686,8 @@ public final class BatteryStatsImpl extends BatteryStats {
*/
long mAcquireTime;
+ long mTimeout;
+
StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
ArrayList<Unpluggable> 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<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
}
+ mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
}
@@ -2679,6 +2725,12 @@ public final class BatteryStatsImpl extends BatteryStats {
if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
}
+ public void setRadioScanningTimeout(long timeout) {
+ if (mPhoneSignalScanningTimer != null) {
+ mPhoneSignalScanningTimer.setTimeout(timeout);
+ }
+ }
+
@Override
public int getStartCount() {
return mStartCount;
@@ -3114,6 +3166,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
}
+ mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
}
@@ -3257,6 +3310,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
}
+ mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
}
@@ -3418,6 +3472,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
}
+ mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
}
@@ -3513,6 +3568,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
}
+ mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
}
@@ -3598,6 +3654,8 @@ public final class BatteryStatsImpl extends BatteryStats {
pr.println("*** Signal strength #" + i + ":");
mPhoneSignalStrengthsTimer[i].logState(pr, " ");
}
+ pr.println("*** Signal scanning :");
+ mPhoneSignalScanningTimer.logState(pr, " ");
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
pr.println("*** Data connection type #" + i + ":");
mPhoneDataConnectionsTimer[i].logState(pr, " ");
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 4b4b717..2369d25 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -97,6 +97,11 @@ public class PowerProfile {
public static final String POWER_RADIO_ON = "radio.on";
/**
+ * Power consumption when cell radio is hunting for a signal.
+ */
+ public static final String POWER_RADIO_SCANNING = "radio.scanning";
+
+ /**
* Power consumption when talking on the phone.
*/
public static final String POWER_RADIO_ACTIVE = "radio.active";
diff --git a/core/res/res/layout/media_controller.xml b/core/res/res/layout/media_controller.xml
index c49835d..32db60a 100644
--- a/core/res/res/layout/media_controller.xml
+++ b/core/res/res/layout/media_controller.xml
@@ -59,7 +59,7 @@
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dip"
android:layout_weight="1"
- android:layout_height="30px"
+ android:layout_height="30dip"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 45fcaa59..274ec2b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -40,6 +40,10 @@
<!-- The duration (in milliseconds) of a long animation. -->
<integer name="config_longAnimTime">400</integer>
+ <!-- The duration (in milliseconds) that the radio will scan for a signal
+ when there's no network connection. If the scan doesn't timeout, use zero -->
+ <integer name="config_radioScanningTimeout">0</integer>
+
<!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
Please don't copy them, copy anything else. -->
@@ -164,4 +168,38 @@
<!-- Control whether status bar should distinguish HSPA data icon form UMTS data icon on devices -->
<bool name="config_hspa_data_distinguishable">false</bool>
+
+ <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
+ The N entries of this array define N + 1 zones as follows:
+
+ Zone 0: 0 <= LUX < array[0]
+ Zone 1: array[0] <= LUX < array[1]
+ ...
+ Zone N: array[N - 1] <= LUX < array[N]
+ Zone N + 1: array[N] <= LUX < infinity
+
+ Must be overridden in platform specific overlays -->
+ <integer-array name="config_autoBrightnessLevels">
+ </integer-array>
+
+ <!-- Array of output values for LCD backlight corresponding to the LUX values
+ in the config_autoBrightnessLevels array. This array should have size one greater
+ than the size of the config_autoBrightnessLevels array.
+ This must be overridden in platform specific overlays -->
+ <integer-array name="config_autoBrightnessLcdBacklightValues">
+ </integer-array>
+
+ <!-- Array of output values for button backlight corresponding to the LUX values
+ in the config_autoBrightnessLevels array. This array should have size one greater
+ than the size of the config_autoBrightnessLevels array.
+ This must be overridden in platform specific overlays -->
+ <integer-array name="config_autoBrightnessButtonBacklightValues">
+ </integer-array>
+
+ <!-- Array of output values for keyboard backlight corresponding to the LUX values
+ in the config_autoBrightnessLevels array. This array should have size one greater
+ than the size of the config_autoBrightnessLevels array.
+ This must be overridden in platform specific overlays -->
+ <integer-array name="config_autoBrightnessKeyboardBacklightValues">
+ </integer-array>
</resources>
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index 710b71e..ce623e8 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -29,10 +29,12 @@
<item name="dsp.audio">0.1</item>
<item name="dsp.video">0.1</item>
<item name="radio.active">1</item>
+ <!-- The current consumed by the radio when it is scanning for a signal -->
+ <item name="radio.scanning">0.5</item>
<item name="gps.on">1</item>
<!-- Current consumed by the radio at different signal strengths, when paging -->
<array name="radio.on"> <!-- Strength 0 to BINS-1 -->
- <value>1</value>
+ <value>0.2</value>
<value>0.1</value>
</array>
<!-- Different CPU speeds as reported in
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 867459d..73b2355 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);
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 37628b7..d04900e 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<numConfigs ; i++) {
+ for (int i=0 ; possibleMatch && i<numConfigs ; i++) {
if (!(possibleMatch & (1<<i)))
continue;
if (isAttributeMatching(i, attr, val) == 0) {
@@ -1523,15 +1536,15 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
}
// now, handle the attributes which have a useful default value
- for (size_t j=0 ; j<NELEM(config_defaults) ; j++) {
- // see if this attribute was specified, if not apply its
+ for (size_t j=0 ; possibleMatch && j<NELEM(config_defaults) ; j++) {
+ // see if this attribute was specified, if not, apply its
// default value
if (binarySearch<config_pair_t>(
(config_pair_t const*)attrib_list,
0, numAttributes-1,
config_defaults[j].key) < 0)
{
- for (int i=0 ; i<numConfigs ; i++) {
+ for (int i=0 ; possibleMatch && i<numConfigs ; i++) {
if (!(possibleMatch & (1<<i)))
continue;
if (isAttributeMatching(i,
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 90e6d29..13d078e 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);
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 9578452..6d20e80 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -32,6 +32,10 @@ ifeq ($(TARGET_BOARD_PLATFORM),msm7k)
LOCAL_CFLAGS += -DADRENO130=1
endif
+ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+endif
+
include $(BUILD_SHARED_LIBRARY)
installed_libEGL := $(LOCAL_INSTALLED_MODULE)
@@ -78,6 +82,10 @@ LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv1\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -fvisibility=hidden
+ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+endif
+
include $(BUILD_SHARED_LIBRARY)
@@ -107,4 +115,8 @@ LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv2\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -fvisibility=hidden
+ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+endif
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 4c0ba88..b8e3283 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -41,12 +41,20 @@ using namespace android;
#if USE_FAST_TLS_KEY
+ #ifdef HAVE_ARM_TLS_REGISTER
+ #define GET_TLS(reg) \
+ "mrc p15, 0, " #reg ", c13, c0, 3 \n"
+ #else
+ #define GET_TLS(reg) \
+ "mov " #reg ", #0xFFFF0FFF \n" \
+ "ldr " #reg ", [" #reg ", #-15] \n"
+ #endif
+
#define API_ENTRY(_api) __attribute__((naked)) _api
#define CALL_GL_API(_api, ...) \
asm volatile( \
- "mov r12, #0xFFFF0FFF \n" \
- "ldr r12, [r12, #-15] \n" \
+ GET_TLS(r12) \
"ldr r12, [r12, %[tls]] \n" \
"cmp r12, #0 \n" \
"ldrne pc, [r12, %[api]] \n" \
@@ -56,7 +64,7 @@ using namespace android;
[api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \
: \
);
-
+
#define CALL_GL_API_RETURN(_api, ...) \
CALL_GL_API(_api, __VA_ARGS__) \
return 0; // placate gcc's warnings. never reached.
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 1e4c136..0c9352e 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -76,12 +76,20 @@ void glVertexPointerBounds(GLint size, GLenum type,
#if USE_FAST_TLS_KEY && !CHECK_FOR_GL_ERRORS
+ #ifdef HAVE_ARM_TLS_REGISTER
+ #define GET_TLS(reg) \
+ "mrc p15, 0, " #reg ", c13, c0, 3 \n"
+ #else
+ #define GET_TLS(reg) \
+ "mov " #reg ", #0xFFFF0FFF \n" \
+ "ldr " #reg ", [" #reg ", #-15] \n"
+ #endif
+
#define API_ENTRY(_api) __attribute__((naked)) _api
#define CALL_GL_API(_api, ...) \
asm volatile( \
- "mov r12, #0xFFFF0FFF \n" \
- "ldr r12, [r12, #-15] \n" \
+ GET_TLS(r12) \
"ldr r12, [r12, %[tls]] \n" \
"cmp r12, #0 \n" \
"ldrne pc, [r12, %[api]] \n" \
@@ -91,7 +99,7 @@ void glVertexPointerBounds(GLint size, GLenum type,
[api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \
: \
);
-
+
#define CALL_GL_API_RETURN(_api, ...) \
CALL_GL_API(_api, __VA_ARGS__) \
return 0; // placate gcc's warnings. never reached.
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 99e008c..9b54a70 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,
@@ -456,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;
@@ -553,7 +579,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 +877,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 +1286,14 @@ 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);
+ // clear current value so we will update based on the new conditions
+ // when the sensor is reenabled.
+ mLightSensorValue = -1;
+ }
}
return err;
}
@@ -1291,7 +1331,7 @@ class PowerManagerService extends IPowerManager.Stub
return;
}
- if (!mDoneBooting) {
+ if (!mDoneBooting && !mAutoBrightessEnabled) {
newState |= ALL_BRIGHT;
}
@@ -1712,6 +1752,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 +1837,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 +1864,77 @@ 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() {
+ synchronized (mLocks) {
+ 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 +2022,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
@@ -2175,6 +2285,7 @@ class PowerManagerService extends IPowerManager.Stub
SensorManager.SENSOR_DELAY_NORMAL);
} else {
mSensorManager.unregisterListener(mLightListener);
+ mHandler.removeCallbacks(mAutoBrightnessTask);
}
}
}
@@ -2217,7 +2328,19 @@ class PowerManagerService extends IPowerManager.Stub
if (mDebugLightSensor) {
Log.d(TAG, "onSensorChanged: light value: " + value);
}
- lightSensorChangedLocked(value);
+ mHandler.removeCallbacks(mAutoBrightnessTask);
+ if (mLightSensorValue != value) {
+ 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;
+ }
}
}
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 101b075..47cb6ad 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -477,7 +477,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private void broadcastServiceStateChanged(ServiceState state) {
long ident = Binder.clearCallingIdentity();
try {
- mBatteryStats.noteAirplaneMode(state.getState() == ServiceState.STATE_POWER_OFF);
+ mBatteryStats.notePhoneState(state.getState());
} catch (RemoteException re) {
// Can't do much
} finally {
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 61537f5..5a1619a 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -51,6 +51,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
mContext = context;
ServiceManager.addService("batteryinfo", asBinder());
mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
+ mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_radioScanningTimeout)
+ * 1000L);
}
public void shutdown() {
@@ -195,10 +198,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
}
- public void noteAirplaneMode(boolean airplaneMode) {
+ public void notePhoneState(int state) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteAirplaneModeLocked(airplaneMode);
+ mStats.notePhoneStateLocked(state);
}
}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index d26a092..53c0bef 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -303,6 +303,7 @@ public abstract class SMSDispatcher extends Handler {
notifyAndAcknowledgeLastIncomingSms(handled, result, null);
}
} catch (RuntimeException ex) {
+ Log.e(TAG, "Exception dispatching message", ex);
notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 7baf770..d895cd4 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -100,6 +100,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
// If sms is null, means there was a parsing error.
if (smsb == null) {
+ Log.e(TAG, "dispatchMessage: message is null");
return Intents.RESULT_SMS_GENERIC_ERROR;
}