From 7058b02a9c798c21b169b778be2befc7739f4e9b Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 15 May 2013 16:49:15 +0900 Subject: [PATCH] Extract a new class for app-specific workarounds. Bug: 8944307 Change-Id: Iaff9dd03d3d856a6bdaa2b16c4e71e95cd2b6349 --- .../compat/AppWorkaroundsUtils.java | 53 +++++++++++++++++++ ...ictionaryPackInstallBroadcastReceiver.java | 2 +- .../android/inputmethod/latin/LatinIME.java | 37 ++++++------- ....java => TargetPackageInfoGetterTask.java} | 36 ++++++------- 4 files changed, 88 insertions(+), 40 deletions(-) create mode 100644 java/src/com/android/inputmethod/compat/AppWorkaroundsUtils.java rename java/src/com/android/inputmethod/latin/{TargetApplicationGetter.java => TargetPackageInfoGetterTask.java} (54%) diff --git a/java/src/com/android/inputmethod/compat/AppWorkaroundsUtils.java b/java/src/com/android/inputmethod/compat/AppWorkaroundsUtils.java new file mode 100644 index 000000000..5594ccba5 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/AppWorkaroundsUtils.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.compat; + +import android.content.pm.PackageInfo; +import android.os.Build.VERSION_CODES; + +/** + * A class to encapsulate work-arounds specific to particular apps. + */ +public class AppWorkaroundsUtils { + private PackageInfo mPackageInfo; // May be null + + public void setPackageInfo(final PackageInfo packageInfo) { + mPackageInfo = packageInfo; + } + + public boolean isBeforeJellyBean() { + if (null == mPackageInfo || null == mPackageInfo.applicationInfo) { + return false; + } + return mPackageInfo.applicationInfo.targetSdkVersion < VERSION_CODES.JELLY_BEAN; + } + + @Override + public String toString() { + if (null == mPackageInfo || null == mPackageInfo.applicationInfo) { + return ""; + } + final StringBuilder s = new StringBuilder(); + s.append("Target application : ") + .append(mPackageInfo.applicationInfo.name) + .append("\nPackage : ") + .append(mPackageInfo.applicationInfo.packageName) + .append("\nTarget app sdk version : ") + .append(mPackageInfo.applicationInfo.targetSdkVersion); + return s.toString(); + } +} diff --git a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java index 41fcb83e6..56096127e 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java +++ b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java @@ -75,7 +75,7 @@ public final class DictionaryPackInstallBroadcastReceiver extends BroadcastRecei final String packageName = packageUri.getSchemeSpecificPart(); if (null == packageName) return; // TODO: do this in a more appropriate place - TargetApplicationGetter.removeApplicationInfoCache(packageName); + TargetPackageInfoGetterTask.removeCachedPackageInfo(packageName); final PackageInfo packageInfo; try { packageInfo = manager.getPackageInfo(packageName, PackageManager.GET_PROVIDERS); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 347a4c63a..93495956d 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -28,14 +28,13 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.net.ConnectivityManager; -import android.os.Build.VERSION_CODES; import android.os.Debug; import android.os.Handler; import android.os.HandlerThread; @@ -64,6 +63,7 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.annotations.UsedForTesting; +import com.android.inputmethod.compat.AppWorkaroundsUtils; import com.android.inputmethod.compat.InputMethodServiceCompatUtils; import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.dictionarypack.DictionaryPackConstants; @@ -91,7 +91,7 @@ import java.util.TreeSet; * Input method implementation for Qwerty'ish keyboard. */ public class LatinIME extends InputMethodService implements KeyboardActionListener, - SuggestionStripView.Listener, TargetApplicationGetter.OnTargetApplicationKnownListener, + SuggestionStripView.Listener, TargetPackageInfoGetterTask.OnTargetPackageInfoKnownListener, Suggest.SuggestInitializationListener { private static final String TAG = LatinIME.class.getSimpleName(); private static final boolean TRACE = false; @@ -141,7 +141,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY; @UsedForTesting Suggest mSuggest; private CompletionInfo[] mApplicationSpecifiedCompletions; - private ApplicationInfo mTargetApplicationInfo; + private AppWorkaroundsUtils mAppWorkAroundsUtils = new AppWorkaroundsUtils(); private RichInputMethodManager mRichImm; @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; @@ -711,10 +711,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead"); } - mTargetApplicationInfo = - TargetApplicationGetter.getCachedApplicationInfo(editorInfo.packageName); - if (null == mTargetApplicationInfo) { - new TargetApplicationGetter(this /* context */, this /* listener */) + final PackageInfo packageInfo = + TargetPackageInfoGetterTask.getCachedPackageInfo(editorInfo.packageName); + mAppWorkAroundsUtils.setPackageInfo(packageInfo); + if (null == packageInfo) { + new TargetPackageInfoGetterTask(this /* context */, this /* listener */) .execute(editorInfo.packageName); } @@ -819,10 +820,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } - // Callback for the TargetApplicationGetter + // Callback for the TargetPackageInfoGetterTask @Override - public void onTargetApplicationKnown(final ApplicationInfo info) { - mTargetApplicationInfo = info; + public void onTargetPackageInfoKnown(final PackageInfo info) { + mAppWorkAroundsUtils.setPackageInfo(info); } @Override @@ -1369,8 +1370,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } - if (Constants.CODE_ENTER == code && mTargetApplicationInfo != null - && mTargetApplicationInfo.targetSdkVersion < VERSION_CODES.JELLY_BEAN) { + if (Constants.CODE_ENTER == code && mAppWorkAroundsUtils.isBeforeJellyBean()) { // Backward compatibility mode. Before Jelly bean, the keyboard would simulate // a hardware keyboard event on pressing enter or delete. This is bad for many // reasons (there are race conditions with commits) but some applications are @@ -1864,8 +1864,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // This should never happen. Log.e(TAG, "Backspace when we don't know the selection position"); } - if (mTargetApplicationInfo != null - && mTargetApplicationInfo.targetSdkVersion < VERSION_CODES.JELLY_BEAN) { + if (mAppWorkAroundsUtils.isBeforeJellyBean()) { // Backward compatibility mode. Before Jelly bean, the keyboard would simulate // a hardware keyboard event on pressing enter or delete. This is bad for many // reasons (there are race conditions with commits) but some applications are @@ -2785,12 +2784,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void debugDumpStateAndCrashWithException(final String context) { - final StringBuilder s = new StringBuilder(); - s.append("Target application : ").append(mTargetApplicationInfo.name) - .append("\nPackage : ").append(mTargetApplicationInfo.packageName) - .append("\nTarget app sdk version : ") - .append(mTargetApplicationInfo.targetSdkVersion) - .append("\nAttributes : ").append(mSettings.getCurrent().mInputAttributes) + final StringBuilder s = new StringBuilder(mAppWorkAroundsUtils.toString()); + s.append("\nAttributes : ").append(mSettings.getCurrent().mInputAttributes) .append("\nContext : ").append(context); throw new RuntimeException(s.toString()); } diff --git a/java/src/com/android/inputmethod/latin/TargetApplicationGetter.java b/java/src/com/android/inputmethod/latin/TargetPackageInfoGetterTask.java similarity index 54% rename from java/src/com/android/inputmethod/latin/TargetApplicationGetter.java rename to java/src/com/android/inputmethod/latin/TargetPackageInfoGetterTask.java index 1ea4ac346..947b0c586 100644 --- a/java/src/com/android/inputmethod/latin/TargetApplicationGetter.java +++ b/java/src/com/android/inputmethod/latin/TargetPackageInfoGetterTask.java @@ -17,54 +17,54 @@ package com.android.inputmethod.latin; import android.content.Context; -import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.AsyncTask; import android.util.LruCache; -public final class TargetApplicationGetter extends AsyncTask { +public final class TargetPackageInfoGetterTask extends + AsyncTask { private static final int MAX_CACHE_ENTRIES = 64; // arbitrary - private static LruCache sCache = - new LruCache(MAX_CACHE_ENTRIES); + private static final LruCache sCache = + new LruCache(MAX_CACHE_ENTRIES); - public static ApplicationInfo getCachedApplicationInfo(final String packageName) { + public static PackageInfo getCachedPackageInfo(final String packageName) { if (null == packageName) return null; return sCache.get(packageName); } - public static void removeApplicationInfoCache(final String packageName) { + public static void removeCachedPackageInfo(final String packageName) { sCache.remove(packageName); } - public interface OnTargetApplicationKnownListener { - public void onTargetApplicationKnown(final ApplicationInfo info); + public interface OnTargetPackageInfoKnownListener { + public void onTargetPackageInfoKnown(final PackageInfo info); } private Context mContext; - private final OnTargetApplicationKnownListener mListener; + private final OnTargetPackageInfoKnownListener mListener; - public TargetApplicationGetter(final Context context, - final OnTargetApplicationKnownListener listener) { + public TargetPackageInfoGetterTask(final Context context, + final OnTargetPackageInfoKnownListener listener) { mContext = context; mListener = listener; } @Override - protected ApplicationInfo doInBackground(final String... packageName) { + protected PackageInfo doInBackground(final String... packageName) { final PackageManager pm = mContext.getPackageManager(); mContext = null; // Bazooka-powered anti-leak device try { - final ApplicationInfo targetAppInfo = - pm.getApplicationInfo(packageName[0], 0 /* flags */); - sCache.put(packageName[0], targetAppInfo); - return targetAppInfo; + final PackageInfo packageInfo = pm.getPackageInfo(packageName[0], 0 /* flags */); + sCache.put(packageName[0], packageInfo); + return packageInfo; } catch (android.content.pm.PackageManager.NameNotFoundException e) { return null; } } @Override - protected void onPostExecute(final ApplicationInfo info) { - mListener.onTargetApplicationKnown(info); + protected void onPostExecute(final PackageInfo info) { + mListener.onTargetPackageInfoKnown(info); } }