Merge change 23667 into eclair
* changes:
Fix the -1 unread count bug.
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 5ed8941..8cfb758 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1397,7 +1397,7 @@
Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi);
}
- if (!imsi.equals(storedImsi) && !"initial".equals(storedImsi)) {
+ if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "wiping all passwords and authtokens");
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 59529be..2a17672 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1267,6 +1267,8 @@
* enabled or disabled. The data contains the name of the package.
* <ul>
* <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
+ * <li> {@link #EXTRA_CHANGED_COMPONENT_NAME} containing the class name of the changed component.
+ * <li> {@link #EXTRA_DONT_KILL_APP} containing boolean field to override the default action of restarting the application.
* </ul>
*
* <p class="note">This is a protected intent that can only be sent
@@ -2034,6 +2036,14 @@
public static final String EXTRA_REMOTE_INTENT_TOKEN =
"android.intent.extra.remote_intent_token";
+ /**
+ * Used as an int extra field in {@link android.content.Intent#ACTION_PACKAGE_CHANGED}
+ * intent to supply the name of the component that changed.
+ * @hide
+ */
+ public static final String EXTRA_CHANGED_COMPONENT_NAME =
+ "android.intent.extra.changed_component_name";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 6b491ab..84753ee 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -59,6 +59,8 @@
/** Valid tag values. Extend as necessary for your needs. */
public enum Tag {
+ APANIC_CONSOLE,
+ APANIC_THREADS,
AUTOTEST_FAILURE,
AUTOTEST_SEQUENCE_BEGIN,
AUTOTEST_SUITE_BEGIN,
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 77d1740..125ed0b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2231,6 +2231,32 @@
public static final String BACKGROUND_DATA = "background_data";
/**
+ * The time in msec, when the LAST_KMSG file was send to the checkin server.
+ * We will only send the LAST_KMSG file if it was modified after this time.
+ *
+ * @hide
+ */
+ public static final String CHECKIN_SEND_LAST_KMSG_TIME = "checkin_kmsg_time";
+
+ /**
+ * The time in msec, when the apanic_console file was send to the checkin server.
+ * We will only send the apanic_console file if it was modified after this time.
+ *
+ * @hide
+ */
+ public static final String CHECKIN_SEND_APANIC_CONSOLE_TIME =
+ "checkin_apanic_console_time";
+
+ /**
+ * The time in msec, when the apanic_thread file was send to the checkin server.
+ * We will only send the apanic_thread file if it was modified after this time.
+ *
+ * @hide
+ */
+ public static final String CHECKIN_SEND_APANIC_THREAD_TIME =
+ "checkin_apanic_thread_time";
+
+ /**
* The CDMA roaming mode 0 = Home Networks, CDMA default
* 1 = Roaming on Affiliated networks
* 2 = Roaming on any networks
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 8bae3e4..ce0c9cb 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -425,6 +425,11 @@
}
public void onClick(View view) {
+ // Make sure there is a contact
+ if (mContactUri == null) {
+ return;
+ }
+
switch (view.getId()) {
case R.id.star: {
// Toggle "starred" state
diff --git a/core/res/res/values-en-rUS/donottranslate-names.xml b/core/res/res/values-en-rUS/donottranslate-names.xml
index 42c8ab4..82ba310 100644
--- a/core/res/res/values-en-rUS/donottranslate-names.xml
+++ b/core/res/res/values-en-rUS/donottranslate-names.xml
@@ -147,7 +147,7 @@
MD, MS, PH.D., PHD, SR, V, VI, VII, VIII, X
</string>
<string name="common_last_name_prefixes">
- D', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
+ D\', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
</string>
<string name="common_name_conjunctions">
&, AND, OR
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 29cdf21..5b0e0b4 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -136,7 +136,7 @@
void clearCodecSpecificData();
void setAMRFormat();
- void setAACFormat();
+ void setAACFormat(int32_t numChannels, int32_t sampleRate);
status_t setVideoPortFormatType(
OMX_U32 portIndex,
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 0831f4a..f80843d 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3284,7 +3284,16 @@
break;
}
if (c == '\'' && (quoted == 0 || quoted == '\'')) {
- break;
+ /*
+ * In practice, when people write ' instead of \'
+ * in a string, they are doing it by accident
+ * instead of really meaning to use ' as a quoting
+ * character. Warn them so they don't lose it.
+ */
+ if (outErrorMsg) {
+ *outErrorMsg = "Apostrophe not preceded by \\";
+ }
+ return false;
}
}
p++;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 098ddbd..6af7df9 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -174,7 +174,7 @@
*http_status = -1;
mHeaders.clear();
- char line[256];
+ char line[1024];
status_t err = receive_line(line, sizeof(line));
if (err != OK) {
return err;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3a065ae..7c8defc 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -302,7 +302,11 @@
codec->setAMRFormat();
}
if (!createEncoder && !strcasecmp("audio/mp4a-latm", mime)) {
- codec->setAACFormat();
+ int32_t numChannels, sampleRate;
+ CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
+ CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
+
+ codec->setAACFormat(numChannels, sampleRate);
}
if (!strncasecmp(mime, "video/", 6)) {
int32_t width, height;
@@ -1321,10 +1325,6 @@
return;
}
- // We're going to temporarily give up the lock while reading data
- // from the source. A certain client unfortunately chose to have the
- // thread supplying input data and reading output data be the same...
-
MediaBuffer *srcBuffer;
status_t err;
if (mSeekTimeUs >= 0) {
@@ -1332,13 +1332,10 @@
options.setSeekTo(mSeekTimeUs);
mSeekTimeUs = -1;
- mLock.unlock();
err = mSource->read(&srcBuffer, &options);
} else {
- mLock.unlock();
err = mSource->read(&srcBuffer);
}
- mLock.lock();
OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
OMX_TICKS timestamp = 0;
@@ -1496,20 +1493,22 @@
}
}
-void OMXCodec::setAACFormat() {
- OMX_AUDIO_PARAM_AACPROFILETYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
- def.nPortIndex = kPortIndexInput;
+void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
+ OMX_AUDIO_PARAM_AACPROFILETYPE profile;
+ profile.nSize = sizeof(profile);
+ profile.nVersion.s.nVersionMajor = 1;
+ profile.nVersion.s.nVersionMinor = 1;
+ profile.nPortIndex = kPortIndexInput;
status_t err =
- mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
+ mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
CHECK_EQ(err, OK);
- def.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
+ profile.nChannels = numChannels;
+ profile.nSampleRate = sampleRate;
+ profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
- err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
+ err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
CHECK_EQ(err, OK);
}
@@ -2123,8 +2122,19 @@
inputFormat->findInt32(kKeyChannelCount, &numChannels);
inputFormat->findInt32(kKeySampleRate, &sampleRate);
+ if ((OMX_U32)numChannels != params.nChannels) {
+ LOGW("Codec outputs a different number of channels than "
+ "the input stream contains.");
+ }
+
mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
- mOutputFormat->setInt32(kKeyChannelCount, numChannels);
+
+ // Use the codec-advertised number of channels, as some
+ // codecs appear to output stereo even if the input data is
+ // mono.
+ mOutputFormat->setInt32(kKeyChannelCount, params.nChannels);
+
+ // The codec-reported sampleRate is not reliable...
mOutputFormat->setInt32(kKeySampleRate, sampleRate);
break;
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 8ec6ec3..14cd7a8 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -62,6 +62,8 @@
import android.os.Build;
import android.os.Bundle;
import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.Environment;
@@ -140,7 +142,7 @@
final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
Process.THREAD_PRIORITY_BACKGROUND);
- final Handler mHandler;
+ final PackageHandler mHandler;
final int mSdkVersion = Build.VERSION.SDK_INT;
final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
@@ -272,6 +274,49 @@
ComponentName mResolveComponentName;
PackageParser.Package mPlatformPackage;
+ // Set of pending broadcasts for aggregating enable/disable of components.
+ final HashMap<String, String> mPendingBroadcasts = new HashMap<String, String>();
+ static final int SEND_PENDING_BROADCAST = 1;
+ // Delay time in millisecs
+ static final int BROADCAST_DELAY = 10 * 1000;
+
+ class PackageHandler extends Handler {
+ PackageHandler(Looper looper) {
+ super(looper);
+ }
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SEND_PENDING_BROADCAST : {
+ int size = 0;
+ String broadcastList[];
+ HashMap<String, String> tmpMap;
+ int uids[];
+ synchronized (mPackages) {
+ size = mPendingBroadcasts.size();
+ if (size <= 0) {
+ // Nothing to be done. Just return
+ return;
+ }
+ broadcastList = new String[size];
+ mPendingBroadcasts.keySet().toArray(broadcastList);
+ tmpMap = new HashMap<String, String>(mPendingBroadcasts);
+ uids = new int[size];
+ for (int i = 0; i < size; i++) {
+ PackageSetting ps = mSettings.mPackages.get(mPendingBroadcasts.get(broadcastList[i]));
+ uids[i] = (ps != null) ? ps.userId : -1;
+ }
+ mPendingBroadcasts.clear();
+ }
+ // Send broadcasts
+ for (int i = 0; i < size; i++) {
+ String className = broadcastList[i];
+ sendPackageChangedBroadcast(className, true, tmpMap.get(className), uids[i]);
+ }
+ break;
+ }
+ }
+ }
+ }
public static final IPackageManager main(Context context, boolean factoryTest) {
PackageManagerService m = new PackageManagerService(context, factoryTest);
ServiceManager.addService("package", m);
@@ -355,7 +400,7 @@
synchronized (mInstallLock) {
synchronized (mPackages) {
mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
+ mHandler = new PackageHandler(mHandlerThread.getLooper());
File dataDir = Environment.getDataDirectory();
mAppDataDir = new File(dataDir, "data");
@@ -4866,7 +4911,7 @@
}
private void setEnabledSetting(
- final String packageNameStr, String classNameStr, int newState, final int flags) {
+ final String packageName, String className, int newState, final int flags) {
if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
|| newState == COMPONENT_ENABLED_STATE_ENABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED)) {
@@ -4878,17 +4923,20 @@
final int permission = mContext.checkCallingPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
+ boolean sendNow = false;
+ boolean isApp = (className == null);
+ String key = isApp ? packageName : className;
int packageUid = -1;
synchronized (mPackages) {
- pkgSetting = mSettings.mPackages.get(packageNameStr);
+ pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
- if (classNameStr == null) {
+ if (className == null) {
throw new IllegalArgumentException(
- "Unknown package: " + packageNameStr);
+ "Unknown package: " + packageName);
}
throw new IllegalArgumentException(
- "Unknown component: " + packageNameStr
- + "/" + classNameStr);
+ "Unknown component: " + packageName
+ + "/" + className);
}
if (!allowedByPermission && (uid != pkgSetting.userId)) {
throw new SecurityException(
@@ -4896,41 +4944,67 @@
+ Binder.getCallingPid()
+ ", uid=" + uid + ", package uid=" + pkgSetting.userId);
}
- packageUid = pkgSetting.userId;
- if (classNameStr == null) {
+ if (className == null) {
// We're dealing with an application/package level state change
pkgSetting.enabled = newState;
} else {
// We're dealing with a component level state change
switch (newState) {
case COMPONENT_ENABLED_STATE_ENABLED:
- pkgSetting.enableComponentLP(classNameStr);
+ pkgSetting.enableComponentLP(className);
break;
case COMPONENT_ENABLED_STATE_DISABLED:
- pkgSetting.disableComponentLP(classNameStr);
+ pkgSetting.disableComponentLP(className);
break;
case COMPONENT_ENABLED_STATE_DEFAULT:
- pkgSetting.restoreComponentLP(classNameStr);
+ pkgSetting.restoreComponentLP(className);
break;
default:
Log.e(TAG, "Invalid new component state: " + newState);
+ return;
}
}
mSettings.writeLP();
+ packageUid = pkgSetting.userId;
+ if ((flags&PackageManager.DONT_KILL_APP) == 0) {
+ sendNow = true;
+ // Purge entry from pending broadcast list if another one exists already
+ // since we are sending one right away.
+ if (mPendingBroadcasts.get(key) != null) {
+ mPendingBroadcasts.remove(key);
+ // Can ignore empty list since its handled in the handler anyway
+ }
+ } else {
+ if (mPendingBroadcasts.get(key) == null) {
+ mPendingBroadcasts.put(key, packageName);
+ }
+ if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
+ // Schedule a message
+ mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+ }
+ }
}
-
+
long callingId = Binder.clearCallingIdentity();
try {
- Bundle extras = new Bundle(2);
- extras.putBoolean(Intent.EXTRA_DONT_KILL_APP,
- (flags&PackageManager.DONT_KILL_APP) != 0);
- extras.putInt(Intent.EXTRA_UID, packageUid);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageNameStr, extras);
+ if (sendNow) {
+ sendPackageChangedBroadcast(packageName,
+ (flags&PackageManager.DONT_KILL_APP) != 0, key, packageUid);
+ }
} finally {
Binder.restoreCallingIdentity(callingId);
}
}
+ private void sendPackageChangedBroadcast(String packageName,
+ boolean killFlag, String componentName, int packageUid) {
+ Bundle extras = new Bundle(2);
+ extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentName);
+ extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
+ extras.putInt(Intent.EXTRA_UID, packageUid);
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras);
+ }
+
public String getInstallerPackageName(String packageName) {
synchronized (mPackages) {
PackageSetting pkg = mSettings.mPackages.get(packageName);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 4c958f6..dab529e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -46,6 +46,7 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.gsm.MccTable;
+import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
@@ -443,6 +444,8 @@
if (!mIsMinInfoReady) {
mIsMinInfoReady = true;
}
+ phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
+ null);
} else {
Log.w(LOG_TAG,"error parsing cdmaSubscription params num="
+ cdmaSubscription.length);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 95a2384..f9d2434 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2364,13 +2364,12 @@
String8 region(config.string(), 2);
if (configSet.find(region) == configSet.end()) {
if (configSet.count(defaultLocale) == 0) {
- fprintf(stdout, "aapt: error: "
+ fprintf(stdout, "aapt: warning: "
"*** string '%s' has no default or required localization "
"for '%s' in %s\n",
String8(nameIter->first).string(),
config.string(),
mBundle->getResourceSourceDirs()[0]);
- err = UNKNOWN_ERROR;
}
}
}
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 6daa0d2..d4d2a45c 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -219,7 +219,12 @@
}
spanStack.pop();
- if (empty) {
+ /*
+ * This warning seems to be just an irritation to most people,
+ * since it is typically introduced by translators who then never
+ * see the warning.
+ */
+ if (0 && empty) {
fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
fileName, inXml->getLineNumber(),
String8(spanTag).string(), String8(*outString).string());