1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging;
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentProvider;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentProviderClient;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentValues;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.pm.ProviderInfo;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.database.Cursor;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle;
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.RemoteException;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.util.SimpleArrayMap;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.TextUtils;
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.FakeCursor;
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil;
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.ArrayList;
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class FakeContentProvider extends ContentProvider {
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private static class ContentOverride {
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private final String uri;
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private final String where;
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private final String args;
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private final String[] columns;
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        private final Object[][] data;
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        ContentOverride(final String uri, final String where, final String args,
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final String[] columns, final Object[][] data) {
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            this.uri = uri;
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            this.where = where;
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            this.args = args;
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            this.columns = columns;
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            this.data = data;
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        boolean match(final String uri, final String where, final String[] args) {
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (!this.uri.equals(uri) || !TextUtils.equals(this.where, where)) {
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return false;
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (this.args == null || args == null) {
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return this.args == null && args == null;
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return this.args.equals(TextUtils.join(";", args));
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private final Context mGlobalContext;
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private final ArrayList<ContentOverride> mOverrides = new ArrayList<ContentOverride>();
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private final SimpleArrayMap<String, String> mTypes = new SimpleArrayMap<String, String>();
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private final ContentProviderClient mProvider;
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    private final Uri mUri;
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public FakeContentProvider(final Context context, final Uri uri, final boolean canDelegate) {
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mGlobalContext = context;
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mUri = uri;
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (canDelegate) {
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mProvider = mGlobalContext.getContentResolver().acquireContentProviderClient(mUri);
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } else {
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mProvider = null;
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        ProviderInfo providerInfo = new ProviderInfo();
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        providerInfo.authority = uri.getAuthority();
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        this.attachInfo(mGlobalContext, providerInfo);
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void addOverrideData(final Uri uri, final String where, final String args,
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String[] columns, final Object[][] data) {
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mOverrides.add(new ContentOverride(uri.toString(), where, args, columns, data));
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void addOverrideType(final Uri uri, final String type) {
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        mTypes.put(uri.toString(), type);
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public boolean onCreate() {
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return false;
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public void shutdown() {
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (mProvider != null) {
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            mProvider.release();
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Cursor query(final Uri uri, final String[] projection, final String selection,
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String[] selectionArgs, final String sortOrder) {
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        LogUtil.w(LogUtil.BUGLE_TAG, "FakeContentProvider: query " + uri.toString()
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                + " for " + (projection == null ? null : TextUtils.join(",", projection))
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                + " where " + selection
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                + " with " + (selectionArgs == null ? null : TextUtils.join(";", selectionArgs)));
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        for(final ContentOverride content : mOverrides) {
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            if (content.match(uri.toString(), selection, selectionArgs)) {
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return new FakeCursor(projection, content.columns, content.data);
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (mProvider != null) {
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            try {
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.w(LogUtil.BUGLE_TAG, "FakeContentProvider: delgating");
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                final Cursor cursor = mProvider.query(uri, projection, selection, selectionArgs,
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        sortOrder);
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                LogUtil.w(LogUtil.BUGLE_TAG, "FakeContentProvider: response size "
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                        + cursor.getCount() + " contains " + TextUtils.join(",",
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                                cursor.getColumnNames()) + " type(0) " + cursor.getType(0));
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return cursor;
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } catch (final RemoteException e) {
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                e.printStackTrace();
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return null;
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public String getType(final Uri uri) {
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        String type = mTypes.get(uri.toString());
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (type == null) {
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            try {
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                type = mProvider.getType(uri);
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            } catch (final RemoteException e) {
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                e.printStackTrace();
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            }
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return type;
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Uri insert(final Uri uri, final ContentValues values) {
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // TODO: Add code to track insert operations and return correct status
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        throw new UnsupportedOperationException();
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public int delete(final Uri uri, final String selection, final String[] selectionArgs) {
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // TODO: Add code to track delete operations and return correct status
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        throw new UnsupportedOperationException();
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    @Override
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public int update(final Uri uri, final ContentValues values, final String selection,
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final String[] selectionArgs) {
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // TODO: Add code to track update operations and return correct status
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        throw new UnsupportedOperationException();
171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public Bundle call(final String callingPkg, final String method, final String arg,
174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final Bundle extras) {
175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return null;
176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
178