152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee/* 252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * Copyright (C) 2011 The Android Open Source Project 352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * 452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * Licensed under the Apache License, Version 2.0 (the "License"); 552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * you may not use this file except in compliance with the License. 652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * You may obtain a copy of the License at 752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * 852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * http://www.apache.org/licenses/LICENSE-2.0 952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * 1052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * Unless required by applicable law or agreed to in writing, software 1152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * distributed under the License is distributed on an "AS IS" BASIS, 1252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * See the License for the specific language governing permissions and 1452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * limitations under the License 1552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee */ 1652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeepackage com.android.providers.contacts; 1752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 189cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport static android.provider.VoicemailContract.SOURCE_PACKAGE_FIELD; 199cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport static com.android.providers.contacts.util.DbQueryUtils.concatenateClauses; 2052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport static com.android.providers.contacts.util.DbQueryUtils.getEqualityClause; 2152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 2252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.content.ContentProvider; 2352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.content.ContentValues; 2452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.content.Context; 25eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjeeimport android.content.Intent; 26eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjeeimport android.content.pm.PackageManager; 2752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.database.Cursor; 2852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.net.Uri; 2952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.os.Binder; 3052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.os.ParcelFileDescriptor; 319cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.provider.BaseColumns; 3252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.provider.VoicemailContract; 3352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport android.provider.VoicemailContract.Voicemails; 34663b8b8ce7a29fb2796dc6431f2cd5992934f315Makoto Onukiimport android.util.Log; 3552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 3638210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.Tables; 3738210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.util.SelectionBuilder; 3838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.util.TypedUriMatcherImpl; 3938210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.common.annotations.VisibleForTesting; 4038210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki 4152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport java.io.FileNotFoundException; 4252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjeeimport java.util.List; 4352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 4452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee/** 459cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * An implementation of the Voicemail content provider. This class in the entry point for both 469cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * voicemail content ('calls') table and 'voicemail_status' table. This class performs all common 479cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * permission checks and then delegates database level operations to respective table delegate 489cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * objects. 4952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee */ 504b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjeepublic class VoicemailContentProvider extends ContentProvider 514b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee implements VoicemailTable.DelegateHelper { 52aafbe295d67686870c64c74a59e589d1dfb506faDebashish Chatterjee private VoicemailPermissions mVoicemailPermissions; 534b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee private VoicemailTable.Delegate mVoicemailContentTable; 549cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private VoicemailTable.Delegate mVoicemailStatusTable; 5552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 5652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee @Override 5752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee public boolean onCreate() { 58663b8b8ce7a29fb2796dc6431f2cd5992934f315Makoto Onuki if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { 59663b8b8ce7a29fb2796dc6431f2cd5992934f315Makoto Onuki Log.d(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate start"); 60663b8b8ce7a29fb2796dc6431f2cd5992934f315Makoto Onuki } 6152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee Context context = context(); 62aafbe295d67686870c64c74a59e589d1dfb506faDebashish Chatterjee mVoicemailPermissions = new VoicemailPermissions(context); 639cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee mVoicemailContentTable = new VoicemailContentTable(Tables.CALLS, context, 64aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda getDatabaseHelper(context), this, createCallLogInsertionHelper(context)); 659cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee mVoicemailStatusTable = new VoicemailStatusTable(Tables.VOICEMAIL_STATUS, context, 664b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee getDatabaseHelper(context), this); 67663b8b8ce7a29fb2796dc6431f2cd5992934f315Makoto Onuki if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { 68663b8b8ce7a29fb2796dc6431f2cd5992934f315Makoto Onuki Log.d(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate finish"); 69663b8b8ce7a29fb2796dc6431f2cd5992934f315Makoto Onuki } 7052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return true; 7152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 7252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 73aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda @VisibleForTesting 74aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda /*package*/ CallLogInsertionHelper createCallLogInsertionHelper(Context context) { 75c4144727cd740079f47e74ae5078d1613874f72aMakoto Onuki return DefaultCallLogInsertionHelper.getInstance(context); 76aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda } 77aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda 78aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda @VisibleForTesting 79aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda /*package*/ ContactsDatabaseHelper getDatabaseHelper(Context context) { 801975b56a3368b4b7684429ffa79e7b9dbc35b475Debashish Chatterjee return ContactsDatabaseHelper.getInstance(context); 811975b56a3368b4b7684429ffa79e7b9dbc35b475Debashish Chatterjee } 821975b56a3368b4b7684429ffa79e7b9dbc35b475Debashish Chatterjee 83aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda @VisibleForTesting 84aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda /*package*/ Context context() { 8552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return getContext(); 8652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 8752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 8852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee @Override 8952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee public String getType(Uri uri) { 9052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee UriData uriData = null; 9152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee try { 924b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee uriData = UriData.createUriData(uri); 9352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } catch (IllegalArgumentException ignored) { 9452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee // Special case: for illegal URIs, we return null rather than thrown an exception. 9552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return null; 9652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 979cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return getTableDelegate(uriData).getType(uriData); 9852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 9952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 10052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee @Override 1014b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public Uri insert(Uri uri, ContentValues values) { 1029cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee UriData uriData = checkPermissionsAndCreateUriData(uri, values); 1039cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return getTableDelegate(uriData).insert(uriData, values); 10452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 10552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 10652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee @Override 1074b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 1084b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee String sortOrder) { 109eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee UriData uriData = checkPermissionsAndCreateUriDataForReadOperation(uri); 1104b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee SelectionBuilder selectionBuilder = new SelectionBuilder(selection); 1114b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee selectionBuilder.addClause(getPackageRestrictionClause()); 1129cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return getTableDelegate(uriData).query(uriData, projection, selectionBuilder.build(), 1134b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee selectionArgs, sortOrder); 11452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 11552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1164b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee @Override 1174b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 1189cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee UriData uriData = checkPermissionsAndCreateUriData(uri, values); 1194b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee SelectionBuilder selectionBuilder = new SelectionBuilder(selection); 1204b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee selectionBuilder.addClause(getPackageRestrictionClause()); 1219cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return getTableDelegate(uriData).update(uriData, values, selectionBuilder.build(), 1224b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee selectionArgs); 12352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 12452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1254b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee @Override 1264b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public int delete(Uri uri, String selection, String[] selectionArgs) { 1274b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee UriData uriData = checkPermissionsAndCreateUriData(uri); 1284b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee SelectionBuilder selectionBuilder = new SelectionBuilder(selection); 1294b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee selectionBuilder.addClause(getPackageRestrictionClause()); 1309cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return getTableDelegate(uriData).delete(uriData, selectionBuilder.build(), selectionArgs); 13152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 13252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1334b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee @Override 1344b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 135eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee UriData uriData = null; 136eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee if (mode.equals("r")) { 137eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee uriData = checkPermissionsAndCreateUriDataForReadOperation(uri); 138eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee } else { 139eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee uriData = checkPermissionsAndCreateUriData(uri); 140eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee } 1414b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee // openFileHelper() relies on "_data" column to be populated with the file path. 1429cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return getTableDelegate(uriData).openFile(uriData, mode); 1439cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 1449cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 1459cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee /** Returns the correct table delegate object that can handle this URI. */ 1469cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private VoicemailTable.Delegate getTableDelegate(UriData uriData) { 1479cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee switch (uriData.getUriType()) { 1489cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee case STATUS: 1499cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee case STATUS_ID: 1509cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return mVoicemailStatusTable; 1519cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee case VOICEMAILS: 1529cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee case VOICEMAILS_ID: 1539cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return mVoicemailContentTable; 1549cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee case NO_MATCH: 1559cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee throw new IllegalStateException("Invalid uri type for uri: " + uriData.getUri()); 1569cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee default: 1579cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee throw new IllegalStateException("Impossible, all cases are covered."); 1589cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 15952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 16052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 16152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee /** 1624b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee * Decorates a URI by providing methods to get various properties from the URI. 16352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee */ 1644b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public static class UriData { 1654b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee private final Uri mUri; 1664b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee private final String mId; 1674b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee private final String mSourcePackage; 1689cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private final VoicemailUriType mUriType; 16952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1709cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public UriData(Uri uri, VoicemailUriType uriType, String id, String sourcePackage) { 1719cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee mUriType = uriType; 1724b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee mUri = uri; 1734b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee mId = id; 1744b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee mSourcePackage = sourcePackage; 17552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 17652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1774b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee /** Gets the original URI to which this {@link UriData} corresponds. */ 1784b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public final Uri getUri() { 1794b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee return mUri; 18052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 18152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1824b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee /** Tells us if our URI has an individual voicemail id. */ 1834b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public final boolean hasId() { 1844b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee return mId != null; 18552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 18652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1874b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee /** Gets the ID for the voicemail. */ 1884b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public final String getId() { 1894b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee return mId; 19052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 19152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1924b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee /** Tells us if our URI has a source package string. */ 1934b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public final boolean hasSourcePackage() { 1944b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee return mSourcePackage != null; 19552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 19652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 1974b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee /** Gets the source package. */ 1984b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public final String getSourcePackage() { 1994b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee return mSourcePackage; 20052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 20152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 2029cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee /** Gets the Voicemail URI type. */ 2039cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public final VoicemailUriType getUriType() { 2049cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return mUriType; 2059cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 2069cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 2079cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee /** Builds a where clause from the URI data. */ 2089cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public final String getWhereClause() { 2099cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return concatenateClauses( 2109cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee (hasId() ? getEqualityClause(BaseColumns._ID, getId()) : null), 2119cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee (hasSourcePackage() ? getEqualityClause(SOURCE_PACKAGE_FIELD, 2129cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee getSourcePackage()) : null)); 2139cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 2149cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 2154b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee /** Create a {@link UriData} corresponding to a given uri. */ 2164b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public static UriData createUriData(Uri uri) { 2174b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee String sourcePackage = uri.getQueryParameter( 2184b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee VoicemailContract.PARAM_KEY_SOURCE_PACKAGE); 2194b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee List<String> segments = uri.getPathSegments(); 2209cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee VoicemailUriType uriType = createUriMatcher().match(uri); 2219cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee switch (uriType) { 2224b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee case VOICEMAILS: 2239cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee case STATUS: 2249cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return new UriData(uri, uriType, null, sourcePackage); 2254b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee case VOICEMAILS_ID: 2269cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee case STATUS_ID: 2279cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return new UriData(uri, uriType, segments.get(1), sourcePackage); 2284b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee case NO_MATCH: 2294b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee throw new IllegalArgumentException("Invalid URI: " + uri); 2304b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee default: 2314b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee throw new IllegalStateException("Impossible, all cases are covered"); 2324b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee } 2334b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee } 2349cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 2359cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private static TypedUriMatcherImpl<VoicemailUriType> createUriMatcher() { 2369cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return new TypedUriMatcherImpl<VoicemailUriType>( 2379cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee VoicemailContract.AUTHORITY, VoicemailUriType.values()); 2389cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 23952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 24052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 2414b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee @Override 2424b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee // VoicemailTable.DelegateHelper interface. 2434b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee public void checkAndAddSourcePackageIntoValues(UriData uriData, ContentValues values) { 2444b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee // If content values don't contain the provider, calculate the right provider to use. 2459cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee if (!values.containsKey(SOURCE_PACKAGE_FIELD)) { 2464b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee String provider = uriData.hasSourcePackage() ? 2474b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee uriData.getSourcePackage() : getCallingPackage(); 2489cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee values.put(SOURCE_PACKAGE_FIELD, provider); 2494b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee } 2504b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee // You must have access to the provider given in values. 2514b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee if (!mVoicemailPermissions.callerHasFullAccess()) { 2524b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee checkPackagesMatch(getCallingPackage(), 2534b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee values.getAsString(VoicemailContract.SOURCE_PACKAGE_FIELD), 2544b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee uriData.getUri()); 255975d52af754e6f05089fcd9f7066df05c290c3b7Debashish Chatterjee } 256975d52af754e6f05089fcd9f7066df05c290c3b7Debashish Chatterjee } 257975d52af754e6f05089fcd9f7066df05c290c3b7Debashish Chatterjee 2589cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee /** 2599cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * Checks that the source_package field is same in uriData and ContentValues, if it happens 2609cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * to be set in both. 2619cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee */ 2629cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private void checkSourcePackageSameIfSet(UriData uriData, ContentValues values) { 2639cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee if (uriData.hasSourcePackage() && values.containsKey(SOURCE_PACKAGE_FIELD)) { 2649cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee if (!uriData.getSourcePackage().equals(values.get(SOURCE_PACKAGE_FIELD))) { 2659cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee throw new SecurityException( 2669cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee "source_package in URI was " + uriData.getSourcePackage() + 2679cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee " but doesn't match source_package in ContentValues which was " 2689cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee + values.get(SOURCE_PACKAGE_FIELD)); 2699cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 2709cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 2719cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 2729cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 2739cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee @Override 2749cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee /** Implementation of {@link VoicemailTable.DelegateHelper#openDataFile(UriData, String)} */ 2759cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public ParcelFileDescriptor openDataFile(UriData uriData, String mode) 2769cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee throws FileNotFoundException { 2779cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return openFileHelper(uriData.getUri(), mode); 27852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 27952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 28052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee /** 2814b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee * Performs necessary voicemail permission checks common to all operations and returns 2824b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee * the structured representation, {@link UriData}, of the supplied uri. 28352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee */ 284eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee private UriData checkPermissionsAndCreateUriDataForReadOperation(Uri uri) { 285eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee // If the caller has been explicitly granted read permission to this URI then no need to 286eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee // check further. 287eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee if (context().checkCallingUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION) 288eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee == PackageManager.PERMISSION_GRANTED) { 289eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee return UriData.createUriData(uri); 290eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee } 291eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee return checkPermissionsAndCreateUriData(uri); 292eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee } 293eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee 294eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee /** 295eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee * Performs necessary voicemail permission checks common to all operations and returns 296eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee * the structured representation, {@link UriData}, of the supplied uri. 297eeffa7edb048e785ebc665c830dc84d87f174b07Debashish Chatterjee */ 2984b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee private UriData checkPermissionsAndCreateUriData(Uri uri) { 2994b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee mVoicemailPermissions.checkCallerHasOwnVoicemailAccess(); 3004b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee UriData uriData = UriData.createUriData(uri); 3014b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee checkPackagePermission(uriData); 3024b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee return uriData; 3034b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee } 30452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 3054b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee /** 3069cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * Same as {@link #checkPackagePermission(UriData)}. In addition does permission check 3079cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * on the ContentValues. 3089cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee */ 3099cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private UriData checkPermissionsAndCreateUriData(Uri uri, ContentValues... valuesArray) { 3109cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee UriData uriData = checkPermissionsAndCreateUriData(uri); 3119cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee for (ContentValues values : valuesArray) { 3129cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee checkSourcePackageSameIfSet(uriData, values); 3139cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 3149cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return uriData; 3159cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 3169cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 3179cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee /** 3189cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * Checks that the callingPackage is same as voicemailSourcePackage. Throws {@link 3194b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee * SecurityException} if they don't match. 3204b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee */ 3219cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private final void checkPackagesMatch(String callingPackage, String voicemailSourcePackage, 3224b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee Uri uri) { 3239cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee if (!voicemailSourcePackage.equals(callingPackage)) { 3244b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee String errorMsg = String.format("Permission denied for URI: %s\n. " + 3259cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee "Package %s cannot perform this operation for %s. Requires %s permission.", 3269cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee uri, callingPackage, voicemailSourcePackage, 3274b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee Manifest.permission.READ_WRITE_ALL_VOICEMAIL); 3284b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee throw new SecurityException(errorMsg); 32952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 33052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 33152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 33252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee /** 33352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * Checks that either the caller has READ_WRITE_ALL_VOICEMAIL permission, or has the 33498a77ec8057c5fe0ff487ca7d0910312693e5689Debashish Chatterjee * ADD_VOICEMAIL permission and is using a URI that matches 3359cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * /voicemail/?source_package=[source-package] where [source-package] is the same as the calling 33652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * package. 33752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * 33852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * @throws SecurityException if the check fails. 33952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee */ 34052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee private void checkPackagePermission(UriData uriData) { 341aafbe295d67686870c64c74a59e589d1dfb506faDebashish Chatterjee if (!mVoicemailPermissions.callerHasFullAccess()) { 34252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee if (!uriData.hasSourcePackage()) { 3439cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee // You cannot have a match if this is not a provider URI. 34452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee throw new SecurityException(String.format( 34552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee "Provider %s does not have %s permission." + 3464b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee "\nPlease set query parameter '%s' in the URI.\nURI: %s", 34752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee getCallingPackage(), Manifest.permission.READ_WRITE_ALL_VOICEMAIL, 3484b571ba0de4fac4ff9d2a4277032b8c6548fdbfaDebashish Chatterjee VoicemailContract.PARAM_KEY_SOURCE_PACKAGE, uriData.getUri())); 34952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 35052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee checkPackagesMatch(getCallingPackage(), uriData.getSourcePackage(), uriData.getUri()); 35152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 35252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 35352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 35452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee /** 35552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * Gets the name of the calling package. 35652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * <p> 35752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * It's possible (though unlikely) for there to be more than one calling package (requires that 35852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * your manifest say you want to share process ids) in which case we will return an arbitrary 35952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * package name. It's also possible (though very unlikely) for us to be unable to work out what 36052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * your calling package is, in which case we will return null. 36152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee */ 36252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee /* package for test */String getCallingPackage() { 36352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee int caller = Binder.getCallingUid(); 36452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee if (caller == 0) { 36552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return null; 36652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 36752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee String[] callerPackages = context().getPackageManager().getPackagesForUid(caller); 36852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee if (callerPackages == null || callerPackages.length == 0) { 36952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return null; 37052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 37152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee if (callerPackages.length == 1) { 37252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return callerPackages[0]; 37352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 37452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee // If we have more than one caller package, which is very unlikely, let's return the one 37552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee // with the highest permissions. If more than one has the same permission, we don't care 37652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee // which one we return. 37752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee String bestSoFar = callerPackages[0]; 37852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee for (String callerPackage : callerPackages) { 379aafbe295d67686870c64c74a59e589d1dfb506faDebashish Chatterjee if (mVoicemailPermissions.packageHasFullAccess(callerPackage)) { 38052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee // Full always wins, we can return early. 38152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return callerPackage; 38252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 383aafbe295d67686870c64c74a59e589d1dfb506faDebashish Chatterjee if (mVoicemailPermissions.packageHasOwnVoicemailAccess(callerPackage)) { 38452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee bestSoFar = callerPackage; 38552e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 38652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 38752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return bestSoFar; 38852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 38952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee 39052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee /** 39152e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * Creates a clause to restrict the selection to the calling provider or null if the caller has 39252e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee * access to all data. 39352e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee */ 39452e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee private String getPackageRestrictionClause() { 395aafbe295d67686870c64c74a59e589d1dfb506faDebashish Chatterjee if (mVoicemailPermissions.callerHasFullAccess()) { 39652e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return null; 39752e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 39852e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee return getEqualityClause(Voicemails.SOURCE_PACKAGE, getCallingPackage()); 39952e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee } 40052e8d24f8492116f0b49b147576ce13a5f913aa2Debashish Chatterjee} 401