mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1057086: Improve type safety in UIAsyncTask r=nalexander
--HG-- rename : mobile/android/base/util/UiAsyncTask.java => mobile/android/base/util/UIAsyncTask.java
This commit is contained in:
parent
915d568b45
commit
b72133e63f
@ -71,7 +71,7 @@ import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.util.PrefUtils;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
import org.mozilla.gecko.widget.ButtonToast;
|
||||
import org.mozilla.gecko.widget.GeckoActionProvider;
|
||||
|
||||
@ -439,9 +439,9 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
|
||||
private void handleReaderFaviconRequest(final String url) {
|
||||
(new UiAsyncTask<Void, Void, String>(ThreadUtils.getBackgroundHandler()) {
|
||||
(new UIAsyncTask.WithoutParams<String>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public String doInBackground(Void... params) {
|
||||
public String doInBackground() {
|
||||
return Favicons.getFaviconURLForPageURL(url);
|
||||
}
|
||||
|
||||
@ -2847,9 +2847,9 @@ public class BrowserApp extends GeckoApp
|
||||
return;
|
||||
}
|
||||
|
||||
(new UiAsyncTask<Void, Void, Boolean>(ThreadUtils.getBackgroundHandler()) {
|
||||
(new UIAsyncTask.WithoutParams<Boolean>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public synchronized Boolean doInBackground(Void... params) {
|
||||
public synchronized Boolean doInBackground() {
|
||||
// Check to see how many times the app has been launched.
|
||||
SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE);
|
||||
String keyName = getPackageName() + ".feedback_launch_count";
|
||||
@ -2891,9 +2891,9 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
|
||||
private void getLastUrl() {
|
||||
(new UiAsyncTask<Void, Void, String>(ThreadUtils.getBackgroundHandler()) {
|
||||
(new UIAsyncTask.WithoutParams<String>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public synchronized String doInBackground(Void... params) {
|
||||
public synchronized String doInBackground() {
|
||||
// Get the most recent URL stored in browser history.
|
||||
String url = "";
|
||||
Cursor c = null;
|
||||
|
@ -8,7 +8,7 @@ package org.mozilla.gecko;
|
||||
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
@ -141,9 +141,9 @@ public class EditBookmarkDialog {
|
||||
*/
|
||||
public void show(final String url) {
|
||||
final ContentResolver cr = mContext.getContentResolver();
|
||||
(new UiAsyncTask<Void, Void, Bookmark>(ThreadUtils.getBackgroundHandler()) {
|
||||
(new UIAsyncTask.WithoutParams<Bookmark>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public Bookmark doInBackground(Void... params) {
|
||||
public Bookmark doInBackground() {
|
||||
final Cursor cursor = BrowserDB.getBookmarkForUrl(cr, url);
|
||||
if (cursor == null) {
|
||||
return null;
|
||||
@ -202,9 +202,9 @@ public class EditBookmarkDialog {
|
||||
editPrompt.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
(new UiAsyncTask<Void, Void, Void>(ThreadUtils.getBackgroundHandler()) {
|
||||
(new UIAsyncTask.WithoutParams<Void>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public Void doInBackground(Void... params) {
|
||||
public Void doInBackground() {
|
||||
String newUrl = locationText.getText().toString().trim();
|
||||
String newKeyword = keywordText.getText().toString().trim();
|
||||
BrowserDB.updateBookmark(context.getContentResolver(), id, newUrl, nameText.getText().toString(), newKeyword);
|
||||
|
@ -15,7 +15,7 @@ import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
@ -56,9 +56,9 @@ public class GeckoAccessibility {
|
||||
}));
|
||||
|
||||
public static void updateAccessibilitySettings (final Context context) {
|
||||
new UiAsyncTask<Void, Void, Void>(ThreadUtils.getBackgroundHandler()) {
|
||||
new UIAsyncTask.WithoutParams<Void>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public Void doInBackground(Void... args) {
|
||||
public Void doInBackground() {
|
||||
JSONObject ret = new JSONObject();
|
||||
sEnabled = false;
|
||||
AccessibilityManager accessibilityManager =
|
||||
|
@ -6,7 +6,7 @@ package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
@ -82,9 +82,9 @@ public final class TabsAccessor {
|
||||
if (listener == null)
|
||||
return;
|
||||
|
||||
(new UiAsyncTask<Void, Void, List<RemoteTab>>(ThreadUtils.getBackgroundHandler()) {
|
||||
(new UIAsyncTask.WithoutParams<List<RemoteTab>>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
protected List<RemoteTab> doInBackground(Void... unused) {
|
||||
protected List<RemoteTab> doInBackground() {
|
||||
Uri uri = BrowserContract.Tabs.CONTENT_URI;
|
||||
|
||||
if (limit > 0) {
|
||||
|
@ -20,7 +20,7 @@ import org.mozilla.gecko.favicons.decoders.FaviconDecoder;
|
||||
import org.mozilla.gecko.favicons.decoders.LoadFaviconResult;
|
||||
import org.mozilla.gecko.util.GeckoJarReader;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
|
||||
import static org.mozilla.gecko.favicons.Favicons.context;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -14,7 +14,7 @@ import java.net.URL;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.GeckoJarReader;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
import org.mozilla.gecko.ThumbnailHelper;
|
||||
@ -80,9 +80,9 @@ public final class BitmapUtils {
|
||||
}
|
||||
|
||||
if (data.startsWith("jar:") || data.startsWith("file://")) {
|
||||
(new UiAsyncTask<Void, Void, Drawable>(ThreadUtils.getBackgroundHandler()) {
|
||||
(new UIAsyncTask.WithoutParams<Drawable>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public Drawable doInBackground(Void... params) {
|
||||
public Drawable doInBackground() {
|
||||
try {
|
||||
if (data.startsWith("jar:jar")) {
|
||||
return GeckoJarReader.getBitmapDrawable(context.getResources(), data);
|
||||
|
@ -12,7 +12,7 @@ import org.mozilla.gecko.home.PanelLayout.ContextMenuRegistry;
|
||||
import org.mozilla.gecko.home.PanelLayout.DatasetHandler;
|
||||
import org.mozilla.gecko.home.PanelLayout.DatasetRequest;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
@ -70,7 +70,7 @@ public class DynamicPanel extends HomeFragment {
|
||||
|
||||
// Hold a reference to the UiAsyncTask we use to check the state of the
|
||||
// PanelAuthCache, so that we can cancel it if necessary.
|
||||
private UiAsyncTask<Void, Void, Boolean> mAuthStateTask;
|
||||
private UIAsyncTask.WithoutParams<Boolean> mAuthStateTask;
|
||||
|
||||
// The configuration associated with this panel
|
||||
private PanelConfig mPanelConfig;
|
||||
@ -137,7 +137,7 @@ public class DynamicPanel extends HomeFragment {
|
||||
mPanelAuthCache.setOnChangeListener(null);
|
||||
|
||||
if (mAuthStateTask != null) {
|
||||
mAuthStateTask.cancel(true);
|
||||
mAuthStateTask.cancel();
|
||||
mAuthStateTask = null;
|
||||
}
|
||||
}
|
||||
@ -156,9 +156,9 @@ public class DynamicPanel extends HomeFragment {
|
||||
Log.d(LOGTAG, "Loading layout");
|
||||
|
||||
if (requiresAuth()) {
|
||||
mAuthStateTask = new UiAsyncTask<Void, Void, Boolean>(ThreadUtils.getBackgroundHandler()) {
|
||||
mAuthStateTask = new UIAsyncTask.WithoutParams<Boolean>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public synchronized Boolean doInBackground(Void... params) {
|
||||
public synchronized Boolean doInBackground() {
|
||||
return mPanelAuthCache.isAuthenticated(mPanelConfig.getId());
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ import org.mozilla.gecko.home.TopSitesGridView.TopSitesGridContextMenuInfo;
|
||||
import org.mozilla.gecko.util.Clipboard;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
import org.mozilla.gecko.widget.ButtonToast;
|
||||
|
||||
import android.app.Activity;
|
||||
@ -332,7 +332,7 @@ abstract class HomeFragment extends Fragment {
|
||||
mIsLoaded = true;
|
||||
}
|
||||
|
||||
private static class RemoveItemByUrlTask extends UiAsyncTask<Void, Void, Void> {
|
||||
private static class RemoveItemByUrlTask extends UIAsyncTask.WithoutParams<Void> {
|
||||
private final Context mContext;
|
||||
private final String mUrl;
|
||||
private final int mPosition;
|
||||
@ -357,7 +357,7 @@ abstract class HomeFragment extends Fragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void doInBackground(Void... params) {
|
||||
public Void doInBackground() {
|
||||
ContentResolver cr = mContext.getContentResolver();
|
||||
|
||||
if (mPosition > -1) {
|
||||
|
@ -5,27 +5,15 @@
|
||||
|
||||
package org.mozilla.gecko.home;
|
||||
|
||||
import com.squareup.picasso.Picasso;
|
||||
import com.squareup.picasso.Callback;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract.TopSites;
|
||||
import org.mozilla.gecko.db.URLMetadata;
|
||||
import org.mozilla.gecko.favicons.Favicons;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContentResolver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
@ -78,7 +78,7 @@ gujar.sources += [
|
||||
'util/RawResource.java',
|
||||
'util/StringUtils.java',
|
||||
'util/ThreadUtils.java',
|
||||
'util/UiAsyncTask.java',
|
||||
'util/UIAsyncTask.java',
|
||||
'util/WebActivityMapper.java',
|
||||
]
|
||||
gujar.extra_jars = [
|
||||
|
@ -11,7 +11,7 @@ import org.mozilla.gecko.home.HomeConfig;
|
||||
import org.mozilla.gecko.home.HomeConfig.PanelConfig;
|
||||
import org.mozilla.gecko.home.HomeConfig.State;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
@ -23,7 +23,7 @@ public class PanelsPreferenceCategory extends CustomListCategory {
|
||||
protected HomeConfig mHomeConfig;
|
||||
protected HomeConfig.Editor mConfigEditor;
|
||||
|
||||
protected UiAsyncTask<Void, Void, HomeConfig.State> mLoadTask;
|
||||
protected UIAsyncTask.WithoutParams<State> mLoadTask;
|
||||
|
||||
public PanelsPreferenceCategory(Context context) {
|
||||
super(context);
|
||||
@ -55,9 +55,9 @@ public class PanelsPreferenceCategory extends CustomListCategory {
|
||||
* Load the Home Panels config and populate the preferences screen and maintain local state.
|
||||
*/
|
||||
private void loadHomeConfig(final String animatePanelId) {
|
||||
mLoadTask = new UiAsyncTask<Void, Void, HomeConfig.State>(ThreadUtils.getBackgroundHandler()) {
|
||||
mLoadTask = new UIAsyncTask.WithoutParams<State>(ThreadUtils.getBackgroundHandler()) {
|
||||
@Override
|
||||
public HomeConfig.State doInBackground(Void... params) {
|
||||
public HomeConfig.State doInBackground() {
|
||||
return mHomeConfig.load();
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ public class PanelsPreferenceCategory extends CustomListCategory {
|
||||
@Override
|
||||
protected void onPrepareForRemoval() {
|
||||
if (mLoadTask != null) {
|
||||
mLoadTask.cancel(true);
|
||||
mLoadTask.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,44 @@ import android.os.Looper;
|
||||
* The standard {@link android.os.AsyncTask} only runs onPostExecute on the
|
||||
* thread it is constructed on, so this is a convenience class for creating
|
||||
* tasks off the UI thread.
|
||||
*
|
||||
* We use generics differently to Android's AsyncTask.
|
||||
* Android uses a "Params" type parameter to represent the type of all the parameters to this task.
|
||||
* It then uses arguments of type Params... to permit arbitrarily-many of these to be passed
|
||||
* fluently.
|
||||
*
|
||||
* Unfortunately, since Java does not support generic array types (and since varargs desugars to a
|
||||
* single array parameter) that behaviour exposes a hole in the type system. See:
|
||||
* http://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html#vulnerabilities
|
||||
*
|
||||
* Instead, we equivalently have a single type parameter "Param". A UiAsyncTask may take exactly one
|
||||
* parameter of type Param. Since Param can be an array type, this no more restrictive than the
|
||||
* other approach, it just provides additional type safety.
|
||||
*/
|
||||
public abstract class UiAsyncTask<Params, Progress, Result> {
|
||||
private volatile boolean mCancelled;
|
||||
public abstract class UIAsyncTask<Param, Result> {
|
||||
/**
|
||||
* Provide a convenient API for parameter-free UiAsyncTasks by wrapping parameter-taking methods
|
||||
* from UiAsyncTask in parameterless equivalents.
|
||||
*/
|
||||
public static abstract class WithoutParams<InnerResult> extends UIAsyncTask<Void, InnerResult> {
|
||||
public WithoutParams(Handler backgroundThreadHandler) {
|
||||
super(backgroundThreadHandler);
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
execute(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InnerResult doInBackground(Void unused) {
|
||||
return doInBackground();
|
||||
}
|
||||
|
||||
protected abstract InnerResult doInBackground();
|
||||
}
|
||||
|
||||
/* inner-access */ final Handler mBackgroundThreadHandler;
|
||||
private volatile boolean mCancelled;
|
||||
private static Handler sHandler;
|
||||
|
||||
/**
|
||||
@ -25,7 +59,7 @@ public abstract class UiAsyncTask<Params, Progress, Result> {
|
||||
*
|
||||
* @param backgroundThreadHandler the handler to execute the background task on
|
||||
*/
|
||||
public UiAsyncTask(Handler backgroundThreadHandler) {
|
||||
public UIAsyncTask(Handler backgroundThreadHandler) {
|
||||
mBackgroundThreadHandler = backgroundThreadHandler;
|
||||
}
|
||||
|
||||
@ -33,44 +67,45 @@ public abstract class UiAsyncTask<Params, Progress, Result> {
|
||||
if (sHandler == null) {
|
||||
sHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
return sHandler;
|
||||
}
|
||||
|
||||
private final class BackgroundTaskRunnable implements Runnable {
|
||||
private Params[] mParams;
|
||||
private Param mParam;
|
||||
|
||||
public BackgroundTaskRunnable(Params... params) {
|
||||
mParams = params;
|
||||
public BackgroundTaskRunnable(Param param) {
|
||||
mParam = param;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final Result result = doInBackground(mParams);
|
||||
final Result result = doInBackground(mParam);
|
||||
|
||||
getUiHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mCancelled)
|
||||
if (mCancelled) {
|
||||
onCancelled();
|
||||
else
|
||||
} else {
|
||||
onPostExecute(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public final void execute(final Params... params) {
|
||||
protected void execute(final Param param) {
|
||||
getUiHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onPreExecute();
|
||||
mBackgroundThreadHandler.post(new BackgroundTaskRunnable(params));
|
||||
mBackgroundThreadHandler.post(new BackgroundTaskRunnable(param));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedParameters"})
|
||||
public final boolean cancel(boolean mayInterruptIfRunning) {
|
||||
public final boolean cancel() {
|
||||
mCancelled = true;
|
||||
return mCancelled;
|
||||
}
|
||||
@ -82,5 +117,5 @@ public abstract class UiAsyncTask<Params, Progress, Result> {
|
||||
protected void onPreExecute() { }
|
||||
protected void onPostExecute(Result result) { }
|
||||
protected void onCancelled() { }
|
||||
protected abstract Result doInBackground(Params... params);
|
||||
protected abstract Result doInBackground(Param param);
|
||||
}
|
Loading…
Reference in New Issue
Block a user