1839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang/*
2839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * Copyright (C) 2012 Google Inc.
3839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * Licensed to The Android Open Source Project.
4839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang *
5839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * Licensed under the Apache License, Version 2.0 (the "License");
6839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * you may not use this file except in compliance with the License.
7839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * You may obtain a copy of the License at
8839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang *
9839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang *      http://www.apache.org/licenses/LICENSE-2.0
10839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang *
11839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * Unless required by applicable law or agreed to in writing, software
12839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * distributed under the License is distributed on an "AS IS" BASIS,
13839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * See the License for the specific language governing permissions and
15839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * limitations under the License.
16839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang */
17839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
18839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangpackage com.android.mail.utils;
19839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
20839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport android.content.ContentProvider;
21839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport android.content.ContentProviderOperation;
22839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport android.content.ContentProviderResult;
23839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport android.content.ContentResolver;
24839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport android.content.ContentValues;
25839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport android.net.Uri;
26839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport android.os.AsyncTask;
27839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
28839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport com.google.common.collect.Lists;
29839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
30839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangimport java.util.ArrayList;
31839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
32839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang/**
33839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * Simple utility class to make an asynchronous {@link ContentProvider} request expressed as
34839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * a list of {@link ContentProviderOperation}s. As with all {@link AsyncTask}s, subclasses should
35d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal * override {@link #onPostExecute(Object)} to handle success/failure.
36839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang *
37839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * @see InsertTask
38839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * @see UpdateTask
39839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang * @see DeleteTask
40839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang *
41839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang */
42839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huangpublic class ContentProviderTask extends AsyncTask<Void, Void, ContentProviderTask.Result> {
43839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
44839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    private ContentResolver mResolver;
45839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    private String mAuthority;
46839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    private ArrayList<ContentProviderOperation> mOps;
47839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
48839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    private static final String LOG_TAG = LogTag.getLogTag();
49839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
50839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    public static class Result {
51d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        public final Exception exception;
52d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        public final ContentProviderResult[] results;
53d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal
54d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        /**
55d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * Create a new result.
56d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * @param exception
57d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * @param results
58d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         */
59d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        private Result(Exception exception, ContentProviderResult[] results) {
60d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal            this.exception = exception;
61d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal            this.results = results;
62d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        }
63839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
64d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        /**
65d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * Create a new success result.
66d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * @param success
67d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * @return
68d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         */
69d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        private static Result newSuccess(ContentProviderResult[] success) {
70d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal            return new Result(null, success);
71839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        }
72839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
73d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        /**
74d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * Create a new failure result.
75d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         * @param failure
76d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal         */
77d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        private static Result newFailure(Exception failure) {
78d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal            return new Result(failure, null);
79839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        }
80839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    }
81839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
82839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    @Override
83839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    protected Result doInBackground(Void... params) {
84d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal        Result result;
85839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            try {
86d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal                result = Result.newSuccess(mResolver.applyBatch(mAuthority, mOps));
87839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            } catch (Exception e) {
88839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                LogUtils.w(LOG_TAG, e, "exception executing ContentProviderOperationsTask");
89d9895b65e074a2cd68ad2aaa87d7b49f05bacdbeVikram Aggarwal                result = Result.newFailure(e);
90839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            }
91839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        return result;
92839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    }
93839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
94839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    public void run(ContentResolver resolver, String authority,
95839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            ArrayList<ContentProviderOperation> ops) {
96839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        mResolver = resolver;
97839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        mAuthority = authority;
98839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        mOps = ops;
99839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        executeOnExecutor(THREAD_POOL_EXECUTOR, (Void) null);
100839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    }
101839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
102839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    public static class InsertTask extends ContentProviderTask {
103839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
104839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        public void run(ContentResolver resolver, Uri uri, ContentValues values) {
105839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            final ContentProviderOperation op = ContentProviderOperation
106839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .newInsert(uri)
107839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .withValues(values)
108839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .build();
109839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            super.run(resolver, uri.getAuthority(), Lists.newArrayList(op));
110839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        }
111839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
112839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    }
113839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
114839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    public static class UpdateTask extends ContentProviderTask {
115839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
116839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        public void run(ContentResolver resolver, Uri uri, ContentValues values,
117839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                String selection, String[] selectionArgs) {
118839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            final ContentProviderOperation op = ContentProviderOperation
119839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .newUpdate(uri)
120839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .withValues(values)
121839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .withSelection(selection, selectionArgs)
122839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .build();
123839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            super.run(resolver, uri.getAuthority(), Lists.newArrayList(op));
124839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        }
125839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
126839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    }
127839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
128839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    public static class DeleteTask extends ContentProviderTask {
129839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
130839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        public void run(ContentResolver resolver, Uri uri, String selection,
131839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                String[] selectionArgs) {
132839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            final ContentProviderOperation op = ContentProviderOperation
133839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .newDelete(uri)
134839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .withSelection(selection, selectionArgs)
135839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang                    .build();
136839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang            super.run(resolver, uri.getAuthority(), Lists.newArrayList(op));
137839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang        }
138839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
139839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang    }
140839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang
141839ada22ea84251dde3305003d2f8fc5bf14914eAndy Huang}
142