blob: 90577e33f5ae7afaac7146fb52f78d9c1271c467 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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
17package com.android.server.am;
18
19import android.content.Intent;
Jeff Sharkey69062202017-06-26 19:34:04 -060020import android.os.Binder;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070021import android.os.UserHandle;
Jeff Sharkey846318a2014-04-04 12:12:41 -070022import android.util.ArraySet;
Jeff Sharkeyd16b1252016-09-01 11:07:23 -060023import android.util.Log;
Jeff Sharkey846318a2014-04-04 12:12:41 -070024import android.util.Slog;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070025
Jeff Sharkey846318a2014-04-04 12:12:41 -070026import com.android.server.am.ActivityManagerService.GrantUri;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070027import com.google.android.collect.Sets;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
29import java.io.PrintWriter;
Jeff Sharkeye66c1772013-09-20 14:30:59 -070030import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Dianne Hackborn7e269642010-08-25 19:50:20 -070032/**
33 * Description of a permission granted to an app to access a particular URI.
34 *
35 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
36 *
Dianne Hackborncca1f0e2010-09-26 18:34:53 -070037 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
38 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
Dianne Hackborn7e269642010-08-25 19:50:20 -070039 */
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070040final class UriPermission {
Jeff Sharkey328ebf22013-03-21 18:09:39 -070041 private static final String TAG = "UriPermission";
42
Jeff Sharkeye66c1772013-09-20 14:30:59 -070043 public static final int STRENGTH_NONE = 0;
44 public static final int STRENGTH_OWNED = 1;
45 public static final int STRENGTH_GLOBAL = 2;
46 public static final int STRENGTH_PERSISTABLE = 3;
47
Nicolas Prevotd85fc722014-04-16 19:52:08 +010048 final int targetUserId;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070049 final String sourcePkg;
50 final String targetPkg;
51
52 /** Cached UID of {@link #targetPkg}; should not be persisted */
53 final int targetUid;
54
Jeff Sharkey846318a2014-04-04 12:12:41 -070055 final GrantUri uri;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070056
57 /**
58 * Allowed modes. All permission enforcement should use this field. Must
Jeff Sharkeye66c1772013-09-20 14:30:59 -070059 * always be a combination of {@link #ownedModeFlags},
60 * {@link #globalModeFlags}, {@link #persistableModeFlags}, and
61 * {@link #persistedModeFlags}. Mutations <em>must</em> only be performed by
62 * the owning class.
Jeff Sharkey328ebf22013-03-21 18:09:39 -070063 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 int modeFlags = 0;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070065
Jeff Sharkey846318a2014-04-04 12:12:41 -070066 /** Allowed modes with active owner. */
Jeff Sharkeye66c1772013-09-20 14:30:59 -070067 int ownedModeFlags = 0;
68 /** Allowed modes without explicit owner. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 int globalModeFlags = 0;
Jeff Sharkeye66c1772013-09-20 14:30:59 -070070 /** Allowed modes that have been offered for possible persisting. */
71 int persistableModeFlags = 0;
Jeff Sharkey846318a2014-04-04 12:12:41 -070072
Jeff Sharkeye66c1772013-09-20 14:30:59 -070073 /** Allowed modes that should be persisted across device boots. */
74 int persistedModeFlags = 0;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070075
76 /**
Jeff Sharkeye66c1772013-09-20 14:30:59 -070077 * Timestamp when {@link #persistedModeFlags} was first defined in
78 * {@link System#currentTimeMillis()} time base.
Jeff Sharkey328ebf22013-03-21 18:09:39 -070079 */
Jeff Sharkeye66c1772013-09-20 14:30:59 -070080 long persistedCreateTime = INVALID_TIME;
81
82 private static final long INVALID_TIME = Long.MIN_VALUE;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070083
Jeff Sharkey846318a2014-04-04 12:12:41 -070084 private ArraySet<UriPermissionOwner> mReadOwners;
85 private ArraySet<UriPermissionOwner> mWriteOwners;
Jeff Sharkey328ebf22013-03-21 18:09:39 -070086
87 private String stringName;
88
Jeff Sharkey846318a2014-04-04 12:12:41 -070089 UriPermission(String sourcePkg, String targetPkg, int targetUid, GrantUri uri) {
Nicolas Prevotd85fc722014-04-16 19:52:08 +010090 this.targetUserId = UserHandle.getUserId(targetUid);
Jeff Sharkey328ebf22013-03-21 18:09:39 -070091 this.sourcePkg = sourcePkg;
92 this.targetPkg = targetPkg;
93 this.targetUid = targetUid;
94 this.uri = uri;
95 }
96
Jeff Sharkeye66c1772013-09-20 14:30:59 -070097 private void updateModeFlags() {
Jeff Sharkeyd16b1252016-09-01 11:07:23 -060098 final int oldModeFlags = modeFlags;
Jeff Sharkeye66c1772013-09-20 14:30:59 -070099 modeFlags = ownedModeFlags | globalModeFlags | persistableModeFlags | persistedModeFlags;
Jeff Sharkeyd16b1252016-09-01 11:07:23 -0600100
101 if (Log.isLoggable(TAG, Log.VERBOSE) && (modeFlags != oldModeFlags)) {
102 Slog.d(TAG,
103 "Permission for " + targetPkg + " to " + uri + " is changing from 0x"
104 + Integer.toHexString(oldModeFlags) + " to 0x"
Jeff Sharkey69062202017-06-26 19:34:04 -0600105 + Integer.toHexString(modeFlags) + " via calling UID "
106 + Binder.getCallingUid() + " PID " + Binder.getCallingPid(),
Jeff Sharkeyd16b1252016-09-01 11:07:23 -0600107 new Throwable());
108 }
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700109 }
110
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700111 /**
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700112 * Initialize persisted modes as read from file. This doesn't issue any
113 * global or owner grants.
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700114 */
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700115 void initPersistedModes(int modeFlags, long createdTime) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700116 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
117 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
118
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700119 persistableModeFlags = modeFlags;
120 persistedModeFlags = modeFlags;
121 persistedCreateTime = createdTime;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700122
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700123 updateModeFlags();
124 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700125
Jeff Sharkey846318a2014-04-04 12:12:41 -0700126 void grantModes(int modeFlags, UriPermissionOwner owner) {
127 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
128 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
129 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
130
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700131 if (persistable) {
132 persistableModeFlags |= modeFlags;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700133 }
134
135 if (owner == null) {
136 globalModeFlags |= modeFlags;
137 } else {
138 if ((modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
139 addReadOwner(owner);
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700140 }
141 if ((modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
142 addWriteOwner(owner);
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700143 }
144 }
145
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700146 updateModeFlags();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 }
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700148
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700149 /**
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700150 * @return if mode changes should trigger persisting.
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700151 */
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700152 boolean takePersistableModes(int modeFlags) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700153 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
154 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
155
Jeff Sharkey582f7122013-10-11 17:46:47 -0700156 if ((modeFlags & persistableModeFlags) != modeFlags) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700157 Slog.w(TAG, "Requested flags 0x"
Jeff Sharkey582f7122013-10-11 17:46:47 -0700158 + Integer.toHexString(modeFlags) + ", but only 0x"
159 + Integer.toHexString(persistableModeFlags) + " are allowed");
Jeff Sharkey846318a2014-04-04 12:12:41 -0700160 return false;
Jeff Sharkey582f7122013-10-11 17:46:47 -0700161 }
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700162
163 final int before = persistedModeFlags;
164 persistedModeFlags |= (persistableModeFlags & modeFlags);
165
166 if (persistedModeFlags != 0) {
167 persistedCreateTime = System.currentTimeMillis();
168 }
169
170 updateModeFlags();
171 return persistedModeFlags != before;
172 }
173
174 boolean releasePersistableModes(int modeFlags) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700175 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
176 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
177
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700178 final int before = persistedModeFlags;
179
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700180 persistableModeFlags &= ~modeFlags;
181 persistedModeFlags &= ~modeFlags;
182
183 if (persistedModeFlags == 0) {
184 persistedCreateTime = INVALID_TIME;
185 }
186
187 updateModeFlags();
188 return persistedModeFlags != before;
189 }
190
191 /**
192 * @return if mode changes should trigger persisting.
193 */
Jeff Sharkey29b25162014-09-19 09:14:34 -0700194 boolean revokeModes(int modeFlags, boolean includingOwners) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700195 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
196 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
197 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
198
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700199 final int before = persistedModeFlags;
200
201 if ((modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
202 if (persistable) {
203 persistableModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700204 persistedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 globalModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
Jeff Sharkey29b25162014-09-19 09:14:34 -0700207 if (mReadOwners != null && includingOwners) {
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700208 ownedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700209 for (UriPermissionOwner r : mReadOwners) {
Dianne Hackborn39792d22010-08-19 18:01:52 -0700210 r.removeReadPermission(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700212 mReadOwners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 }
214 }
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700215 if ((modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
216 if (persistable) {
217 persistableModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700218 persistedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
Jeff Sharkey29b25162014-09-19 09:14:34 -0700221 if (mWriteOwners != null && includingOwners) {
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700222 ownedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700223 for (UriPermissionOwner r : mWriteOwners) {
Dianne Hackborn39792d22010-08-19 18:01:52 -0700224 r.removeWritePermission(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700226 mWriteOwners = null;
227 }
228 }
229
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700230 if (persistedModeFlags == 0) {
231 persistedCreateTime = INVALID_TIME;
232 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700233
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700234 updateModeFlags();
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700235 return persistedModeFlags != before;
236 }
237
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700238 /**
239 * Return strength of this permission grant for the given flags.
240 */
241 public int getStrength(int modeFlags) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700242 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
243 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700244 if ((persistableModeFlags & modeFlags) == modeFlags) {
245 return STRENGTH_PERSISTABLE;
246 } else if ((globalModeFlags & modeFlags) == modeFlags) {
247 return STRENGTH_GLOBAL;
248 } else if ((ownedModeFlags & modeFlags) == modeFlags) {
249 return STRENGTH_OWNED;
250 } else {
251 return STRENGTH_NONE;
252 }
253 }
254
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700255 private void addReadOwner(UriPermissionOwner owner) {
256 if (mReadOwners == null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700257 mReadOwners = Sets.newArraySet();
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700258 ownedModeFlags |= Intent.FLAG_GRANT_READ_URI_PERMISSION;
259 updateModeFlags();
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700260 }
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700261 if (mReadOwners.add(owner)) {
262 owner.addReadPermission(this);
263 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700264 }
265
266 /**
267 * Remove given read owner, updating {@Link #modeFlags} as needed.
268 */
269 void removeReadOwner(UriPermissionOwner owner) {
270 if (!mReadOwners.remove(owner)) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700271 Slog.wtf(TAG, "Unknown read owner " + owner + " in " + this);
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700272 }
273 if (mReadOwners.size() == 0) {
274 mReadOwners = null;
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700275 ownedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
276 updateModeFlags();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 }
278 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700279
280 private void addWriteOwner(UriPermissionOwner owner) {
281 if (mWriteOwners == null) {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700282 mWriteOwners = Sets.newArraySet();
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700283 ownedModeFlags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
284 updateModeFlags();
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700285 }
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700286 if (mWriteOwners.add(owner)) {
287 owner.addWritePermission(this);
288 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700289 }
290
291 /**
292 * Remove given write owner, updating {@Link #modeFlags} as needed.
293 */
294 void removeWriteOwner(UriPermissionOwner owner) {
295 if (!mWriteOwners.remove(owner)) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700296 Slog.wtf(TAG, "Unknown write owner " + owner + " in " + this);
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700297 }
298 if (mWriteOwners.size() == 0) {
299 mWriteOwners = null;
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700300 ownedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
301 updateModeFlags();
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700302 }
303 }
304
305 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700307 if (stringName != null) {
308 return stringName;
309 }
310 StringBuilder sb = new StringBuilder(128);
311 sb.append("UriPermission{");
312 sb.append(Integer.toHexString(System.identityHashCode(this)));
313 sb.append(' ');
314 sb.append(uri);
315 sb.append('}');
316 return stringName = sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
318
319 void dump(PrintWriter pw, String prefix) {
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700320 pw.print(prefix);
Nicolas Prevotd85fc722014-04-16 19:52:08 +0100321 pw.print("targetUserId=" + targetUserId);
Jeff Sharkey9e0036e2013-04-26 16:54:55 -0700322 pw.print(" sourcePkg=" + sourcePkg);
323 pw.println(" targetPkg=" + targetPkg);
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700324
325 pw.print(prefix);
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700326 pw.print("mode=0x" + Integer.toHexString(modeFlags));
327 pw.print(" owned=0x" + Integer.toHexString(ownedModeFlags));
328 pw.print(" global=0x" + Integer.toHexString(globalModeFlags));
329 pw.print(" persistable=0x" + Integer.toHexString(persistableModeFlags));
330 pw.print(" persisted=0x" + Integer.toHexString(persistedModeFlags));
331 if (persistedCreateTime != INVALID_TIME) {
332 pw.print(" persistedCreate=" + persistedCreateTime);
333 }
334 pw.println();
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700335
336 if (mReadOwners != null) {
337 pw.print(prefix);
338 pw.println("readOwners:");
339 for (UriPermissionOwner owner : mReadOwners) {
340 pw.print(prefix);
341 pw.println(" * " + owner);
Dianne Hackborn39792d22010-08-19 18:01:52 -0700342 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700343 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700344 if (mWriteOwners != null) {
345 pw.print(prefix);
346 pw.println("writeOwners:");
347 for (UriPermissionOwner owner : mReadOwners) {
348 pw.print(prefix);
349 pw.println(" * " + owner);
Dianne Hackborn39792d22010-08-19 18:01:52 -0700350 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -0700351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 }
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700353
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700354 public static class PersistedTimeComparator implements Comparator<UriPermission> {
355 @Override
356 public int compare(UriPermission lhs, UriPermission rhs) {
357 return Long.compare(lhs.persistedCreateTime, rhs.persistedCreateTime);
358 }
359 }
360
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700361 /**
362 * Snapshot of {@link UriPermission} with frozen
363 * {@link UriPermission#persistedModeFlags} state.
364 */
365 public static class Snapshot {
Nicolas Prevotd85fc722014-04-16 19:52:08 +0100366 final int targetUserId;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700367 final String sourcePkg;
368 final String targetPkg;
Jeff Sharkey846318a2014-04-04 12:12:41 -0700369 final GrantUri uri;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700370 final int persistedModeFlags;
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700371 final long persistedCreateTime;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700372
373 private Snapshot(UriPermission perm) {
Nicolas Prevotd85fc722014-04-16 19:52:08 +0100374 this.targetUserId = perm.targetUserId;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700375 this.sourcePkg = perm.sourcePkg;
376 this.targetPkg = perm.targetPkg;
377 this.uri = perm.uri;
378 this.persistedModeFlags = perm.persistedModeFlags;
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700379 this.persistedCreateTime = perm.persistedCreateTime;
Jeff Sharkey328ebf22013-03-21 18:09:39 -0700380 }
381 }
382
383 public Snapshot snapshot() {
384 return new Snapshot(this);
385 }
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700386
387 public android.content.UriPermission buildPersistedPublicApiObject() {
Jeff Sharkey846318a2014-04-04 12:12:41 -0700388 return new android.content.UriPermission(uri.uri, persistedModeFlags, persistedCreateTime);
Jeff Sharkeye66c1772013-09-20 14:30:59 -0700389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390}