am 7058b02a: Extract a new class for app-specific workarounds.

* commit '7058b02a9c798c21b169b778be2befc7739f4e9b':
  Extract a new class for app-specific workarounds.
This commit is contained in:
Jean Chalard 2013-05-20 19:49:25 -07:00 committed by Android Git Automerger
commit 5906b05bb5
4 changed files with 88 additions and 40 deletions

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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());
}

View File

@ -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<String, Void, ApplicationInfo> {
public final class TargetPackageInfoGetterTask extends
AsyncTask<String, Void, PackageInfo> {
private static final int MAX_CACHE_ENTRIES = 64; // arbitrary
private static LruCache<String, ApplicationInfo> sCache =
new LruCache<String, ApplicationInfo>(MAX_CACHE_ENTRIES);
private static final LruCache<String, PackageInfo> sCache =
new LruCache<String, PackageInfo>(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);
}
}