Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9be3f5b6 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Handle full-disk exceptions when viewing call log.

When the internal storage is full, resetNewCallsFlag() fails
and causes Contacts to crash.  Since this method is called
whenever the tab is opened, it makes the call log
inaccessible to users.  (We should always keep the phone in
a usable state, even when the disk is full.)

Because startUpdate() runs on a background thread, I'm
overriding the WorkerHandler used by AsyncQueryHandler to
wrap any calls in a try/catch block.

Also added a try/catch block around the code that updates
any missing contact details after a caller-ID query has
returned, which could also cause a crash when the user
switches to the call log tab.

Partially fixes http://b/issue?id=1966505
parent 2dfe98ab
Loading
Loading
Loading
Loading
+59 −17
Original line number Diff line number Diff line
@@ -24,10 +24,14 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabaseCorruptException;
import android.database.sqlite.SQLiteDiskIOException;
import android.database.sqlite.SQLiteFullException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -277,9 +281,17 @@ public class RecentCallsListActivity extends ListActivity
            values.put(Calls.CACHED_NAME, ci.name);
            values.put(Calls.CACHED_NUMBER_TYPE, ci.type);
            values.put(Calls.CACHED_NUMBER_LABEL, ci.label);
            RecentCallsListActivity.this.getContentResolver().update(
                    Calls.CONTENT_URI,
                    values, Calls.NUMBER + "='" + ciq.number + "'", null);

            try {
                RecentCallsListActivity.this.getContentResolver().update(Calls.CONTENT_URI, values,
                        Calls.NUMBER + "='" + ciq.number + "'", null);
            } catch (SQLiteDiskIOException e) {
                Log.w(TAG, "Exception while updating call info", e);
            } catch (SQLiteFullException e) {
                Log.w(TAG, "Exception while updating call info", e);
            } catch (SQLiteDatabaseCorruptException e) {
                Log.w(TAG, "Exception while updating call info", e);
            }
        }

        private void enqueueRequest(String number, int position,
@@ -509,6 +521,36 @@ public class RecentCallsListActivity extends ListActivity
    private static final class QueryHandler extends AsyncQueryHandler {
        private final WeakReference<RecentCallsListActivity> mActivity;

        /**
         * Simple handler that wraps background calls to catch
         * {@link SQLiteException}, such as when the disk is full.
         */
        protected class CatchingWorkerHandler extends AsyncQueryHandler.WorkerHandler {
            public CatchingWorkerHandler(Looper looper) {
                super(looper);
            }

            @Override
            public void handleMessage(Message msg) {
                try {
                    // Perform same query while catching any exceptions
                    super.handleMessage(msg);
                } catch (SQLiteDiskIOException e) {
                    Log.w(TAG, "Exception on background worker thread", e);
                } catch (SQLiteFullException e) {
                    Log.w(TAG, "Exception on background worker thread", e);
                } catch (SQLiteDatabaseCorruptException e) {
                    Log.w(TAG, "Exception on background worker thread", e);
                }
            }
        }

        @Override
        protected Handler createHandler(Looper looper) {
            // Provide our special handler that catches exceptions
            return new CatchingWorkerHandler(looper);
        }

        public QueryHandler(Context context) {
            super(context.getContentResolver());
            mActivity = new WeakReference<RecentCallsListActivity>(