1 /*
2  * Copyright (C) 2010 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.cts.permissiondeclareapp;
18 
19 import android.content.ClipboardManager;
20 import android.content.ContentProvider;
21 import android.content.ContentValues;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.UriPermission;
25 import android.database.Cursor;
26 import android.net.Uri;
27 import android.os.Binder;
28 import android.os.Bundle;
29 
30 import java.util.List;
31 
32 public class UtilsProvider extends ContentProvider {
33     public static final Uri URI = Uri.parse("content://com.android.cts.permissiondeclareapp/");
34 
35     public static final String ACTION_GRANT_URI = "grantUri";
36     public static final String ACTION_REVOKE_URI = "revokeUri";
37     public static final String ACTION_START_ACTIVITY = "startActivity";
38     public static final String ACTION_START_ACTIVITIES = "startActivities";
39     public static final String ACTION_START_SERVICE = "startService";
40     public static final String ACTION_VERIFY_OUTGOING_PERSISTED = "verifyOutgoingPersisted";
41     public static final String ACTION_SET_PRIMARY_CLIP = "setPrimaryClip";
42     public static final String ACTION_CLEAR_PRIMARY_CLIP = "clearPrimaryClip";
43     public static final String ACTION_SET_INSTALLER_PACKAGE_NAME = "setInstallerPackageName";
44 
45     public static final String EXTRA_PACKAGE_NAME = "packageName";
46     public static final String EXTRA_INSTALLER_PACKAGE_NAME = "installerPackageName";
47     public static final String EXTRA_INTENT = Intent.EXTRA_INTENT;
48     public static final String EXTRA_URI = "uri";
49     public static final String EXTRA_MODE = "mode";
50     public static final String EXTRA_RUN_EXPLICIT = "runExplicit";
51 
52     @Override
call(String method, String arg, Bundle extras)53     public Bundle call(String method, String arg, Bundle extras) {
54         final Context context = getContext();
55         final Intent intent = extras.getParcelable(Intent.EXTRA_INTENT);
56         final String action = intent.getAction();
57 
58         final long token = Binder.clearCallingIdentity();
59         try {
60             if (ACTION_GRANT_URI.equals(action)) {
61                 final Uri uri = intent.getParcelableExtra(EXTRA_URI);
62                 context.grantUriPermission(intent.getStringExtra(EXTRA_PACKAGE_NAME), uri,
63                         intent.getIntExtra(EXTRA_MODE, 0));
64 
65             } else if (ACTION_REVOKE_URI.equals(action)) {
66                 final Uri uri = intent.getParcelableExtra(EXTRA_URI);
67                 context.revokeUriPermission(uri, intent.getIntExtra(EXTRA_MODE, 0));
68 
69             } else if (ACTION_START_ACTIVITY.equals(action)) {
70                 final Intent newIntent = intent.getParcelableExtra(EXTRA_INTENT);
71                 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
72                 context.startActivity(newIntent);
73 
74             } else if (ACTION_START_ACTIVITIES.equals(action)) {
75                 final Intent newIntent = intent.getParcelableExtra(EXTRA_INTENT);
76                 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
77                 context.startActivities(new Intent[] { newIntent });
78 
79             } else if (ACTION_START_SERVICE.equals(action)) {
80                 final Intent newIntent = intent.getParcelableExtra(EXTRA_INTENT);
81                 context.startService(newIntent);
82 
83             } else if (ACTION_VERIFY_OUTGOING_PERSISTED.equals(action)) {
84                 verifyOutgoingPersisted(context, intent);
85 
86             } else if (ACTION_SET_PRIMARY_CLIP.equals(action)) {
87                 context.getSystemService(ClipboardManager.class)
88                         .setPrimaryClip(intent.getClipData());
89 
90             } else if (ACTION_CLEAR_PRIMARY_CLIP.equals(action)) {
91                 context.getSystemService(ClipboardManager.class).clearPrimaryClip();
92 
93             } else if (ACTION_SET_INSTALLER_PACKAGE_NAME.equals(action)) {
94                 context.getPackageManager().setInstallerPackageName(
95                         intent.getStringExtra(EXTRA_PACKAGE_NAME),
96                         intent.getStringExtra(EXTRA_INSTALLER_PACKAGE_NAME));
97             }
98         } finally {
99             Binder.restoreCallingIdentity(token);
100         }
101         return null;
102     }
103 
verifyOutgoingPersisted(Context context, Intent intent)104     private void verifyOutgoingPersisted(Context context, Intent intent) {
105         final Uri uri = intent.getParcelableExtra(EXTRA_URI);
106         final List<UriPermission> perms = context.getContentResolver()
107                 .getOutgoingPersistedUriPermissions();
108         if (uri != null) {
109             // Should have a single persisted perm
110             if (perms.size() != 1) {
111                 throw new SecurityException("Missing grant");
112             }
113             final UriPermission perm = perms.get(0);
114             if (!perm.getUri().equals(uri)) {
115                 throw new SecurityException(
116                         "Expected " + uri + " but found " + perm.getUri());
117             }
118         } else {
119             // Should have zero persisted perms
120             if (perms.size() != 0) {
121                 throw new SecurityException("Unexpected grant");
122             }
123         }
124     }
125 
126     @Override
onCreate()127     public boolean onCreate() {
128         return true;
129     }
130 
131     @Override
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)132     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
133             String sortOrder) {
134         throw new UnsupportedOperationException();
135     }
136 
137     @Override
getType(Uri uri)138     public String getType(Uri uri) {
139         throw new UnsupportedOperationException();
140     }
141 
142     @Override
insert(Uri uri, ContentValues values)143     public Uri insert(Uri uri, ContentValues values) {
144         throw new UnsupportedOperationException();
145     }
146 
147     @Override
delete(Uri uri, String selection, String[] selectionArgs)148     public int delete(Uri uri, String selection, String[] selectionArgs) {
149         throw new UnsupportedOperationException();
150     }
151 
152     @Override
update(Uri uri, ContentValues values, String selection, String[] selectionArgs)153     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
154         throw new UnsupportedOperationException();
155     }
156 }
157