Loading java/src/com/android/inputmethod/dictionarypack/ActionBatch.java +4 −17 Original line number Diff line number Diff line Loading @@ -117,16 +117,11 @@ public final class ActionBatch { final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); final int status = values.getAsInteger(MetadataDbHelper.STATUS_COLUMN); final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); if (MetadataDbHelper.STATUS_DOWNLOADING == status) { // The word list is still downloading. Cancel the download and revert the // word list status to "available". if (null != manager) { // DownloadManager is disabled (or not installed?). We can't cancel - there // is nothing we can do. We still need to mark the entry as available. manager.remove(values.getAsLong(MetadataDbHelper.PENDINGID_COLUMN)); } MetadataDbHelper.markEntryAsAvailable(db, mWordList.mId, mWordList.mVersion); } else if (MetadataDbHelper.STATUS_AVAILABLE != status) { // Should never happen Loading @@ -136,9 +131,6 @@ public final class ActionBatch { // Download it. DebugLogUtils.l("Upgrade word list, downloading", mWordList.mRemoteFilename); // TODO: if DownloadManager is disabled or not installed, download by ourselves if (null == manager) return; // This is an upgraded word list: we should download it. // Adding a disambiguator to circumvent a bug in older versions of DownloadManager. // DownloadManager also stupidly cuts the extension to replace with its own that it Loading Loading @@ -293,13 +285,8 @@ public final class ActionBatch { } // The word list is still downloading. Cancel the download and revert the // word list status to "available". final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); if (null != manager) { // If we can't cancel the download because DownloadManager is not available, // we still need to mark the entry as available. final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); manager.remove(values.getAsLong(MetadataDbHelper.PENDINGID_COLUMN)); } MetadataDbHelper.markEntryAsAvailable(db, mWordList.mId, mWordList.mVersion); } } Loading java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java +3 −7 Original line number Diff line number Diff line Loading @@ -107,26 +107,22 @@ public class DictionaryDownloadProgressBar extends ProgressBar { private class UpdaterThread extends Thread { private final static int REPORT_PERIOD = 150; // how often to report progress, in ms final DownloadManager mDownloadManager; final DownloadManagerWrapper mDownloadManagerWrapper; final int mId; public UpdaterThread(final Context context, final int id) { super(); mDownloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); mDownloadManagerWrapper = new DownloadManagerWrapper(context); mId = id; } @Override public void run() { try { // It's almost impossible that mDownloadManager is null (it would mean it has been // disabled between pressing the 'install' button and displaying the progress // bar), but just in case. if (null == mDownloadManager) return; final UpdateHelper updateHelper = new UpdateHelper(); final Query query = new Query().setFilterById(mId); int lastProgress = 0; setIndeterminate(true); while (!isInterrupted()) { final Cursor cursor = mDownloadManager.query(query); final Cursor cursor = mDownloadManagerWrapper.query(query); if (null == cursor) { // Can't contact DownloadManager: this should never happen. return; Loading java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java 0 → 100644 +99 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 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.dictionarypack; import android.app.DownloadManager; import android.app.DownloadManager.Query; import android.app.DownloadManager.Request; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.os.ParcelFileDescriptor; import android.util.Log; import java.io.FileNotFoundException; /** * A class to help with calling DownloadManager methods. * * Mostly, the problem here is that most methods from DownloadManager may throw SQL exceptions if * they can't open the database on disk. We want to avoid crashing in these cases but can't do * much more, so this class insulates the callers from these. SQLiteException also inherit from * RuntimeException so they are unchecked :( * While we're at it, we also insulate callers from the cases where DownloadManager is disabled, * and getSystemService returns null. */ public class DownloadManagerWrapper { private final static String TAG = DownloadManagerWrapper.class.getSimpleName(); private final DownloadManager mDownloadManager; public DownloadManagerWrapper(final Context context) { this((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)); } private DownloadManagerWrapper(final DownloadManager downloadManager) { mDownloadManager = downloadManager; } public void remove(final long... ids) { try { if (null != mDownloadManager) { mDownloadManager.remove(ids); } } catch (SQLiteException e) { // We couldn't remove the file from DownloadManager. Apparently, the database can't // be opened. It may be a problem with file system corruption. In any case, there is // not much we can do apart from avoiding crashing. Log.e(TAG, "Can't remove files with ID " + ids + " from download manager", e); } } public ParcelFileDescriptor openDownloadedFile(final long fileId) throws FileNotFoundException { try { if (null != mDownloadManager) { return mDownloadManager.openDownloadedFile(fileId); } } catch (SQLiteException e) { Log.e(TAG, "Can't open downloaded file with ID " + fileId, e); } // We come here if mDownloadManager is null or if an exception was thrown. throw new FileNotFoundException(); } public Cursor query(final Query query) { try { if (null != mDownloadManager) { return mDownloadManager.query(query); } } catch (SQLiteException e) { Log.e(TAG, "Can't query the download manager", e); } // We come here if mDownloadManager is null or if an exception was thrown. return null; } public long enqueue(final Request request) { try { if (null != mDownloadManager) { return mDownloadManager.enqueue(request); } } catch (SQLiteException e) { Log.e(TAG, "Can't enqueue a request with the download manager", e); } return 0; } } java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java +12 −20 Original line number Diff line number Diff line Loading @@ -249,13 +249,7 @@ public final class UpdateHandler { metadataRequest.setVisibleInDownloadsUi( res.getBoolean(R.bool.metadata_downloads_visible_in_download_UI)); final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); if (null == manager) { // Download manager is not installed or disabled. // TODO: fall back to self-managed download? return; } final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); cancelUpdateWithDownloadManager(context, metadataUri, manager); final long downloadId; synchronized (sSharedIdProtector) { Loading @@ -278,10 +272,10 @@ public final class UpdateHandler { * * @param context the context to open the database on * @param metadataUri the URI to cancel * @param manager an instance of DownloadManager * @param manager an wrapped instance of DownloadManager */ private static void cancelUpdateWithDownloadManager(final Context context, final String metadataUri, final DownloadManager manager) { final String metadataUri, final DownloadManagerWrapper manager) { synchronized (sSharedIdProtector) { final long metadataDownloadId = MetadataDbHelper.getMetadataDownloadIdForURI(context, metadataUri); Loading @@ -306,10 +300,9 @@ public final class UpdateHandler { * @param clientId the ID of the client we want to cancel the update of */ public static void cancelUpdate(final Context context, final String clientId) { final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); final String metadataUri = MetadataDbHelper.getMetadataUriAsString(context, clientId); if (null != manager) cancelUpdateWithDownloadManager(context, metadataUri, manager); cancelUpdateWithDownloadManager(context, metadataUri, manager); } /** Loading @@ -323,15 +316,15 @@ public final class UpdateHandler { * download request id, which is not known before submitting the request to the download * manager. Hence, it only updates the relevant line. * * @param manager the download manager service to register the request with. * @param manager a wrapped download manager service to register the request with. * @param request the request to register. * @param db the metadata database. * @param id the id of the word list. * @param version the version of the word list. * @return the download id returned by the download manager. */ public static long registerDownloadRequest(final DownloadManager manager, final Request request, final SQLiteDatabase db, final String id, final int version) { public static long registerDownloadRequest(final DownloadManagerWrapper manager, final Request request, final SQLiteDatabase db, final String id, final int version) { DebugLogUtils.l("RegisterDownloadRequest for word list id : ", id, ", version ", version); final long downloadId; synchronized (sSharedIdProtector) { Loading @@ -345,8 +338,8 @@ public final class UpdateHandler { /** * Retrieve information about a specific download from DownloadManager. */ private static CompletedDownloadInfo getCompletedDownloadInfo(final DownloadManager manager, final long downloadId) { private static CompletedDownloadInfo getCompletedDownloadInfo( final DownloadManagerWrapper manager, final long downloadId) { final Query query = new Query().setFilterById(downloadId); final Cursor cursor = manager.query(query); Loading Loading @@ -425,8 +418,7 @@ public final class UpdateHandler { DebugLogUtils.l("DownloadFinished with id", fileId); if (NOT_AN_ID == fileId) return; // Spurious wake-up: ignore final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); final CompletedDownloadInfo downloadInfo = getCompletedDownloadInfo(manager, fileId); final ArrayList<DownloadRecord> recordList = Loading Loading @@ -517,7 +509,7 @@ public final class UpdateHandler { } private static boolean handleDownloadedFile(final Context context, final DownloadRecord downloadRecord, final DownloadManager manager, final DownloadRecord downloadRecord, final DownloadManagerWrapper manager, final long fileId) { try { // {@link handleWordList(Context,InputStream,ContentValues)}. Loading Loading
java/src/com/android/inputmethod/dictionarypack/ActionBatch.java +4 −17 Original line number Diff line number Diff line Loading @@ -117,16 +117,11 @@ public final class ActionBatch { final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); final int status = values.getAsInteger(MetadataDbHelper.STATUS_COLUMN); final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); if (MetadataDbHelper.STATUS_DOWNLOADING == status) { // The word list is still downloading. Cancel the download and revert the // word list status to "available". if (null != manager) { // DownloadManager is disabled (or not installed?). We can't cancel - there // is nothing we can do. We still need to mark the entry as available. manager.remove(values.getAsLong(MetadataDbHelper.PENDINGID_COLUMN)); } MetadataDbHelper.markEntryAsAvailable(db, mWordList.mId, mWordList.mVersion); } else if (MetadataDbHelper.STATUS_AVAILABLE != status) { // Should never happen Loading @@ -136,9 +131,6 @@ public final class ActionBatch { // Download it. DebugLogUtils.l("Upgrade word list, downloading", mWordList.mRemoteFilename); // TODO: if DownloadManager is disabled or not installed, download by ourselves if (null == manager) return; // This is an upgraded word list: we should download it. // Adding a disambiguator to circumvent a bug in older versions of DownloadManager. // DownloadManager also stupidly cuts the extension to replace with its own that it Loading Loading @@ -293,13 +285,8 @@ public final class ActionBatch { } // The word list is still downloading. Cancel the download and revert the // word list status to "available". final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); if (null != manager) { // If we can't cancel the download because DownloadManager is not available, // we still need to mark the entry as available. final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); manager.remove(values.getAsLong(MetadataDbHelper.PENDINGID_COLUMN)); } MetadataDbHelper.markEntryAsAvailable(db, mWordList.mId, mWordList.mVersion); } } Loading
java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java +3 −7 Original line number Diff line number Diff line Loading @@ -107,26 +107,22 @@ public class DictionaryDownloadProgressBar extends ProgressBar { private class UpdaterThread extends Thread { private final static int REPORT_PERIOD = 150; // how often to report progress, in ms final DownloadManager mDownloadManager; final DownloadManagerWrapper mDownloadManagerWrapper; final int mId; public UpdaterThread(final Context context, final int id) { super(); mDownloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); mDownloadManagerWrapper = new DownloadManagerWrapper(context); mId = id; } @Override public void run() { try { // It's almost impossible that mDownloadManager is null (it would mean it has been // disabled between pressing the 'install' button and displaying the progress // bar), but just in case. if (null == mDownloadManager) return; final UpdateHelper updateHelper = new UpdateHelper(); final Query query = new Query().setFilterById(mId); int lastProgress = 0; setIndeterminate(true); while (!isInterrupted()) { final Cursor cursor = mDownloadManager.query(query); final Cursor cursor = mDownloadManagerWrapper.query(query); if (null == cursor) { // Can't contact DownloadManager: this should never happen. return; Loading
java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java 0 → 100644 +99 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 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.dictionarypack; import android.app.DownloadManager; import android.app.DownloadManager.Query; import android.app.DownloadManager.Request; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.os.ParcelFileDescriptor; import android.util.Log; import java.io.FileNotFoundException; /** * A class to help with calling DownloadManager methods. * * Mostly, the problem here is that most methods from DownloadManager may throw SQL exceptions if * they can't open the database on disk. We want to avoid crashing in these cases but can't do * much more, so this class insulates the callers from these. SQLiteException also inherit from * RuntimeException so they are unchecked :( * While we're at it, we also insulate callers from the cases where DownloadManager is disabled, * and getSystemService returns null. */ public class DownloadManagerWrapper { private final static String TAG = DownloadManagerWrapper.class.getSimpleName(); private final DownloadManager mDownloadManager; public DownloadManagerWrapper(final Context context) { this((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)); } private DownloadManagerWrapper(final DownloadManager downloadManager) { mDownloadManager = downloadManager; } public void remove(final long... ids) { try { if (null != mDownloadManager) { mDownloadManager.remove(ids); } } catch (SQLiteException e) { // We couldn't remove the file from DownloadManager. Apparently, the database can't // be opened. It may be a problem with file system corruption. In any case, there is // not much we can do apart from avoiding crashing. Log.e(TAG, "Can't remove files with ID " + ids + " from download manager", e); } } public ParcelFileDescriptor openDownloadedFile(final long fileId) throws FileNotFoundException { try { if (null != mDownloadManager) { return mDownloadManager.openDownloadedFile(fileId); } } catch (SQLiteException e) { Log.e(TAG, "Can't open downloaded file with ID " + fileId, e); } // We come here if mDownloadManager is null or if an exception was thrown. throw new FileNotFoundException(); } public Cursor query(final Query query) { try { if (null != mDownloadManager) { return mDownloadManager.query(query); } } catch (SQLiteException e) { Log.e(TAG, "Can't query the download manager", e); } // We come here if mDownloadManager is null or if an exception was thrown. return null; } public long enqueue(final Request request) { try { if (null != mDownloadManager) { return mDownloadManager.enqueue(request); } } catch (SQLiteException e) { Log.e(TAG, "Can't enqueue a request with the download manager", e); } return 0; } }
java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java +12 −20 Original line number Diff line number Diff line Loading @@ -249,13 +249,7 @@ public final class UpdateHandler { metadataRequest.setVisibleInDownloadsUi( res.getBoolean(R.bool.metadata_downloads_visible_in_download_UI)); final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); if (null == manager) { // Download manager is not installed or disabled. // TODO: fall back to self-managed download? return; } final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); cancelUpdateWithDownloadManager(context, metadataUri, manager); final long downloadId; synchronized (sSharedIdProtector) { Loading @@ -278,10 +272,10 @@ public final class UpdateHandler { * * @param context the context to open the database on * @param metadataUri the URI to cancel * @param manager an instance of DownloadManager * @param manager an wrapped instance of DownloadManager */ private static void cancelUpdateWithDownloadManager(final Context context, final String metadataUri, final DownloadManager manager) { final String metadataUri, final DownloadManagerWrapper manager) { synchronized (sSharedIdProtector) { final long metadataDownloadId = MetadataDbHelper.getMetadataDownloadIdForURI(context, metadataUri); Loading @@ -306,10 +300,9 @@ public final class UpdateHandler { * @param clientId the ID of the client we want to cancel the update of */ public static void cancelUpdate(final Context context, final String clientId) { final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); final String metadataUri = MetadataDbHelper.getMetadataUriAsString(context, clientId); if (null != manager) cancelUpdateWithDownloadManager(context, metadataUri, manager); cancelUpdateWithDownloadManager(context, metadataUri, manager); } /** Loading @@ -323,15 +316,15 @@ public final class UpdateHandler { * download request id, which is not known before submitting the request to the download * manager. Hence, it only updates the relevant line. * * @param manager the download manager service to register the request with. * @param manager a wrapped download manager service to register the request with. * @param request the request to register. * @param db the metadata database. * @param id the id of the word list. * @param version the version of the word list. * @return the download id returned by the download manager. */ public static long registerDownloadRequest(final DownloadManager manager, final Request request, final SQLiteDatabase db, final String id, final int version) { public static long registerDownloadRequest(final DownloadManagerWrapper manager, final Request request, final SQLiteDatabase db, final String id, final int version) { DebugLogUtils.l("RegisterDownloadRequest for word list id : ", id, ", version ", version); final long downloadId; synchronized (sSharedIdProtector) { Loading @@ -345,8 +338,8 @@ public final class UpdateHandler { /** * Retrieve information about a specific download from DownloadManager. */ private static CompletedDownloadInfo getCompletedDownloadInfo(final DownloadManager manager, final long downloadId) { private static CompletedDownloadInfo getCompletedDownloadInfo( final DownloadManagerWrapper manager, final long downloadId) { final Query query = new Query().setFilterById(downloadId); final Cursor cursor = manager.query(query); Loading Loading @@ -425,8 +418,7 @@ public final class UpdateHandler { DebugLogUtils.l("DownloadFinished with id", fileId); if (NOT_AN_ID == fileId) return; // Spurious wake-up: ignore final DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); final CompletedDownloadInfo downloadInfo = getCompletedDownloadInfo(manager, fileId); final ArrayList<DownloadRecord> recordList = Loading Loading @@ -517,7 +509,7 @@ public final class UpdateHandler { } private static boolean handleDownloadedFile(final Context context, final DownloadRecord downloadRecord, final DownloadManager manager, final DownloadRecord downloadRecord, final DownloadManagerWrapper manager, final long fileId) { try { // {@link handleWordList(Context,InputStream,ContentValues)}. Loading