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.server.am;
18 
19 import android.content.Intent;
20 import android.net.Uri;
21 import android.os.Binder;
22 import android.os.IBinder;
23 import android.util.ArraySet;
24 
25 import com.google.android.collect.Sets;
26 
27 import java.io.PrintWriter;
28 import java.util.Iterator;
29 
30 final class UriPermissionOwner {
31     final ActivityManagerService service;
32     final Object owner;
33 
34     Binder externalToken;
35 
36     private ArraySet<UriPermission> mReadPerms;
37     private ArraySet<UriPermission> mWritePerms;
38 
39     class ExternalToken extends Binder {
getOwner()40         UriPermissionOwner getOwner() {
41             return UriPermissionOwner.this;
42         }
43     }
44 
UriPermissionOwner(ActivityManagerService service, Object owner)45     UriPermissionOwner(ActivityManagerService service, Object owner) {
46         this.service = service;
47         this.owner = owner;
48     }
49 
getExternalTokenLocked()50     Binder getExternalTokenLocked() {
51         if (externalToken == null) {
52             externalToken = new ExternalToken();
53         }
54         return externalToken;
55     }
56 
fromExternalToken(IBinder token)57     static UriPermissionOwner fromExternalToken(IBinder token) {
58         if (token instanceof ExternalToken) {
59             return ((ExternalToken)token).getOwner();
60         }
61         return null;
62     }
63 
removeUriPermissionsLocked()64     void removeUriPermissionsLocked() {
65         removeUriPermissionsLocked(Intent.FLAG_GRANT_READ_URI_PERMISSION
66                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
67     }
68 
removeUriPermissionsLocked(int mode)69     void removeUriPermissionsLocked(int mode) {
70         removeUriPermissionLocked(null, mode);
71     }
72 
removeUriPermissionLocked(ActivityManagerService.GrantUri grantUri, int mode)73     void removeUriPermissionLocked(ActivityManagerService.GrantUri grantUri, int mode) {
74         if ((mode & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0
75                 && mReadPerms != null) {
76             Iterator<UriPermission> it = mReadPerms.iterator();
77             while (it.hasNext()) {
78                 UriPermission perm = it.next();
79                 if (grantUri == null || grantUri.equals(perm.uri)) {
80                     perm.removeReadOwner(this);
81                     service.removeUriPermissionIfNeededLocked(perm);
82                     it.remove();
83                 }
84             }
85             if (mReadPerms.isEmpty()) {
86                 mReadPerms = null;
87             }
88         }
89         if ((mode & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0
90                 && mWritePerms != null) {
91             Iterator<UriPermission> it = mWritePerms.iterator();
92             while (it.hasNext()) {
93                 UriPermission perm = it.next();
94                 if (grantUri == null || grantUri.equals(perm.uri)) {
95                     perm.removeWriteOwner(this);
96                     service.removeUriPermissionIfNeededLocked(perm);
97                     it.remove();
98                 }
99             }
100             if (mWritePerms.isEmpty()) {
101                 mWritePerms = null;
102             }
103         }
104     }
105 
addReadPermission(UriPermission perm)106     public void addReadPermission(UriPermission perm) {
107         if (mReadPerms == null) {
108             mReadPerms = Sets.newArraySet();
109         }
110         mReadPerms.add(perm);
111     }
112 
addWritePermission(UriPermission perm)113     public void addWritePermission(UriPermission perm) {
114         if (mWritePerms == null) {
115             mWritePerms = Sets.newArraySet();
116         }
117         mWritePerms.add(perm);
118     }
119 
removeReadPermission(UriPermission perm)120     public void removeReadPermission(UriPermission perm) {
121         mReadPerms.remove(perm);
122         if (mReadPerms.isEmpty()) {
123             mReadPerms = null;
124         }
125     }
126 
removeWritePermission(UriPermission perm)127     public void removeWritePermission(UriPermission perm) {
128         mWritePerms.remove(perm);
129         if (mWritePerms.isEmpty()) {
130             mWritePerms = null;
131         }
132     }
133 
dump(PrintWriter pw, String prefix)134     public void dump(PrintWriter pw, String prefix) {
135         if (mReadPerms != null) {
136             pw.print(prefix); pw.print("readUriPermissions="); pw.println(mReadPerms);
137         }
138         if (mWritePerms != null) {
139             pw.print(prefix); pw.print("writeUriPermissions="); pw.println(mWritePerms);
140         }
141     }
142 
143     @Override
toString()144     public String toString() {
145         return owner.toString();
146     }
147 }
148