ProfileProvider.java revision 82792ae937085bfa1f7878166e89ca4ea84fd652
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16package com.android.providers.contacts;
17
18import android.content.ContentValues;
19import android.content.Context;
20import android.content.res.AssetFileDescriptor;
21import android.database.Cursor;
22import android.database.sqlite.SQLiteDatabase;
23import android.net.Uri;
24
25import java.io.FileNotFoundException;
26import java.util.Locale;
27
28/**
29 * Simple content provider to handle directing profile-specific calls against a separate
30 * database from the rest of contacts.
31 */
32public class ProfileProvider extends AbstractContactsProvider {
33
34    private static final String READ_PERMISSION = "android.permission.READ_PROFILE";
35    private static final String WRITE_PERMISSION = "android.permission.WRITE_PROFILE";
36
37    // The Contacts provider handles most of the logic - this provider is only invoked when the
38    // URI belongs to a profile action, setting up the proper database.
39    private final ContactsProvider2 mDelegate;
40
41    public ProfileProvider(ContactsProvider2 delegate) {
42        mDelegate = delegate;
43    }
44
45    /**
46     * Performs a permission check on the read profile permission.  Checks the delegate contacts
47     * provider to see whether this is an authorized one-time-use URI.
48     * @param uri The URI being accessed.
49     */
50    public void enforceReadPermission(Uri uri) {
51        if (!mDelegate.isValidPreAuthorizedUri(uri)) {
52            mDelegate.getContext().enforceCallingOrSelfPermission(READ_PERMISSION, null);
53        }
54    }
55
56    /**
57     * Performs a permission check on the write profile permission.
58     */
59    public void enforceWritePermission() {
60        mDelegate.getContext().enforceCallingOrSelfPermission(WRITE_PERMISSION, null);
61    }
62
63    @Override
64    protected ProfileDatabaseHelper getDatabaseHelper(Context context) {
65        return ProfileDatabaseHelper.getInstance(context);
66    }
67
68    @Override
69    protected ThreadLocal<ContactsTransaction> getTransactionHolder() {
70        return mDelegate.getTransactionHolder();
71    }
72
73    @Override
74    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
75            String sortOrder) {
76        enforceReadPermission(uri);
77        mDelegate.substituteDb(getDatabaseHelper().getReadableDatabase());
78        return mDelegate.queryLocal(uri, projection, selection, selectionArgs, sortOrder, -1);
79    }
80
81    @Override
82    protected Uri insertInTransaction(Uri uri, ContentValues values) {
83        enforceWritePermission();
84        useProfileDbForTransaction();
85        return mDelegate.insertInTransaction(uri, values);
86    }
87
88    @Override
89    protected int updateInTransaction(Uri uri, ContentValues values, String selection,
90            String[] selectionArgs) {
91        enforceWritePermission();
92        useProfileDbForTransaction();
93        return mDelegate.updateInTransaction(uri, values, selection, selectionArgs);
94    }
95
96    @Override
97    protected int deleteInTransaction(Uri uri, String selection, String[] selectionArgs) {
98        enforceWritePermission();
99        useProfileDbForTransaction();
100        return mDelegate.deleteInTransaction(uri, selection, selectionArgs);
101    }
102
103    @Override
104    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
105        if (mode != null && mode.contains("w")) {
106            enforceWritePermission();
107            mDelegate.substituteDb(getDatabaseHelper().getWritableDatabase());
108        } else {
109            enforceReadPermission(uri);
110            mDelegate.substituteDb(getDatabaseHelper().getReadableDatabase());
111        }
112        return mDelegate.openAssetFileLocal(uri, mode);
113    }
114
115    private void useProfileDbForTransaction() {
116        ContactsTransaction transaction = getCurrentTransaction();
117        SQLiteDatabase db = getDatabaseHelper().getWritableDatabase();
118        transaction.startTransactionForDb(db, ContactsProvider2.PROFILE_DB_TAG, this);
119        mDelegate.substituteDb(db);
120    }
121
122    @Override
123    protected void notifyChange() {
124        mDelegate.notifyChange();
125    }
126
127    protected void notifyChange(boolean syncToNetwork) {
128        mDelegate.notifyChange(syncToNetwork);
129    }
130
131    protected Locale getLocale() {
132        return mDelegate.getLocale();
133    }
134
135    public void onBegin() {
136        mDelegate.switchToProfileMode();
137        mDelegate.onBegin();
138    }
139
140    public void onCommit() {
141        mDelegate.switchToProfileMode();
142        mDelegate.onCommit();
143    }
144
145    @Override
146    public void onRollback() {
147        mDelegate.switchToProfileMode();
148        mDelegate.onRollback();
149    }
150
151    @Override
152    protected boolean yield(ContactsTransaction transaction) {
153        return mDelegate.yield(transaction);
154    }
155
156    @Override
157    public String getType(Uri uri) {
158        return mDelegate.getType(uri);
159    }
160}
161