Skip to content

Commit 30ca5cd

Browse files
author
Fabrice Di Meglio
committed
Fix bug #6408393 Character corruption is caused when locale is changed
- free the TextLayoutCache on Locale change - also free TextLayoutCache when memory is low Change-Id: I39a37ac8ec3c292cfb1c0eea4bb41ff71897d089
1 parent 476b03b commit 30ca5cd

File tree

5 files changed

+47
-2
lines changed

5 files changed

+47
-2
lines changed

core/java/android/app/ActivityThread.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,6 +2639,7 @@ final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForw
26392639
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
26402640
+ r.activityInfo.name + " with newConfig " + r.newConfig);
26412641
performConfigurationChanged(r.activity, r.newConfig);
2642+
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
26422643
r.newConfig = null;
26432644
}
26442645
if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
@@ -2955,6 +2956,7 @@ private void updateVisibility(ActivityClientRecord r, boolean show) {
29552956
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
29562957
+ r.activityInfo.name + " with new config " + r.newConfig);
29572958
performConfigurationChanged(r.activity, r.newConfig);
2959+
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
29582960
r.newConfig = null;
29592961
}
29602962
} else {
@@ -3669,6 +3671,7 @@ final Configuration applyCompatConfiguration() {
36693671
final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
36703672

36713673
ArrayList<ComponentCallbacks2> callbacks = null;
3674+
int configDiff = 0;
36723675

36733676
synchronized (mPackages) {
36743677
if (mPendingConfiguration != null) {
@@ -3693,6 +3696,7 @@ final void handleConfigurationChanged(Configuration config, CompatibilityInfo co
36933696
if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
36943697
return;
36953698
}
3699+
configDiff = mConfiguration.diff(config);
36963700
mConfiguration.updateFrom(config);
36973701
config = applyCompatConfiguration();
36983702
callbacks = collectComponentCallbacksLocked(false, config);
@@ -3701,6 +3705,8 @@ final void handleConfigurationChanged(Configuration config, CompatibilityInfo co
37013705
// Cleanup hardware accelerated stuff
37023706
WindowManagerImpl.getDefault().trimLocalMemory();
37033707

3708+
freeTextLayoutCachesIfNeeded(configDiff);
3709+
37043710
if (callbacks != null) {
37053711
final int N = callbacks.size();
37063712
for (int i=0; i<N; i++) {
@@ -3709,6 +3715,17 @@ final void handleConfigurationChanged(Configuration config, CompatibilityInfo co
37093715
}
37103716
}
37113717

3718+
final void freeTextLayoutCachesIfNeeded(int configDiff) {
3719+
if (configDiff != 0) {
3720+
// Ask text layout engine to free its caches if there is a locale change
3721+
boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
3722+
if (hasLocaleConfigChange) {
3723+
Canvas.freeTextLayoutCaches();
3724+
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
3725+
}
3726+
}
3727+
}
3728+
37123729
final void handleActivityConfigurationChanged(IBinder token) {
37133730
ActivityClientRecord r = mActivities.get(token);
37143731
if (r == null || r.activity == null) {
@@ -3719,6 +3736,8 @@ final void handleActivityConfigurationChanged(IBinder token) {
37193736
+ r.activityInfo.name);
37203737

37213738
performConfigurationChanged(r.activity, mCompatConfiguration);
3739+
3740+
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
37223741
}
37233742

37243743
final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
@@ -3821,6 +3840,9 @@ final void handleLowMemory() {
38213840
// Ask graphics to free up as much as possible (font/image caches)
38223841
Canvas.freeCaches();
38233842

3843+
// Ask text layout engine to free also as much as possible
3844+
Canvas.freeTextLayoutCaches();
3845+
38243846
BinderInternal.forceGc("mem");
38253847
}
38263848

core/jni/android/graphics/Canvas.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ class SkCanvasGlue {
6969
SkImageRef_GlobalPool::SetRAMUsed(0);
7070
SkGraphics::PurgeFontCache();
7171
}
72-
72+
73+
static void freeTextLayoutCaches(JNIEnv* env, jobject) {
74+
TextLayoutEngine::getInstance().purgeCaches();
75+
}
76+
7377
static jboolean isOpaque(JNIEnv* env, jobject jcanvas) {
7478
NPE_CHECK_RETURN_ZERO(env, jcanvas);
7579
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
@@ -986,7 +990,9 @@ static JNINativeMethod gCanvasMethods[] = {
986990
(void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
987991
{"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture},
988992

989-
{"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}
993+
{"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches},
994+
995+
{"freeTextLayoutCaches", "()V", (void*) SkCanvasGlue::freeTextLayoutCaches}
990996
};
991997

992998
///////////////////////////////////////////////////////////////////////////////

core/jni/android/graphics/TextLayoutCache.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,4 +991,11 @@ sp<TextLayoutValue> TextLayoutEngine::getValue(const SkPaint* paint, const jchar
991991
return value;
992992
}
993993

994+
void TextLayoutEngine::purgeCaches() {
995+
#if USE_TEXT_LAYOUT_CACHE
996+
mTextLayoutCache->clear();
997+
#endif
998+
}
999+
1000+
9941001
} // namespace android

core/jni/android/graphics/TextLayoutCache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ class TextLayoutEngine : public Singleton<TextLayoutEngine> {
309309

310310
sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
311311
jint count, jint contextCount, jint dirFlags);
312+
313+
void purgeCaches();
314+
312315
private:
313316
TextLayoutCache* mTextLayoutCache;
314317
TextLayoutShaper* mShaper;

graphics/java/android/graphics/Canvas.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,6 +1617,13 @@ public void drawPicture(Picture picture, Rect dst) {
16171617
*/
16181618
public static native void freeCaches();
16191619

1620+
/**
1621+
* Free up text layout caches
1622+
*
1623+
* @hide
1624+
*/
1625+
public static native void freeTextLayoutCaches();
1626+
16201627
private static native int initRaster(int nativeBitmapOrZero);
16211628
private static native void native_setBitmap(int nativeCanvas, int bitmap);
16221629
private static native int native_saveLayer(int nativeCanvas, RectF bounds,

0 commit comments

Comments
 (0)