[PB12] Implement the progress bar update lifecycle

This ensures the thread does not run uselessly (it is even terminated when
the progress bar exits the screen).

Bug: 7600384
Change-Id: I09117a6f763b574b9b3266f36ba3da4720dc9224
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java
index 39cfb60..a6376a5 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java
@@ -16,11 +16,24 @@
 
 package com.android.inputmethod.dictionarypack;
 
+import android.content.ContentValues;
 import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
 import android.widget.ProgressBar;
 
 public class DictionaryDownloadProgressBar extends ProgressBar {
+    @SuppressWarnings("unused")
+    private static final String TAG = DictionaryDownloadProgressBar.class.getSimpleName();
+    private static final int NOT_A_DOWNLOADMANAGER_PENDING_ID = 0;
+
+    private String mClientId;
+    private String mWordlistId;
+    private boolean mIsCurrentlyAttachedToWindow = false;
+    private Thread mReporterThread = null;
+
     public DictionaryDownloadProgressBar(final Context context) {
         super(context);
     }
@@ -28,4 +41,81 @@
     public DictionaryDownloadProgressBar(final Context context, final AttributeSet attrs) {
         super(context, attrs);
     }
+
+    public void setIds(final String clientId, final String wordlistId) {
+        mClientId = clientId;
+        mWordlistId = wordlistId;
+    }
+
+    static private int getDownloadManagerPendingIdFromWordlistId(final Context context,
+            final String clientId, final String wordlistId) {
+        final SQLiteDatabase db = MetadataDbHelper.getDb(context, clientId);
+        final ContentValues wordlistValues =
+                MetadataDbHelper.getContentValuesOfLatestAvailableWordlistById(db, wordlistId);
+        if (null == wordlistValues) {
+            // We don't know anything about a word list with this id. Bug? This should never
+            // happen, but still return to prevent a crash.
+            Log.e(TAG, "Unexpected word list ID: " + wordlistId);
+            return NOT_A_DOWNLOADMANAGER_PENDING_ID;
+        }
+        return wordlistValues.getAsInteger(MetadataDbHelper.PENDINGID_COLUMN);
+    }
+
+    /*
+     * This method will stop any running updater thread for this progress bar and create and run
+     * a new one only if the progress bar is visible.
+     * Hence, as a result of calling this method, the progress bar will have an updater thread
+     * running if and only if the progress bar is visible.
+     */
+    private void updateReporterThreadRunningStatusAccordingToVisibility() {
+        if (null != mReporterThread) mReporterThread.interrupt();
+        if (mIsCurrentlyAttachedToWindow && View.VISIBLE == getVisibility()) {
+            final int downloadManagerPendingId =
+                    getDownloadManagerPendingIdFromWordlistId(getContext(), mClientId, mWordlistId);
+            if (NOT_A_DOWNLOADMANAGER_PENDING_ID == downloadManagerPendingId) {
+                // Can't get the ID. This is never supposed to happen, but still clear the updater
+                // thread and return to avoid a crash.
+                mReporterThread = null;
+                return;
+            }
+            final UpdaterThread updaterThread = new UpdaterThread(downloadManagerPendingId);
+            updaterThread.start();
+            mReporterThread = updaterThread;
+        } else {
+            // We're not going to restart the thread anyway, so we may as well garbage collect it.
+            mReporterThread = null;
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        mIsCurrentlyAttachedToWindow = true;
+        updateReporterThreadRunningStatusAccordingToVisibility();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        mIsCurrentlyAttachedToWindow = false;
+        updateReporterThreadRunningStatusAccordingToVisibility();
+    }
+
+    private static class UpdaterThread extends Thread {
+        private final static int REPORT_PERIOD = 1000; // how often to report progress
+        final int mId;
+        public UpdaterThread(final int id) {
+            super();
+            mId = id;
+        }
+        @Override
+        public void run() {
+            try {
+                // TODO: implement the actual query and reporting
+                while (!isInterrupted()) {
+                    Thread.sleep(REPORT_PERIOD);
+                }
+            } catch (InterruptedException e) {
+                // Do nothing and terminate normally.
+            }
+        }
+    }
 }
diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
index 1340a41..29015d6 100644
--- a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
+++ b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
@@ -24,7 +24,6 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.widget.ListView;
-import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.android.inputmethod.latin.R;
@@ -195,9 +194,10 @@
         super.onBindView(view);
         ((ViewGroup)view).setLayoutTransition(null);
 
-        final ProgressBar progressBar =
-                (ProgressBar)view.findViewById(R.id.dictionary_line_progress_bar);
+        final DictionaryDownloadProgressBar progressBar =
+                (DictionaryDownloadProgressBar)view.findViewById(R.id.dictionary_line_progress_bar);
         final TextView status = (TextView)view.findViewById(android.R.id.summary);
+        progressBar.setIds(mClientId, mWordlistId);
         progressBar.setMax(mFilesize);
         final boolean showProgressBar = (MetadataDbHelper.STATUS_DOWNLOADING == mStatus);
         status.setVisibility(showProgressBar ? View.INVISIBLE : View.VISIBLE);