DbModifierWithNotification.java revision 98a77ec8057c5fe0ff487ca7d0910312693e5689
1929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee/*
2929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * Copyright (C) 2011 The Android Open Source Project
3929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
4929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee *
5929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * Licensed under the Apache License, Version 2.0 (the "License");
6929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * you may not use this file except in compliance with the License.
7929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * You may obtain a copy of the License at
8929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee *
9929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee *      http://www.apache.org/licenses/LICENSE-2.0
10929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee *
11929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * Unless required by applicable law or agreed to in writing, software
12929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * distributed under the License is distributed on an "AS IS" BASIS,
13929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * See the License for the specific language governing permissions and
15929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * limitations under the License
16929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee */
17929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
18929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeepackage com.android.providers.contacts;
19929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
2098a77ec8057c5fe0ff487ca7d0910312693e5689Debashish Chatterjeeimport static android.Manifest.permission.ADD_VOICEMAIL;
21929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport static com.android.providers.contacts.Manifest.permission.READ_WRITE_ALL_VOICEMAIL;
22929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
23929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport com.android.providers.contacts.ContactsDatabaseHelper.Tables;
24929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport com.android.providers.contacts.util.DbQueryUtils;
25929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport com.google.android.collect.Lists;
26929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
27929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.content.ComponentName;
28929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.content.ContentUris;
29929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.content.ContentValues;
30929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.content.Context;
31929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.content.Intent;
32929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.content.pm.ActivityInfo;
33929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.content.pm.ResolveInfo;
34929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.database.Cursor;
35929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.database.DatabaseUtils.InsertHelper;
36929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.database.sqlite.SQLiteDatabase;
37929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.net.Uri;
38929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.os.Binder;
39929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.provider.VoicemailContract;
40929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.provider.VoicemailContract.Status;
41929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.provider.VoicemailContract.Voicemails;
42929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport android.util.Log;
43929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
44929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport java.util.ArrayList;
45929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport java.util.Collection;
46929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport java.util.HashSet;
47929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport java.util.List;
48929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeeimport java.util.Set;
49929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
50929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee/**
51929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * An implementation of {@link DatabaseModifier} for voicemail related tables which additionally
52929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee * generates necessary notifications after the modification operation is performed.
53929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee */
54929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjeepublic class DbModifierWithVmNotification implements DatabaseModifier {
55929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private static final String TAG = "DbModifierWithVmNotification";
56929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
57929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private static final String[] PROJECTION = new String[] {
58929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            VoicemailContract.SOURCE_PACKAGE_FIELD
59929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    };
60929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private static final int SOURCE_PACKAGE_COLUMN_INDEX = 0;
61929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private static final String NON_NULL_SOURCE_PACKAGE_SELECTION =
62929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            VoicemailContract.SOURCE_PACKAGE_FIELD + " IS NOT NULL";
63929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
64929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private final String mTableName;
65929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private final SQLiteDatabase mDb;
66929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private final InsertHelper mInsertHelper;
67929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private final Context mContext;
68929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private final Uri mBaseUri;
69929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private final boolean mIsVoicemailContentTable;
70929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private final VoicemailPermissions mVoicemailPermissions;
71929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
72929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    public DbModifierWithVmNotification(String tableName, SQLiteDatabase db, Context context) {
73929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        this(tableName, db, null, context);
74929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
75929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
76929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    public DbModifierWithVmNotification(String tableName, InsertHelper insertHelper,
77929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            Context context) {
78929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        this(tableName, null, insertHelper, context);
79929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
80929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
81929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private DbModifierWithVmNotification(String tableName, SQLiteDatabase db,
82929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            InsertHelper insertHelper, Context context) {
83929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mTableName = tableName;
84929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mDb = db;
85929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mInsertHelper = insertHelper;
86929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mContext = context;
87929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mBaseUri = mTableName.equals(Tables.VOICEMAIL_STATUS) ?
88929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                Status.CONTENT_URI : Voicemails.CONTENT_URI;
89929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mIsVoicemailContentTable = !mTableName.equals(Tables.VOICEMAIL_STATUS);
90929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mVoicemailPermissions = new VoicemailPermissions(mContext);
91929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
92929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
93929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    @Override
94929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    public long insert(String table, String nullColumnHack, ContentValues values) {
95929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Set<String> packagesModified = getModifiedPackages(values);
96929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        long rowId = mDb.insert(table, nullColumnHack, values);
97929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        if (rowId > 0 && packagesModified.size() != 0) {
98929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            notifyOnInsert(ContentUris.withAppendedId(mBaseUri, rowId), packagesModified);
99929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
100929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return rowId;
101929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
102929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
103929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    @Override
104929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    public long insert(ContentValues values) {
105929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Set<String> packagesModified = getModifiedPackages(values);
106929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        long rowId = mInsertHelper.insert(values);
107929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        if (rowId > 0 && packagesModified.size() != 0) {
108929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            notifyOnInsert(ContentUris.withAppendedId(mBaseUri, rowId), packagesModified);
109929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
110929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return rowId;
111929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
112929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
113929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private void notifyOnInsert(Uri notificationUri, Set<String> packagesModified) {
114929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        if (mIsVoicemailContentTable) {
115929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            notifyChange(notificationUri, packagesModified, VoicemailContract.ACTION_NEW_VOICEMAIL,
116929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                    Intent.ACTION_PROVIDER_CHANGED);
117929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        } else {
118929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            notifyChange(notificationUri, packagesModified, Intent.ACTION_PROVIDER_CHANGED);
119929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
120929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
121929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
122929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    @Override
123929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
124929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Set<String> packagesModified = getModifiedPackages(whereClause, whereArgs);
125929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        packagesModified.addAll(getModifiedPackages(values));
126929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        int count = mDb.update(table, values, whereClause, whereArgs);
127929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        if (count > 0 && packagesModified.size() != 0) {
128929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            notifyChange(mBaseUri, packagesModified, Intent.ACTION_PROVIDER_CHANGED);
129929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
130929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return count;
131929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
132929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
133929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    @Override
134929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    public int delete(String table, String whereClause, String[] whereArgs) {
135929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Set<String> packagesModified = getModifiedPackages(whereClause, whereArgs);
136929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        int count = mDb.delete(table, whereClause, whereArgs);
137929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        if (count > 0 && packagesModified.size() != 0) {
138929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            notifyChange(mBaseUri, packagesModified, Intent.ACTION_PROVIDER_CHANGED);
139929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
140929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return count;
141929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
142929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
143929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    /**
144929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * Returns the set of packages affected when a modify operation is run for the specified
145929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * where clause. When called from an insert operation an empty set returned by this method
146929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * implies (indirectly) that this does not affect any voicemail entry, as a voicemail entry is
147929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * always expected to have the source package field set.
148929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     */
149929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private Set<String> getModifiedPackages(String whereClause, String[] whereArgs) {
150929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Set<String> modifiedPackages = new HashSet<String>();
151929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Cursor cursor = mDb.query(mTableName, PROJECTION,
152929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                DbQueryUtils.concatenateClauses(NON_NULL_SOURCE_PACKAGE_SELECTION, whereClause),
153929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                whereArgs, null, null, null);
154929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        while(cursor.moveToNext()) {
155929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            modifiedPackages.add(cursor.getString(SOURCE_PACKAGE_COLUMN_INDEX));
156929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
157929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return modifiedPackages;
158929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
159929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
160929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    /**
161929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * Returns the source package that gets affected (in an insert/update operation) by the supplied
162929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * content values. An empty set returned by this method also implies (indirectly) that this does
163929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * not affect any voicemail entry, as a voicemail entry is always expected to have the source
164929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * package field set.
165929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     */
166929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private Set<String> getModifiedPackages(ContentValues values) {
167929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Set<String> impactedPackages = new HashSet<String>();
168929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        if(values.containsKey(VoicemailContract.SOURCE_PACKAGE_FIELD)) {
169929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            impactedPackages.add(values.getAsString(VoicemailContract.SOURCE_PACKAGE_FIELD));
170929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
171929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return impactedPackages;
172929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
173929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
174929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private void notifyChange(Uri notificationUri, Set<String> modifiedPackages,
175929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            String... intentActions) {
176929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        // Notify the observers.
177929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        // Must be done only once, even if there are multiple broadcast intents.
178929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        mContext.getContentResolver().notifyChange(notificationUri, null, true);
179929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Collection<String> callingPackages = getCallingPackages();
180929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        // Now fire individual intents.
181929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        for (String intentAction : intentActions) {
182929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            // self_change extra should be included only for provider_changed events.
183929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            boolean includeSelfChangeExtra = intentAction.equals(Intent.ACTION_PROVIDER_CHANGED);
184929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            for (ComponentName component :
185929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                    getBroadcastReceiverComponents(intentAction, notificationUri)) {
1868d5a094810ce8c60b83e534d903a0d662e621252Debashish Chatterjee                // Ignore any package that is not affected by the change and don't have full access
1878d5a094810ce8c60b83e534d903a0d662e621252Debashish Chatterjee                // either.
1888d5a094810ce8c60b83e534d903a0d662e621252Debashish Chatterjee                if (!modifiedPackages.contains(component.getPackageName()) &&
1898d5a094810ce8c60b83e534d903a0d662e621252Debashish Chatterjee                        !mVoicemailPermissions.packageHasFullAccess(component.getPackageName())) {
1908d5a094810ce8c60b83e534d903a0d662e621252Debashish Chatterjee                    continue;
1918d5a094810ce8c60b83e534d903a0d662e621252Debashish Chatterjee                }
1928d5a094810ce8c60b83e534d903a0d662e621252Debashish Chatterjee
193929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                Intent intent = new Intent(intentAction, notificationUri);
194929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                intent.setComponent(component);
195929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                if (includeSelfChangeExtra && callingPackages != null) {
196929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                    intent.putExtra(VoicemailContract.EXTRA_SELF_CHANGE,
197929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                            callingPackages.contains(component.getPackageName()));
198929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                }
199929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                String permissionNeeded = modifiedPackages.contains(component.getPackageName()) ?
20098a77ec8057c5fe0ff487ca7d0910312693e5689Debashish Chatterjee                        ADD_VOICEMAIL : READ_WRITE_ALL_VOICEMAIL;
201929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                mContext.sendBroadcast(intent, permissionNeeded);
202929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                Log.v(TAG, String.format("Sent intent. act:%s, url:%s, comp:%s, perm:%s," +
203929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                        " self_change:%s", intent.getAction(), intent.getData(),
204929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                        component.getClassName(), permissionNeeded,
205929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                        intent.hasExtra(VoicemailContract.EXTRA_SELF_CHANGE) ?
206929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                                intent.getBooleanExtra(VoicemailContract.EXTRA_SELF_CHANGE, false) :
207929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                                        null));
208929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            }
209929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
210929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
211929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
212929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    /** Determines the components that can possibly receive the specified intent. */
213929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private List<ComponentName> getBroadcastReceiverComponents(String intentAction, Uri uri) {
214929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        Intent intent = new Intent(intentAction, uri);
215929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        List<ComponentName> receiverComponents = new ArrayList<ComponentName>();
216929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        // For broadcast receivers ResolveInfo.activityInfo is the one that is populated.
217929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        for (ResolveInfo resolveInfo :
218929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee                mContext.getPackageManager().queryBroadcastReceivers(intent, 0)) {
219929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            ActivityInfo activityInfo = resolveInfo.activityInfo;
220929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            receiverComponents.add(new ComponentName(activityInfo.packageName, activityInfo.name));
221929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
222929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return receiverComponents;
223929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
224929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee
225929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    /**
226929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * Returns the package names of the calling process. If the calling process has more than
227929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     * one packages, this returns them all
228929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee     */
229929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    private Collection<String> getCallingPackages() {
230929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        int caller = Binder.getCallingUid();
231929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        if (caller == 0) {
232929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee            return null;
233929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        }
234929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee        return Lists.newArrayList(mContext.getPackageManager().getPackagesForUid(caller));
235929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee    }
236929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee}
237