Merge "Fix bug 2523989"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1c980e3..fa6abec 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3908,16 +3908,16 @@
}
}
- final void applyConfigurationToResourcesLocked(Configuration config) {
+ final boolean applyConfigurationToResourcesLocked(Configuration config) {
if (mResConfiguration == null) {
mResConfiguration = new Configuration();
}
if (!mResConfiguration.isOtherSeqNewer(config)) {
if (DEBUG_CONFIGURATION) Log.v(TAG, "Skipping new config: curSeq="
+ mResConfiguration.seq + ", newSeq=" + config.seq);
- return;
+ return false;
}
- mResConfiguration.updateFrom(config);
+ int changes = mResConfiguration.updateFrom(config);
DisplayMetrics dm = getDisplayMetricsLocked(true);
// set it for java, this also affects newly created Resources
@@ -3948,6 +3948,8 @@
it.remove();
}
}
+
+ return changes != 0;
}
final void handleConfigurationChanged(Configuration config) {
@@ -4522,17 +4524,20 @@
ViewRoot.addConfigCallback(new ComponentCallbacks() {
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mPackages) {
- if (mPendingConfiguration == null ||
- mPendingConfiguration.isOtherSeqNewer(newConfig)) {
- mPendingConfiguration = newConfig;
-
- // We need to apply this change to the resources
- // immediately, because upon returning the view
- // hierarchy will be informed about it.
- applyConfigurationToResourcesLocked(newConfig);
+ // We need to apply this change to the resources
+ // immediately, because upon returning the view
+ // hierarchy will be informed about it.
+ if (applyConfigurationToResourcesLocked(newConfig)) {
+ // This actually changed the resources! Tell
+ // everyone about it.
+ if (mPendingConfiguration == null ||
+ mPendingConfiguration.isOtherSeqNewer(newConfig)) {
+ mPendingConfiguration = newConfig;
+
+ queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
+ }
}
}
- queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
public void onLowMemory() {
}
diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp
index 4e8d05b..36234a9 100644
--- a/core/jni/android_database_SQLiteDatabase.cpp
+++ b/core/jni/android_database_SQLiteDatabase.cpp
@@ -72,8 +72,9 @@
}
static void sqlLogger(void *databaseName, int iErrCode, const char *zMsg) {
- LOGI("sqlite returned: database = %s, error code = %d, msg = %s\n",
- (char *)databaseName, iErrCode, zMsg);
+ // skip printing this message if it is due to certain types of errors
+ if (iErrCode == SQLITE_CONSTRAINT) return;
+ LOGI("sqlite returned: error code = %d, msg = %s\n", iErrCode, zMsg);
}
// register the logging func on sqlite. needs to be done BEFORE any sqlite3 func is called.
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index 28b0d2f..998e353 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -26,6 +26,12 @@
namespace android {
+#define ANDROID_TTS_ENGINE_PROPERTY_CONFIG "engineConfig"
+#define ANDROID_TTS_ENGINE_PROPERTY_PITCH "pitch"
+#define ANDROID_TTS_ENGINE_PROPERTY_RATE "rate"
+#define ANDROID_TTS_ENGINE_PROPERTY_VOLUME "volume"
+
+
enum tts_synth_status {
TTS_SYNTH_DONE = 0,
TTS_SYNTH_PENDING = 1
@@ -85,7 +91,7 @@
// Initialize the TTS engine and returns whether initialization succeeded.
// @param synthDoneCBPtr synthesis callback function pointer
// @return TTS_SUCCESS, or TTS_FAILURE
- virtual tts_result init(synthDoneCB_t synthDoneCBPtr);
+ virtual tts_result init(synthDoneCB_t synthDoneCBPtr, const char *engineConfig);
// Shut down the TTS engine and releases all associated resources.
// @return TTS_SUCCESS, or TTS_FAILURE
@@ -122,7 +128,7 @@
// @param variant pointer to the variant code
// @return TTS_SUCCESS, or TTS_FAILURE
virtual tts_result loadLanguage(const char *lang, const char *country, const char *variant);
-
+
// Load the resources associated with the specified language, country and Locale variant.
// The loaded language will only be used once a call to setLanguageFromLocale() with the same
// language value is issued. Language and country values are coded according to the ISO three
@@ -220,19 +226,6 @@
virtual tts_result synthesizeText(const char *text, int8_t *buffer,
size_t bufferSize, void *userdata);
- // Synthesize IPA text.
- // As the synthesis is performed, the engine invokes the callback to notify
- // the TTS framework that it has filled the given buffer, and indicates how
- // many bytes it wrote. The callback is called repeatedly until the engine
- // has generated all the audio data corresponding to the IPA data.
- // @param ipa the IPA data to synthesize
- // @param userdata pointer to be returned when the call is invoked
- // @param buffer the location where the synthesized data must be written
- // @param bufferSize the number of bytes that can be written in buffer
- // @return TTS_FEATURE_UNSUPPORTED if IPA is not supported,
- // otherwise TTS_SUCCESS or TTS_FAILURE
- virtual tts_result synthesizeIpa(const char *ipa, int8_t *buffer,
- size_t bufferSize, void *userdata);
};
} // namespace android
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index c05d90a..fcf506d 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -595,6 +595,9 @@
static const int32_t kNumIterations = 5000;
+ // We are always going to seek beyond EOS in the first iteration (i == 0)
+ // followed by a linear read for the second iteration (i == 1).
+ // After that it's all random.
for (int32_t i = 0; i < kNumIterations; ++i) {
int64_t requestedSeekTimeUs;
int64_t actualSeekTimeUs;
@@ -602,14 +605,14 @@
double r = uniform_rand();
- if (i > 0 && r < 0.5) {
+ if ((i == 1) || (i > 0 && r < 0.5)) {
// 50% chance of just continuing to decode from last position.
requestedSeekTimeUs = -1;
LOGI("requesting linear read");
} else {
- if (i > 0 && r < 0.55) {
+ if (i == 0 || r < 0.55) {
// 5% chance of seeking beyond end of stream.
requestedSeekTimeUs = durationUs;
@@ -674,7 +677,15 @@
buffer = NULL;
}
} else if (actualSeekTimeUs < 0) {
- CHECK(err != OK);
+ EXPECT(err != OK,
+ "We attempted to seek beyond EOS and expected "
+ "ERROR_END_OF_STREAM to be returned, but instead "
+ "we got a valid buffer.");
+ EXPECT(err == ERROR_END_OF_STREAM,
+ "We attempted to seek beyond EOS and expected "
+ "ERROR_END_OF_STREAM to be returned, but instead "
+ "we found some other error.");
+ CHECK_EQ(err, ERROR_END_OF_STREAM);
CHECK_EQ(buffer, NULL);
} else {
EXPECT(err == OK,
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index b7acd96..1d69361 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -383,7 +383,7 @@
// ----------------------------------------------------------------------------
static int
android_tts_SynthProxy_native_setup(JNIEnv *env, jobject thiz,
- jobject weak_this, jstring nativeSoLib)
+ jobject weak_this, jstring nativeSoLib, jstring engConfig)
{
int result = TTS_FAILURE;
@@ -395,6 +395,7 @@
DEFAULT_TTS_STREAM_TYPE, DEFAULT_TTS_RATE, DEFAULT_TTS_FORMAT, DEFAULT_TTS_NB_CHANNELS);
const char *nativeSoLibNativeString = env->GetStringUTFChars(nativeSoLib, 0);
+ const char *engConfigString = env->GetStringUTFChars(engConfig, 0);
void *engine_lib_handle = dlopen(nativeSoLibNativeString,
RTLD_NOW | RTLD_LOCAL);
@@ -409,7 +410,7 @@
if (pJniStorage->mNativeSynthInterface) {
Mutex::Autolock l(engineMutex);
- pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB);
+ pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB, engConfigString);
}
result = TTS_SUCCESS;
@@ -422,6 +423,7 @@
env->SetIntField(thiz, javaTTSFields.synthProxyFieldJniData, (int)pJniStorage);
env->ReleaseStringUTFChars(nativeSoLib, nativeSoLibNativeString);
+ env->ReleaseStringUTFChars(engConfig, engConfigString);
return result;
}
@@ -482,6 +484,29 @@
return result;
}
+static int
+android_tts_SynthProxy_setConfig(JNIEnv *env, jobject thiz, jint jniData, jstring engineConfig)
+{
+ int result = TTS_FAILURE;
+
+ if (jniData == 0) {
+ LOGE("android_tts_SynthProxy_setConfig(): invalid JNI data");
+ return result;
+ }
+
+ Mutex::Autolock l(engineMutex);
+
+ SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+ const char *engineConfigNativeString = env->GetStringUTFChars(engineConfig, 0);
+
+ if (pSynthData->mNativeSynthInterface) {
+ result = pSynthData->mNativeSynthInterface->setProperty(ANDROID_TTS_ENGINE_PROPERTY_CONFIG,
+ engineConfigNativeString, strlen(engineConfigNativeString));
+ }
+ env->ReleaseStringUTFChars(engineConfig, engineConfigNativeString);
+
+ return result;
+}
static int
android_tts_SynthProxy_setLanguage(JNIEnv *env, jobject thiz, jint jniData,
@@ -867,6 +892,10 @@
"(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void*)android_tts_SynthProxy_isLanguageAvailable
},
+ { "native_setConfig",
+ "(ILjava/lang/String;)I",
+ (void*)android_tts_SynthProxy_setConfig
+ },
{ "native_setLanguage",
"(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void*)android_tts_SynthProxy_setLanguage
@@ -896,7 +925,7 @@
(void*)android_tts_SynthProxy_shutdown
},
{ "native_setup",
- "(Ljava/lang/Object;Ljava/lang/String;)I",
+ "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)I",
(void*)android_tts_SynthProxy_native_setup
},
{ "native_setLowShelf",
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index 5f283e1..2a0bbeb 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -51,7 +51,7 @@
public SynthProxy(String nativeSoLib, String engineConfig) {
boolean applyFilter = nativeSoLib.toLowerCase().contains("pico");
Log.v(TtsService.SERVICE_TAG, "About to load "+ nativeSoLib + ", applyFilter="+applyFilter);
- native_setup(new WeakReference<SynthProxy>(this), nativeSoLib);
+ native_setup(new WeakReference<SynthProxy>(this), nativeSoLib, engineConfig);
native_setLowShelf(applyFilter, PICO_FILTER_GAIN, PICO_FILTER_LOWSHELF_ATTENUATION,
PICO_FILTER_TRANSITION_FREQ, PICO_FILTER_SHELF_SLOPE);
}
@@ -105,10 +105,10 @@
}
/**
- * Sets the engine configuration.
+ * Updates the engine configuration.
*/
public int setConfig(String engineConfig) {
- return android.speech.tts.TextToSpeech.SUCCESS;
+ return native_setConfig(engineConfig);
}
/**
@@ -180,7 +180,8 @@
*/
private int mJniData = 0;
- private native final int native_setup(Object weak_this, String nativeSoLib);
+ private native final int native_setup(Object weak_this, String nativeSoLib,
+ String engineConfig);
private native final int native_setLowShelf(boolean applyFilter, float filterGain,
float attenuationInDb, float freqInHz, float slope);
@@ -204,6 +205,8 @@
private native final int native_loadLanguage(int jniData, String language, String country,
String variant);
+ private native final int native_setConfig(String engineConfig);
+
private native final int native_setSpeechRate(int jniData, int speechRate);
private native final int native_setPitch(int jniData, int speechRate);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 4eb529c..12666927 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -308,13 +308,17 @@
}
} catch (Exception e) {
Slog.e(TAG, "Error configuring interface " + intf + ", :" + e);
+ try {
+ nwService.stopAccessPoint();
+ } catch (Exception ee) {
+ Slog.e(TAG, "Could not stop AP, :" + ee);
+ }
setWifiApEnabledState(WIFI_AP_STATE_FAILED, 0, DriverAction.DRIVER_UNLOAD);
return;
}
if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
Slog.e(TAG, "Error tethering "+intf);
- setWifiApEnabledState(WIFI_AP_STATE_FAILED, 0, DriverAction.DRIVER_UNLOAD);
}
break;
}
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 08530a0..c8b6837 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -37,12 +37,12 @@
mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),
mUpdate(false), mExtending(false),
mRequireLocalization(false), mPseudolocalize(false),
- mUTF8(false), mEncodingSpecified(false), mValues(false),
+ mWantUTF16(false), mValues(false),
mCompressionMethod(0), mOutputAPKFile(NULL),
mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
mAutoAddOverlay(false), mAssetSourceDir(NULL), mProguardFile(NULL),
mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
- mRClassDir(NULL), mResourceIntermediatesDir(NULL),
+ mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
mArgc(0), mArgv(NULL)
@@ -77,10 +77,8 @@
void setRequireLocalization(bool val) { mRequireLocalization = val; }
bool getPseudolocalize(void) const { return mPseudolocalize; }
void setPseudolocalize(bool val) { mPseudolocalize = val; }
- bool getUTF8(void) const { return mUTF8; }
- void setUTF8(bool val) { mUTF8 = val; }
- bool getEncodingSpecified(void) const { return mEncodingSpecified; }
- void setEncodingSpecified(bool val) { mEncodingSpecified = val; }
+ bool getWantUTF16(void) const { return mWantUTF16; }
+ void setWantUTF16(bool val) { mWantUTF16 = val; }
bool getValues(void) const { return mValues; }
void setValues(bool val) { mValues = val; }
int getCompressionMethod(void) const { return mCompressionMethod; }
@@ -122,13 +120,10 @@
const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; }
void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); }
+ const char* getManifestMinSdkVersion() const { return mManifestMinSdkVersion; }
+ void setManifestMinSdkVersion(const char* val) { mManifestMinSdkVersion = val; }
const char* getMinSdkVersion() const { return mMinSdkVersion; }
- void setMinSdkVersion(const char* val) {
- mMinSdkVersion = val;
- if (!mEncodingSpecified) {
- setUTF8(isUTF8Available());
- }
- }
+ void setMinSdkVersion(const char* val) { mMinSdkVersion = val; }
const char* getTargetSdkVersion() const { return mTargetSdkVersion; }
void setTargetSdkVersion(const char* val) { mTargetSdkVersion = val; }
const char* getMaxSdkVersion() const { return mMaxSdkVersion; }
@@ -167,6 +162,34 @@
void setPackageCount(int val) { mPackageCount = val; }
#endif
+ /* UTF-8 is only available on APIs 7 or above or
+ * SDK levels that have code names.
+ */
+ bool isUTF8Available() {
+ /* If the application specifies a minSdkVersion in the manifest
+ * then use that. Otherwise, check what the user specified on
+ * the command line. If neither, it's not available since
+ * the minimum SDK version is assumed to be 1.
+ */
+ const char *minVer;
+ if (mManifestMinSdkVersion != NULL) {
+ minVer = mManifestMinSdkVersion;
+ } else if (mMinSdkVersion != NULL) {
+ minVer = mMinSdkVersion;
+ } else {
+ return false;
+ }
+
+ char *end;
+ int minSdkNum = (int)strtol(minVer, &end, 0);
+ if (*end == '\0') {
+ if (minSdkNum < 7) {
+ return false;
+ }
+ }
+ return true;
+ }
+
private:
/* commands & modifiers */
Command mCmd;
@@ -179,8 +202,7 @@
bool mExtending;
bool mRequireLocalization;
bool mPseudolocalize;
- bool mUTF8;
- bool mEncodingSpecified;
+ bool mWantUTF16;
bool mValues;
int mCompressionMethod;
bool mJunkPath;
@@ -200,6 +222,7 @@
android::Vector<const char*> mNoCompressExtensions;
android::Vector<const char*> mResourceSourceDirs;
+ const char* mManifestMinSdkVersion;
const char* mMinSdkVersion;
const char* mTargetSdkVersion;
const char* mMaxSdkVersion;
@@ -216,19 +239,6 @@
int mPackageCount;
#endif
- /* UTF-8 is only available on APIs 7 or above or
- * SDK levels that have code names.
- */
- bool isUTF8Available() {
- char *end;
- int minSdkNum = (int)strtol(mMinSdkVersion, &end, 0);
- if (*end == '\0') {
- if (minSdkNum < 7) {
- return false;
- }
- }
- return true;
- }
};
#endif // __BUNDLE_H
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index dd98c85..b0c6e39 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -446,8 +446,7 @@
}
bundle.setCustomPackage(argv[0]);
} else if (strcmp(cp, "-utf16") == 0) {
- bundle.setEncodingSpecified(true);
- bundle.setUTF8(false);
+ bundle.setWantUTF16(true);
} else if (strcmp(cp, "-rename-manifest-package") == 0) {
argc--;
argv++;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index c0ebb59..87f2420 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -226,7 +226,7 @@
if (minSdkIndex >= 0) {
const uint16_t* minSdk16 = block.getAttributeStringValue(minSdkIndex, &len);
const char* minSdk8 = strdup(String8(minSdk16).string());
- bundle->setMinSdkVersion(minSdk8);
+ bundle->setManifestMinSdkVersion(minSdk8);
}
}
}
@@ -768,7 +768,13 @@
// Standard flags for compiled XML and optional UTF-8 encoding
int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;
- if (bundle->getUTF8()) {
+
+ /* Only enable UTF-8 if the caller of aapt didn't specifically
+ * request UTF-16 encoding and the parameters of this package
+ * allow UTF-8 to be used.
+ */
+ if (!bundle->getWantUTF16()
+ && bundle->isUTF8Available()) {
xmlFlags |= XML_COMPILE_UTF8;
}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index ab5e937..66db450 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2527,9 +2527,11 @@
const size_t N = mOrderedPackages.size();
size_t pi;
+ bool useUTF8 = !bundle->getWantUTF16() && bundle->isUTF8Available();
+
// Iterate through all data, collecting all values (strings,
// references, etc).
- StringPool valueStrings = StringPool(false, bundle->getUTF8());
+ StringPool valueStrings = StringPool(false, useUTF8);
for (pi=0; pi<N; pi++) {
sp<Package> p = mOrderedPackages.itemAt(pi);
if (p->getTypes().size() == 0) {
@@ -2537,8 +2539,8 @@
continue;
}
- StringPool typeStrings = StringPool(false, bundle->getUTF8());
- StringPool keyStrings = StringPool(false, bundle->getUTF8());
+ StringPool typeStrings = StringPool(false, useUTF8);
+ StringPool keyStrings = StringPool(false, useUTF8);
const size_t N = p->getOrderedTypes().size();
for (size_t ti=0; ti<N; ti++) {