1 /*
2  * Copyright (C) 2014 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  */
16 
17 package com.android.providers.telephony;
18 
19 import android.content.ComponentName;
20 import android.content.ContentValues;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.net.Uri;
24 import android.os.Process;
25 import android.provider.Telephony;
26 import android.text.TextUtils;
27 import android.util.Log;
28 
29 import com.android.internal.telephony.SmsApplication;
30 
31 /**
32  * Helpers
33  */
34 public class ProviderUtil {
35     private final static String TAG = "SmsProvider";
36 
37     /**
38      * Check if a caller of the provider has restricted access,
39      * i.e. being non-system, non-phone, non-default SMS app
40      *
41      * @param context the context to use
42      * @param packageName the caller package name
43      * @param uid the caller uid
44      * @return true if the caller is not system, or phone or default sms app, false otherwise
45      */
isAccessRestricted(Context context, String packageName, int uid)46     public static boolean isAccessRestricted(Context context, String packageName, int uid) {
47         return (uid != Process.SYSTEM_UID
48                 && uid != Process.PHONE_UID
49                 && !SmsApplication.isDefaultSmsApplication(context, packageName));
50     }
51 
52     /**
53      * Whether should set CREATOR for an insertion
54      *
55      * @param values The content of the message
56      * @param uid The caller UID of the insertion
57      * @return true if we should set CREATOR, false otherwise
58      */
shouldSetCreator(ContentValues values, int uid)59     public static boolean shouldSetCreator(ContentValues values, int uid) {
60         return (uid != Process.SYSTEM_UID && uid != Process.PHONE_UID) ||
61                 (!values.containsKey(Telephony.Sms.CREATOR) &&
62                         !values.containsKey(Telephony.Mms.CREATOR));
63     }
64 
65     /**
66      * Whether should remove CREATOR for an update
67      *
68      * @param values The content of the message
69      * @param uid The caller UID of the update
70      * @return true if we should remove CREATOR, false otherwise
71      */
shouldRemoveCreator(ContentValues values, int uid)72     public static boolean shouldRemoveCreator(ContentValues values, int uid) {
73         return (uid != Process.SYSTEM_UID && uid != Process.PHONE_UID) &&
74                 (values.containsKey(Telephony.Sms.CREATOR) ||
75                         values.containsKey(Telephony.Mms.CREATOR));
76     }
77 
78     /**
79      * Notify the default SMS app of an SMS/MMS provider change if the change is being made
80      * by a package other than the default SMS app itself.
81      *
82      * @param uri The uri the provider change applies to
83      * @param callingPackage The package name of the provider caller
84      * @param Context
85      */
notifyIfNotDefaultSmsApp(final Uri uri, final String callingPackage, final Context context)86     public static void notifyIfNotDefaultSmsApp(final Uri uri, final String callingPackage,
87             final Context context) {
88         if (TextUtils.equals(callingPackage, Telephony.Sms.getDefaultSmsPackage(context))) {
89             if (Log.isLoggable(TAG, Log.VERBOSE)) {
90                 Log.d(TAG, "notifyIfNotDefaultSmsApp - called from default sms app");
91             }
92             return;
93         }
94         // Direct the intent to only the default SMS app, and only if the SMS app has a receiver
95         // for the intent.
96         ComponentName componentName =
97                 SmsApplication.getDefaultExternalTelephonyProviderChangedApplication(context, true);
98         if (componentName == null) {
99             return;     // the default sms app doesn't have a receiver for this intent
100         }
101 
102         final Intent intent =
103                 new Intent(Telephony.Sms.Intents.ACTION_EXTERNAL_PROVIDER_CHANGE);
104         intent.setFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
105         intent.setComponent(componentName);
106         if (uri != null) {
107             intent.setData(uri);
108         }
109         if (Log.isLoggable(TAG, Log.VERBOSE)) {
110             Log.d(TAG, "notifyIfNotDefaultSmsApp - called from " + callingPackage + ", notifying");
111         }
112         intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
113         context.sendBroadcast(intent);
114     }
115 
getCredentialEncryptedContext(Context context)116     public static Context getCredentialEncryptedContext(Context context) {
117         if (context.isCredentialProtectedStorage()) {
118             return context;
119         }
120         return context.createCredentialProtectedStorageContext();
121     }
122 
getDeviceEncryptedContext(Context context)123     public static Context getDeviceEncryptedContext(Context context) {
124         if (context.isDeviceProtectedStorage()) {
125             return context;
126         }
127         return context.createDeviceProtectedStorageContext();
128     }
129 }
130