PageRenderTime 128ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/services/core/java/com/android/server/content/ContentService.java

https://gitlab.com/amardeep434/nitro_base
Java | 1213 lines | 949 code | 113 blank | 151 comment | 153 complexity | 85ad4e6ba22d7d59fe53369252828e09 MD5 | raw file
  1. /*
  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. package com.android.server.content;
  17. import android.Manifest;
  18. import android.accounts.Account;
  19. import android.annotation.Nullable;
  20. import android.app.ActivityManager;
  21. import android.app.ActivityManagerNative;
  22. import android.app.AppOpsManager;
  23. import android.app.job.JobInfo;
  24. import android.content.BroadcastReceiver;
  25. import android.content.ComponentName;
  26. import android.content.ContentProvider;
  27. import android.content.ContentResolver;
  28. import android.content.Context;
  29. import android.content.IContentService;
  30. import android.content.ISyncStatusObserver;
  31. import android.content.Intent;
  32. import android.content.IntentFilter;
  33. import android.content.PeriodicSync;
  34. import android.content.SyncAdapterType;
  35. import android.content.SyncInfo;
  36. import android.content.SyncRequest;
  37. import android.content.SyncStatusInfo;
  38. import android.content.pm.PackageManager;
  39. import android.content.pm.PackageManagerInternal;
  40. import android.content.pm.ProviderInfo;
  41. import android.database.IContentObserver;
  42. import android.database.sqlite.SQLiteException;
  43. import android.net.Uri;
  44. import android.os.Binder;
  45. import android.os.Bundle;
  46. import android.os.FactoryTest;
  47. import android.os.IBinder;
  48. import android.os.Parcel;
  49. import android.os.RemoteException;
  50. import android.os.SystemProperties;
  51. import android.os.UserHandle;
  52. import android.text.TextUtils;
  53. import android.util.ArrayMap;
  54. import android.util.Log;
  55. import android.util.Pair;
  56. import android.util.Slog;
  57. import android.util.SparseArray;
  58. import android.util.SparseIntArray;
  59. import com.android.internal.annotations.GuardedBy;
  60. import com.android.internal.util.IndentingPrintWriter;
  61. import com.android.server.LocalServices;
  62. import com.android.server.SystemService;
  63. import java.io.FileDescriptor;
  64. import java.io.PrintWriter;
  65. import java.security.InvalidParameterException;
  66. import java.util.ArrayList;
  67. import java.util.Collections;
  68. import java.util.Comparator;
  69. import java.util.List;
  70. /**
  71. * {@hide}
  72. */
  73. public final class ContentService extends IContentService.Stub {
  74. static final String TAG = "ContentService";
  75. static final boolean DEBUG = false;
  76. public static class Lifecycle extends SystemService {
  77. private ContentService mService;
  78. public Lifecycle(Context context) {
  79. super(context);
  80. }
  81. @Override
  82. public void onStart() {
  83. final boolean factoryTest = (FactoryTest
  84. .getMode() == FactoryTest.FACTORY_TEST_LOW_LEVEL);
  85. mService = new ContentService(getContext(), factoryTest);
  86. publishBinderService(ContentResolver.CONTENT_SERVICE_NAME, mService);
  87. }
  88. @Override
  89. public void onBootPhase(int phase) {
  90. if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
  91. mService.systemReady();
  92. }
  93. }
  94. @Override
  95. public void onCleanupUser(int userHandle) {
  96. synchronized (mService.mCache) {
  97. mService.mCache.remove(userHandle);
  98. }
  99. }
  100. }
  101. private Context mContext;
  102. private boolean mFactoryTest;
  103. private final ObserverNode mRootNode = new ObserverNode("");
  104. private SyncManager mSyncManager = null;
  105. private final Object mSyncManagerLock = new Object();
  106. /**
  107. * Map from userId to providerPackageName to [clientPackageName, uri] to
  108. * value. This structure is carefully optimized to keep invalidation logic
  109. * as cheap as possible.
  110. */
  111. @GuardedBy("mCache")
  112. private final SparseArray<ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>>>
  113. mCache = new SparseArray<>();
  114. private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() {
  115. @Override
  116. public void onReceive(Context context, Intent intent) {
  117. synchronized (mCache) {
  118. if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
  119. mCache.clear();
  120. } else {
  121. final Uri data = intent.getData();
  122. if (data != null) {
  123. final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
  124. UserHandle.USER_NULL);
  125. final String packageName = data.getSchemeSpecificPart();
  126. invalidateCacheLocked(userId, packageName, null);
  127. }
  128. }
  129. }
  130. }
  131. };
  132. private SyncManager getSyncManager() {
  133. if (SystemProperties.getBoolean("config.disable_network", false)) {
  134. return null;
  135. }
  136. synchronized(mSyncManagerLock) {
  137. try {
  138. // Try to create the SyncManager, return null if it fails (e.g. the disk is full).
  139. if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest);
  140. } catch (SQLiteException e) {
  141. Log.e(TAG, "Can't create SyncManager", e);
  142. }
  143. return mSyncManager;
  144. }
  145. }
  146. @Override
  147. protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) {
  148. mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP,
  149. "caller doesn't have the DUMP permission");
  150. final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, " ");
  151. // This makes it so that future permission checks will be in the context of this
  152. // process rather than the caller's process. We will restore this before returning.
  153. final long identityToken = clearCallingIdentity();
  154. try {
  155. if (mSyncManager == null) {
  156. pw.println("No SyncManager created! (Disk full?)");
  157. } else {
  158. mSyncManager.dump(fd, pw);
  159. }
  160. pw.println();
  161. pw.println("Observer tree:");
  162. synchronized (mRootNode) {
  163. int[] counts = new int[2];
  164. final SparseIntArray pidCounts = new SparseIntArray();
  165. mRootNode.dumpLocked(fd, pw, args, "", " ", counts, pidCounts);
  166. pw.println();
  167. ArrayList<Integer> sorted = new ArrayList<Integer>();
  168. for (int i=0; i<pidCounts.size(); i++) {
  169. sorted.add(pidCounts.keyAt(i));
  170. }
  171. Collections.sort(sorted, new Comparator<Integer>() {
  172. @Override
  173. public int compare(Integer lhs, Integer rhs) {
  174. int lc = pidCounts.get(lhs);
  175. int rc = pidCounts.get(rhs);
  176. if (lc < rc) {
  177. return 1;
  178. } else if (lc > rc) {
  179. return -1;
  180. }
  181. return 0;
  182. }
  183. });
  184. for (int i=0; i<sorted.size(); i++) {
  185. int pid = sorted.get(i);
  186. pw.print(" pid "); pw.print(pid); pw.print(": ");
  187. pw.print(pidCounts.get(pid)); pw.println(" observers");
  188. }
  189. pw.println();
  190. pw.print(" Total number of nodes: "); pw.println(counts[0]);
  191. pw.print(" Total number of observers: "); pw.println(counts[1]);
  192. }
  193. synchronized (mCache) {
  194. pw.println();
  195. pw.println("Cached content:");
  196. pw.increaseIndent();
  197. for (int i = 0; i < mCache.size(); i++) {
  198. pw.println("User " + mCache.keyAt(i) + ":");
  199. pw.increaseIndent();
  200. pw.println(mCache.valueAt(i));
  201. pw.decreaseIndent();
  202. }
  203. pw.decreaseIndent();
  204. }
  205. } finally {
  206. restoreCallingIdentity(identityToken);
  207. }
  208. }
  209. @Override
  210. public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
  211. throws RemoteException {
  212. try {
  213. return super.onTransact(code, data, reply, flags);
  214. } catch (RuntimeException e) {
  215. // The content service only throws security exceptions, so let's
  216. // log all others.
  217. if (!(e instanceof SecurityException)) {
  218. Slog.wtf(TAG, "Content Service Crash", e);
  219. }
  220. throw e;
  221. }
  222. }
  223. /*package*/ ContentService(Context context, boolean factoryTest) {
  224. mContext = context;
  225. mFactoryTest = factoryTest;
  226. // Let the package manager query for the sync adapters for a given authority
  227. // as we grant default permissions to sync adapters for specific authorities.
  228. PackageManagerInternal packageManagerInternal = LocalServices.getService(
  229. PackageManagerInternal.class);
  230. packageManagerInternal.setSyncAdapterPackagesprovider(
  231. new PackageManagerInternal.SyncAdapterPackagesProvider() {
  232. @Override
  233. public String[] getPackages(String authority, int userId) {
  234. return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
  235. }
  236. });
  237. final IntentFilter packageFilter = new IntentFilter();
  238. packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
  239. packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
  240. packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
  241. packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
  242. packageFilter.addDataScheme("package");
  243. mContext.registerReceiverAsUser(mCacheReceiver, UserHandle.ALL,
  244. packageFilter, null, null);
  245. final IntentFilter localeFilter = new IntentFilter();
  246. localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
  247. mContext.registerReceiverAsUser(mCacheReceiver, UserHandle.ALL,
  248. localeFilter, null, null);
  249. }
  250. void systemReady() {
  251. getSyncManager();
  252. }
  253. /**
  254. * Register a content observer tied to a specific user's view of the provider.
  255. * @param userHandle the user whose view of the provider is to be observed. May be
  256. * the calling user without requiring any permission, otherwise the caller needs to
  257. * hold the INTERACT_ACROSS_USERS_FULL permission or hold a read uri grant to the uri.
  258. * Pseudousers USER_ALL and USER_CURRENT are properly handled; all other pseudousers
  259. * are forbidden.
  260. */
  261. @Override
  262. public void registerContentObserver(Uri uri, boolean notifyForDescendants,
  263. IContentObserver observer, int userHandle) {
  264. if (observer == null || uri == null) {
  265. throw new IllegalArgumentException("You must pass a valid uri and observer");
  266. }
  267. final int uid = Binder.getCallingUid();
  268. final int pid = Binder.getCallingPid();
  269. final int callingUserHandle = UserHandle.getCallingUserId();
  270. // Registering an observer for any user other than the calling user requires uri grant or
  271. // cross user permission
  272. if (callingUserHandle != userHandle) {
  273. if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle)
  274. != PackageManager.PERMISSION_GRANTED) {
  275. enforceCrossUserPermission(userHandle,
  276. "no permission to observe other users' provider view");
  277. }
  278. }
  279. if (userHandle < 0) {
  280. if (userHandle == UserHandle.USER_CURRENT) {
  281. userHandle = ActivityManager.getCurrentUser();
  282. } else if (userHandle != UserHandle.USER_ALL) {
  283. throw new InvalidParameterException("Bad user handle for registerContentObserver: "
  284. + userHandle);
  285. }
  286. }
  287. synchronized (mRootNode) {
  288. mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
  289. uid, pid, userHandle);
  290. if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri +
  291. " with notifyForDescendants " + notifyForDescendants);
  292. }
  293. }
  294. public void registerContentObserver(Uri uri, boolean notifyForDescendants,
  295. IContentObserver observer) {
  296. registerContentObserver(uri, notifyForDescendants, observer,
  297. UserHandle.getCallingUserId());
  298. }
  299. @Override
  300. public void unregisterContentObserver(IContentObserver observer) {
  301. if (observer == null) {
  302. throw new IllegalArgumentException("You must pass a valid observer");
  303. }
  304. synchronized (mRootNode) {
  305. mRootNode.removeObserverLocked(observer);
  306. if (false) Log.v(TAG, "Unregistered observer " + observer);
  307. }
  308. }
  309. /**
  310. * Notify observers of a particular user's view of the provider.
  311. * @param userHandle the user whose view of the provider is to be notified. May be
  312. * the calling user without requiring any permission, otherwise the caller needs to
  313. * hold the INTERACT_ACROSS_USERS_FULL permission or hold a write uri grant to the uri.
  314. * Pseudousers USER_ALL and USER_CURRENT are properly interpreted; no other pseudousers are
  315. * allowed.
  316. */
  317. @Override
  318. public void notifyChange(Uri uri, IContentObserver observer,
  319. boolean observerWantsSelfNotifications, int flags,
  320. int userHandle) {
  321. if (DEBUG) Slog.d(TAG, "Notifying update of " + uri + " for user " + userHandle
  322. + " from observer " + observer + ", flags " + Integer.toHexString(flags));
  323. if (uri == null) {
  324. throw new NullPointerException("Uri must not be null");
  325. }
  326. final int uid = Binder.getCallingUid();
  327. final int pid = Binder.getCallingPid();
  328. final int callingUserHandle = UserHandle.getCallingUserId();
  329. // Notify for any user other than the caller requires uri grant or cross user permission
  330. if (callingUserHandle != userHandle) {
  331. if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
  332. userHandle) != PackageManager.PERMISSION_GRANTED) {
  333. enforceCrossUserPermission(userHandle, "no permission to notify other users");
  334. }
  335. }
  336. // We passed the permission check; resolve pseudouser targets as appropriate
  337. if (userHandle < 0) {
  338. if (userHandle == UserHandle.USER_CURRENT) {
  339. userHandle = ActivityManager.getCurrentUser();
  340. } else if (userHandle != UserHandle.USER_ALL) {
  341. throw new InvalidParameterException("Bad user handle for notifyChange: "
  342. + userHandle);
  343. }
  344. }
  345. // This makes it so that future permission checks will be in the context of this
  346. // process rather than the caller's process. We will restore this before returning.
  347. long identityToken = clearCallingIdentity();
  348. try {
  349. ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>();
  350. synchronized (mRootNode) {
  351. mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications,
  352. flags, userHandle, calls);
  353. }
  354. final int numCalls = calls.size();
  355. for (int i=0; i<numCalls; i++) {
  356. ObserverCall oc = calls.get(i);
  357. try {
  358. oc.mObserver.onChange(oc.mSelfChange, uri, userHandle);
  359. if (DEBUG) Slog.d(TAG, "Notified " + oc.mObserver + " of " + "update at "
  360. + uri);
  361. } catch (RemoteException ex) {
  362. synchronized (mRootNode) {
  363. Log.w(TAG, "Found dead observer, removing");
  364. IBinder binder = oc.mObserver.asBinder();
  365. final ArrayList<ObserverNode.ObserverEntry> list
  366. = oc.mNode.mObservers;
  367. int numList = list.size();
  368. for (int j=0; j<numList; j++) {
  369. ObserverNode.ObserverEntry oe = list.get(j);
  370. if (oe.observer.asBinder() == binder) {
  371. list.remove(j);
  372. j--;
  373. numList--;
  374. }
  375. }
  376. }
  377. }
  378. }
  379. if ((flags&ContentResolver.NOTIFY_SYNC_TO_NETWORK) != 0) {
  380. SyncManager syncManager = getSyncManager();
  381. if (syncManager != null) {
  382. syncManager.scheduleLocalSync(null /* all accounts */, callingUserHandle, uid,
  383. uri != null ? uri.getAuthority() : null);
  384. }
  385. }
  386. synchronized (mCache) {
  387. final String providerPackageName = getProviderPackageName(uri);
  388. invalidateCacheLocked(userHandle, providerPackageName, uri);
  389. }
  390. } finally {
  391. restoreCallingIdentity(identityToken);
  392. }
  393. }
  394. private int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, int userHandle) {
  395. try {
  396. return ActivityManagerNative.getDefault().checkUriPermission(
  397. uri, pid, uid, modeFlags, userHandle, null);
  398. } catch (RemoteException e) {
  399. return PackageManager.PERMISSION_DENIED;
  400. }
  401. }
  402. public void notifyChange(Uri uri, IContentObserver observer,
  403. boolean observerWantsSelfNotifications, boolean syncToNetwork) {
  404. notifyChange(uri, observer, observerWantsSelfNotifications,
  405. syncToNetwork ? ContentResolver.NOTIFY_SYNC_TO_NETWORK : 0,
  406. UserHandle.getCallingUserId());
  407. }
  408. /**
  409. * Hide this class since it is not part of api,
  410. * but current unittest framework requires it to be public
  411. * @hide
  412. *
  413. */
  414. public static final class ObserverCall {
  415. final ObserverNode mNode;
  416. final IContentObserver mObserver;
  417. final boolean mSelfChange;
  418. final int mObserverUserId;
  419. ObserverCall(ObserverNode node, IContentObserver observer, boolean selfChange, int observerUserId) {
  420. mNode = node;
  421. mObserver = observer;
  422. mSelfChange = selfChange;
  423. mObserverUserId = observerUserId;
  424. }
  425. }
  426. @Override
  427. public void requestSync(Account account, String authority, Bundle extras) {
  428. Bundle.setDefusable(extras, true);
  429. ContentResolver.validateSyncExtrasBundle(extras);
  430. int userId = UserHandle.getCallingUserId();
  431. int uId = Binder.getCallingUid();
  432. // This makes it so that future permission checks will be in the context of this
  433. // process rather than the caller's process. We will restore this before returning.
  434. long identityToken = clearCallingIdentity();
  435. try {
  436. SyncManager syncManager = getSyncManager();
  437. if (syncManager != null) {
  438. syncManager.scheduleSync(account, userId, uId, authority, extras,
  439. 0 /* no delay */, 0 /* no delay */,
  440. false /* onlyThoseWithUnkownSyncableState */);
  441. }
  442. } finally {
  443. restoreCallingIdentity(identityToken);
  444. }
  445. }
  446. /**
  447. * Request a sync with a generic {@link android.content.SyncRequest} object. This will be
  448. * either:
  449. * periodic OR one-off sync.
  450. * and
  451. * anonymous OR provider sync.
  452. * Depending on the request, we enqueue to suit in the SyncManager.
  453. * @param request The request object. Validation of this object is done by its builder.
  454. */
  455. @Override
  456. public void sync(SyncRequest request) {
  457. syncAsUser(request, UserHandle.getCallingUserId());
  458. }
  459. private long clampPeriod(long period) {
  460. long minPeriod = JobInfo.getMinPeriodMillis() / 1000;
  461. if (period < minPeriod) {
  462. Slog.w(TAG, "Requested poll frequency of " + period
  463. + " seconds being rounded up to " + minPeriod + "s.");
  464. period = minPeriod;
  465. }
  466. return period;
  467. }
  468. /**
  469. * If the user id supplied is different to the calling user, the caller must hold the
  470. * INTERACT_ACROSS_USERS_FULL permission.
  471. */
  472. @Override
  473. public void syncAsUser(SyncRequest request, int userId) {
  474. enforceCrossUserPermission(userId, "no permission to request sync as user: " + userId);
  475. int callerUid = Binder.getCallingUid();
  476. // This makes it so that future permission checks will be in the context of this
  477. // process rather than the caller's process. We will restore this before returning.
  478. long identityToken = clearCallingIdentity();
  479. try {
  480. SyncManager syncManager = getSyncManager();
  481. if (syncManager == null) {
  482. return;
  483. }
  484. Bundle extras = request.getBundle();
  485. long flextime = request.getSyncFlexTime();
  486. long runAtTime = request.getSyncRunTime();
  487. if (request.isPeriodic()) {
  488. mContext.enforceCallingOrSelfPermission(
  489. Manifest.permission.WRITE_SYNC_SETTINGS,
  490. "no permission to write the sync settings");
  491. SyncStorageEngine.EndPoint info;
  492. info = new SyncStorageEngine.EndPoint(
  493. request.getAccount(), request.getProvider(), userId);
  494. runAtTime = clampPeriod(runAtTime);
  495. // Schedule periodic sync.
  496. getSyncManager().updateOrAddPeriodicSync(info, runAtTime,
  497. flextime, extras);
  498. } else {
  499. long beforeRuntimeMillis = (flextime) * 1000;
  500. long runtimeMillis = runAtTime * 1000;
  501. syncManager.scheduleSync(
  502. request.getAccount(), userId, callerUid, request.getProvider(), extras,
  503. beforeRuntimeMillis, runtimeMillis,
  504. false /* onlyThoseWithUnknownSyncableState */);
  505. }
  506. } finally {
  507. restoreCallingIdentity(identityToken);
  508. }
  509. }
  510. /**
  511. * Clear all scheduled sync operations that match the uri and cancel the active sync
  512. * if they match the authority and account, if they are present.
  513. *
  514. * @param account filter the pending and active syncs to cancel using this account, or null.
  515. * @param authority filter the pending and active syncs to cancel using this authority, or
  516. * null.
  517. * @param cname cancel syncs running on this service, or null for provider/account.
  518. */
  519. @Override
  520. public void cancelSync(Account account, String authority, ComponentName cname) {
  521. cancelSyncAsUser(account, authority, cname, UserHandle.getCallingUserId());
  522. }
  523. /**
  524. * Clear all scheduled sync operations that match the uri and cancel the active sync
  525. * if they match the authority and account, if they are present.
  526. *
  527. * <p> If the user id supplied is different to the calling user, the caller must hold the
  528. * INTERACT_ACROSS_USERS_FULL permission.
  529. *
  530. * @param account filter the pending and active syncs to cancel using this account, or null.
  531. * @param authority filter the pending and active syncs to cancel using this authority, or
  532. * null.
  533. * @param userId the user id for which to cancel sync operations.
  534. * @param cname cancel syncs running on this service, or null for provider/account.
  535. */
  536. @Override
  537. public void cancelSyncAsUser(Account account, String authority, ComponentName cname,
  538. int userId) {
  539. if (authority != null && authority.length() == 0) {
  540. throw new IllegalArgumentException("Authority must be non-empty");
  541. }
  542. enforceCrossUserPermission(userId,
  543. "no permission to modify the sync settings for user " + userId);
  544. // This makes it so that future permission checks will be in the context of this
  545. // process rather than the caller's process. We will restore this before returning.
  546. long identityToken = clearCallingIdentity();
  547. if (cname != null) {
  548. Slog.e(TAG, "cname not null.");
  549. return;
  550. }
  551. try {
  552. SyncManager syncManager = getSyncManager();
  553. if (syncManager != null) {
  554. SyncStorageEngine.EndPoint info;
  555. info = new SyncStorageEngine.EndPoint(account, authority, userId);
  556. syncManager.clearScheduledSyncOperations(info);
  557. syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
  558. }
  559. } finally {
  560. restoreCallingIdentity(identityToken);
  561. }
  562. }
  563. @Override
  564. public void cancelRequest(SyncRequest request) {
  565. SyncManager syncManager = getSyncManager();
  566. if (syncManager == null) return;
  567. int userId = UserHandle.getCallingUserId();
  568. long identityToken = clearCallingIdentity();
  569. try {
  570. SyncStorageEngine.EndPoint info;
  571. Bundle extras = new Bundle(request.getBundle());
  572. Account account = request.getAccount();
  573. String provider = request.getProvider();
  574. info = new SyncStorageEngine.EndPoint(account, provider, userId);
  575. if (request.isPeriodic()) {
  576. // Remove periodic sync.
  577. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
  578. "no permission to write the sync settings");
  579. getSyncManager().removePeriodicSync(info, extras);
  580. }
  581. // Cancel active syncs and clear pending syncs from the queue.
  582. syncManager.cancelScheduledSyncOperation(info, extras);
  583. syncManager.cancelActiveSync(info, extras);
  584. } finally {
  585. restoreCallingIdentity(identityToken);
  586. }
  587. }
  588. /**
  589. * Get information about the SyncAdapters that are known to the system.
  590. * @return an array of SyncAdapters that have registered with the system
  591. */
  592. @Override
  593. public SyncAdapterType[] getSyncAdapterTypes() {
  594. return getSyncAdapterTypesAsUser(UserHandle.getCallingUserId());
  595. }
  596. /**
  597. * Get information about the SyncAdapters that are known to the system for a particular user.
  598. *
  599. * <p> If the user id supplied is different to the calling user, the caller must hold the
  600. * INTERACT_ACROSS_USERS_FULL permission.
  601. *
  602. * @return an array of SyncAdapters that have registered with the system
  603. */
  604. @Override
  605. public SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) {
  606. enforceCrossUserPermission(userId,
  607. "no permission to read sync settings for user " + userId);
  608. // This makes it so that future permission checks will be in the context of this
  609. // process rather than the caller's process. We will restore this before returning.
  610. final long identityToken = clearCallingIdentity();
  611. try {
  612. SyncManager syncManager = getSyncManager();
  613. return syncManager.getSyncAdapterTypes(userId);
  614. } finally {
  615. restoreCallingIdentity(identityToken);
  616. }
  617. }
  618. @Override
  619. public String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) {
  620. enforceCrossUserPermission(userId,
  621. "no permission to read sync settings for user " + userId);
  622. // This makes it so that future permission checks will be in the context of this
  623. // process rather than the caller's process. We will restore this before returning.
  624. final long identityToken = clearCallingIdentity();
  625. try {
  626. SyncManager syncManager = getSyncManager();
  627. return syncManager.getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
  628. } finally {
  629. restoreCallingIdentity(identityToken);
  630. }
  631. }
  632. @Override
  633. public boolean getSyncAutomatically(Account account, String providerName) {
  634. return getSyncAutomaticallyAsUser(account, providerName, UserHandle.getCallingUserId());
  635. }
  636. /**
  637. * If the user id supplied is different to the calling user, the caller must hold the
  638. * INTERACT_ACROSS_USERS_FULL permission.
  639. */
  640. @Override
  641. public boolean getSyncAutomaticallyAsUser(Account account, String providerName, int userId) {
  642. enforceCrossUserPermission(userId,
  643. "no permission to read the sync settings for user " + userId);
  644. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
  645. "no permission to read the sync settings");
  646. long identityToken = clearCallingIdentity();
  647. try {
  648. SyncManager syncManager = getSyncManager();
  649. if (syncManager != null) {
  650. return syncManager.getSyncStorageEngine()
  651. .getSyncAutomatically(account, userId, providerName);
  652. }
  653. } finally {
  654. restoreCallingIdentity(identityToken);
  655. }
  656. return false;
  657. }
  658. @Override
  659. public void setSyncAutomatically(Account account, String providerName, boolean sync) {
  660. setSyncAutomaticallyAsUser(account, providerName, sync, UserHandle.getCallingUserId());
  661. }
  662. @Override
  663. public void setSyncAutomaticallyAsUser(Account account, String providerName, boolean sync,
  664. int userId) {
  665. if (TextUtils.isEmpty(providerName)) {
  666. throw new IllegalArgumentException("Authority must be non-empty");
  667. }
  668. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
  669. "no permission to write the sync settings");
  670. enforceCrossUserPermission(userId,
  671. "no permission to modify the sync settings for user " + userId);
  672. long identityToken = clearCallingIdentity();
  673. try {
  674. SyncManager syncManager = getSyncManager();
  675. if (syncManager != null) {
  676. syncManager.getSyncStorageEngine().setSyncAutomatically(account, userId,
  677. providerName, sync);
  678. }
  679. } finally {
  680. restoreCallingIdentity(identityToken);
  681. }
  682. }
  683. /** Old API. Schedule periodic sync with default flexMillis time. */
  684. @Override
  685. public void addPeriodicSync(Account account, String authority, Bundle extras,
  686. long pollFrequency) {
  687. Bundle.setDefusable(extras, true);
  688. if (account == null) {
  689. throw new IllegalArgumentException("Account must not be null");
  690. }
  691. if (TextUtils.isEmpty(authority)) {
  692. throw new IllegalArgumentException("Authority must not be empty.");
  693. }
  694. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
  695. "no permission to write the sync settings");
  696. int userId = UserHandle.getCallingUserId();
  697. pollFrequency = clampPeriod(pollFrequency);
  698. long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);
  699. long identityToken = clearCallingIdentity();
  700. try {
  701. SyncStorageEngine.EndPoint info =
  702. new SyncStorageEngine.EndPoint(account, authority, userId);
  703. getSyncManager().updateOrAddPeriodicSync(info, pollFrequency,
  704. defaultFlex, extras);
  705. } finally {
  706. restoreCallingIdentity(identityToken);
  707. }
  708. }
  709. @Override
  710. public void removePeriodicSync(Account account, String authority, Bundle extras) {
  711. Bundle.setDefusable(extras, true);
  712. if (account == null) {
  713. throw new IllegalArgumentException("Account must not be null");
  714. }
  715. if (TextUtils.isEmpty(authority)) {
  716. throw new IllegalArgumentException("Authority must not be empty");
  717. }
  718. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
  719. "no permission to write the sync settings");
  720. int userId = UserHandle.getCallingUserId();
  721. long identityToken = clearCallingIdentity();
  722. try {
  723. getSyncManager()
  724. .removePeriodicSync(
  725. new SyncStorageEngine.EndPoint(account, authority, userId),
  726. extras);
  727. } finally {
  728. restoreCallingIdentity(identityToken);
  729. }
  730. }
  731. @Override
  732. public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName,
  733. ComponentName cname) {
  734. if (account == null) {
  735. throw new IllegalArgumentException("Account must not be null");
  736. }
  737. if (TextUtils.isEmpty(providerName)) {
  738. throw new IllegalArgumentException("Authority must not be empty");
  739. }
  740. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
  741. "no permission to read the sync settings");
  742. int userId = UserHandle.getCallingUserId();
  743. long identityToken = clearCallingIdentity();
  744. try {
  745. return getSyncManager().getPeriodicSyncs(
  746. new SyncStorageEngine.EndPoint(account, providerName, userId));
  747. } finally {
  748. restoreCallingIdentity(identityToken);
  749. }
  750. }
  751. @Override
  752. public int getIsSyncable(Account account, String providerName) {
  753. return getIsSyncableAsUser(account, providerName, UserHandle.getCallingUserId());
  754. }
  755. /**
  756. * If the user id supplied is different to the calling user, the caller must hold the
  757. * INTERACT_ACROSS_USERS_FULL permission.
  758. */
  759. @Override
  760. public int getIsSyncableAsUser(Account account, String providerName, int userId) {
  761. enforceCrossUserPermission(userId,
  762. "no permission to read the sync settings for user " + userId);
  763. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
  764. "no permission to read the sync settings");
  765. long identityToken = clearCallingIdentity();
  766. try {
  767. SyncManager syncManager = getSyncManager();
  768. if (syncManager != null) {
  769. return syncManager.getIsSyncable(
  770. account, userId, providerName);
  771. }
  772. } finally {
  773. restoreCallingIdentity(identityToken);
  774. }
  775. return -1;
  776. }
  777. @Override
  778. public void setIsSyncable(Account account, String providerName, int syncable) {
  779. if (TextUtils.isEmpty(providerName)) {
  780. throw new IllegalArgumentException("Authority must not be empty");
  781. }
  782. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
  783. "no permission to write the sync settings");
  784. int userId = UserHandle.getCallingUserId();
  785. long identityToken = clearCallingIdentity();
  786. try {
  787. SyncManager syncManager = getSyncManager();
  788. if (syncManager != null) {
  789. syncManager.getSyncStorageEngine().setIsSyncable(
  790. account, userId, providerName, syncable);
  791. }
  792. } finally {
  793. restoreCallingIdentity(identityToken);
  794. }
  795. }
  796. @Override
  797. public boolean getMasterSyncAutomatically() {
  798. return getMasterSyncAutomaticallyAsUser(UserHandle.getCallingUserId());
  799. }
  800. /**
  801. * If the user id supplied is different to the calling user, the caller must hold the
  802. * INTERACT_ACROSS_USERS_FULL permission.
  803. */
  804. @Override
  805. public boolean getMasterSyncAutomaticallyAsUser(int userId) {
  806. enforceCrossUserPermission(userId,
  807. "no permission to read the sync settings for user " + userId);
  808. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
  809. "no permission to read the sync settings");
  810. long identityToken = clearCallingIdentity();
  811. try {
  812. SyncManager syncManager = getSyncManager();
  813. if (syncManager != null) {
  814. return syncManager.getSyncStorageEngine().getMasterSyncAutomatically(userId);
  815. }
  816. } finally {
  817. restoreCallingIdentity(identityToken);
  818. }
  819. return false;
  820. }
  821. @Override
  822. public void setMasterSyncAutomatically(boolean flag) {
  823. setMasterSyncAutomaticallyAsUser(flag, UserHandle.getCallingUserId());
  824. }
  825. @Override
  826. public void setMasterSyncAutomaticallyAsUser(boolean flag, int userId) {
  827. enforceCrossUserPermission(userId,
  828. "no permission to set the sync status for user " + userId);
  829. mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
  830. "no permission to write the sync settings");
  831. long identityToken = clearCallingIdentity();
  832. try {
  833. SyncManager syncManager = getSyncManager();
  834. if (syncManager != null) {
  835. syncManager.getSyncStorageEngine().setMasterSyncAutomatically(flag, userId);
  836. }
  837. } finally {
  838. restoreCallingIdentity(identityToken);
  839. }
  840. }
  841. @Override
  842. public boolean isSyncActive(Account account, String authority, ComponentName cname) {
  843. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
  844. "no permission to read the sync stats");
  845. int userId = UserHandle.getCallingUserId();
  846. long identityToken = clearCallingIdentity();
  847. try {
  848. SyncManager syncManager = getSyncManager();
  849. if (syncManager == null) {
  850. return false;
  851. }
  852. return syncManager.getSyncStorageEngine().isSyncActive(
  853. new SyncStorageEngine.EndPoint(account, authority, userId));
  854. } finally {
  855. restoreCallingIdentity(identityToken);
  856. }
  857. }
  858. @Override
  859. public List<SyncInfo> getCurrentSyncs() {
  860. return getCurrentSyncsAsUser(UserHandle.getCallingUserId());
  861. }
  862. /**
  863. * If the user id supplied is different to the calling user, the caller must hold the
  864. * INTERACT_ACROSS_USERS_FULL permission.
  865. */
  866. @Override
  867. public List<SyncInfo> getCurrentSyncsAsUser(int userId) {
  868. enforceCrossUserPermission(userId,
  869. "no permission to read the sync settings for user " + userId);
  870. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
  871. "no permission to read the sync stats");
  872. final boolean canAccessAccounts =
  873. mContext.checkCallingOrSelfPermission(Manifest.permission.GET_ACCOUNTS)
  874. == PackageManager.PERMISSION_GRANTED;
  875. long identityToken = clearCallingIdentity();
  876. try {
  877. return getSyncManager().getSyncStorageEngine()
  878. .getCurrentSyncsCopy(userId, canAccessAccounts);
  879. } finally {
  880. restoreCallingIdentity(identityToken);
  881. }
  882. }
  883. @Override
  884. public SyncStatusInfo getSyncStatus(Account account, String authority, ComponentName cname) {
  885. return getSyncStatusAsUser(account, authority, cname, UserHandle.getCallingUserId());
  886. }
  887. /**
  888. * If the user id supplied is different to the calling user, the caller must hold the
  889. * INTERACT_ACROSS_USERS_FULL permission.
  890. */
  891. @Override
  892. public SyncStatusInfo getSyncStatusAsUser(Account account, String authority,
  893. ComponentName cname, int userId) {
  894. if (TextUtils.isEmpty(authority)) {
  895. throw new IllegalArgumentException("Authority must not be empty");
  896. }
  897. enforceCrossUserPermission(userId,
  898. "no permission to read the sync stats for user " + userId);
  899. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
  900. "no permission to read the sync stats");
  901. long identityToken = clearCallingIdentity();
  902. try {
  903. SyncManager syncManager = getSyncManager();
  904. if (syncManager == null) {
  905. return null;
  906. }
  907. SyncStorageEngine.EndPoint info;
  908. if (!(account == null || authority == null)) {
  909. info = new SyncStorageEngine.EndPoint(account, authority, userId);
  910. } else {
  911. throw new IllegalArgumentException("Must call sync status with valid authority");
  912. }
  913. return syncManager.getSyncStorageEngine().getStatusByAuthority(info);
  914. } finally {
  915. restoreCallingIdentity(identityToken);
  916. }
  917. }
  918. @Override
  919. public boolean isSyncPending(Account account, String authority, ComponentName cname) {
  920. return isSyncPendingAsUser(account, authority, cname, UserHandle.getCallingUserId());
  921. }
  922. @Override
  923. public boolean isSyncPendingAsUser(Account account, String authority, ComponentName cname,
  924. int userId) {
  925. mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
  926. "no permission to read the sync stats");
  927. enforceCrossUserPermission(userId,
  928. "no permission to retrieve the sync settings for user " + userId);
  929. long identityToken = clearCallingIdentity();
  930. SyncManager syncManager = getSyncManager();
  931. if (syncManager == null) return false;
  932. try {
  933. SyncStorageEngine.EndPoint info;
  934. if (!(account == null || authority == null)) {
  935. info = new SyncStorageEngine.EndPoint(account, authority, userId);
  936. } else {
  937. throw new IllegalArgumentException("Invalid authority specified");
  938. }
  939. return syncManager.getSyncStorageEngine().isSyncPending(info);
  940. } finally {
  941. restoreCallingIdentity(identityToken);
  942. }
  943. }
  944. @Override
  945. public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
  946. long identityToken = clearCallingIdentity();
  947. try {
  948. SyncManager syncManager = getSyncManager();
  949. if (syncManager != null && callback != null) {
  950. syncManager.getSyncStorageEngine().addStatusChangeListener(mask, callback);
  951. }
  952. } finally {
  953. restoreCallingIdentity(identityToken);
  954. }
  955. }
  956. @Override
  957. public void removeStatusChangeListener(ISyncStatusObserver callback) {
  958. long identityToken = clearCallingIdentity();
  959. try {
  960. SyncManager syncManager = getSyncManager();
  961. if (syncManager != null && callback != null) {
  962. syncManager.getSyncStorageEngine().removeStatusChangeListener(callback);
  963. }
  964. } finally {
  965. restoreCallingIdentity(identityToken);
  966. }
  967. }
  968. private @Nullable String getProviderPackageName(Uri uri) {
  969. final ProviderInfo pi = mContext.getPackageManager()
  970. .resolveContentProvider(uri.getAuthority(), 0);
  971. return (pi != null) ? pi.packageName : null;
  972. }
  973. private ArrayMap<Pair<String, Uri>, Bundle> findOrCreateCacheLocked(int userId,
  974. String providerPackageName) {
  975. ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>> userCache = mCache.get(userId);
  976. if (userCache == null) {
  977. userCache = new ArrayMap<>();
  978. mCache.put(userId, userCache);
  979. }
  980. ArrayMap<Pair<String, Uri>, Bundle> packageCache = userCache.get(providerPackageName);
  981. if (packageCache == null) {
  982. packageCache = new ArrayMap<>();
  983. userCache.put(providerPackageName, packageCache);
  984. }
  985. return packageCache;
  986. }
  987. private void invalidateCacheLocked(int userId, String providerPackageName, Uri uri) {
  988. ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>> userCache = mCache.get(userId);
  989. if (userCache == null) return;
  990. ArrayMap<Pair<String, Uri>, Bundle> packageCache = userCache.get(providerPackageName);
  991. if (packageCache == null) return;
  992. if (uri != null) {
  993. for (int i = 0; i < packageCache.size();) {
  994. final Pair<String, Uri> key = packageCache.keyAt(i);
  995. if (key.second != null && key.second.toString().startsWith(uri.toString())) {
  996. if (DEBUG) Slog.d(TAG, "Invalidating cache for key " + key);
  997. packageCache.removeAt(i);
  998. } else {
  999. i++;
  1000. }
  1001. }
  1002. } else {
  1003. if (DEBUG) Slog.d(TAG, "Invalidating cache for package " + providerPackageName);
  1004. packageCache.clear();
  1005. }
  1006. }
  1007. @Override
  1008. public void putCache(String packageName, Uri key, Bundle value, int userId) {
  1009. Bundle.setDefusable(value, true);
  1010. enforceCrossUserPermission(userId, TAG);
  1011. mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG);
  1012. mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
  1013. packageName);
  1014. final String providerPackageName = getProviderPackageName(key);
  1015. final Pair<String, Uri> fullKey = Pair.create(packageName, key);
  1016. synchronized (mCache) {
  1017. final ArrayMap<Pair<String, Uri>, Bundle> cache = findOrCreateCacheLocked(userId,
  1018. providerPackageName);
  1019. if (value != null) {
  1020. cache.put(fullKey, value);
  1021. } else {
  1022. cache.remove(fullKey);
  1023. }
  1024. }
  1025. }
  1026. @Override
  1027. public Bundle getCache(String packageName, Uri key, int userId) {
  1028. enforceCrossUserPermission(userId, TAG);
  1029. mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG);
  1030. mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
  1031. packageName);
  1032. final String providerPackageName = getProviderPackageName(key);
  1033. final Pair<String, Uri> fullKey = Pair.create(packageName, key);
  1034. synchronized (mCache) {
  1035. final ArrayMap<Pair<String, Uri>, Bundle> cache = findOrCreateCacheLocked(userId,
  1036. providerPackageName);
  1037. return cache.get(fullKey);
  1038. }
  1039. }
  1040. /**
  1041. * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS_FULL
  1042. * permission, if the userHandle is not for the caller.
  1043. *
  1044. * @param userHandle the user handle of the user we want to act on behalf of.
  1045. * @param message the message to log on security exception.
  1046. */
  1047. private void enforceCrossUserPermission(int userHandle, String message) {
  1048. final int callingUser = UserHandle.getCallingUserId();
  1049. if (callingUser != userHandle) {
  1050. mContext.enforceCallingOrSelfPermission(
  1051. Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
  1052. }
  1053. }
  1054. /**
  1055. * Hide this class since it is not part of api,
  1056. * but current unittest framework requires it to be public
  1057. * @hide
  1058. */
  1059. public static final class ObserverNode {
  1060. private class ObserverEntry implements IBinder.DeathRecipient {
  1061. public final IContentObserver observer;
  1062. public final int uid;
  1063. public final int pid;
  1064. public final boolean notifyForDescendants;
  1065. private final int userHandle;
  1066. private final Object observersLock;
  1067. public ObserverEntry(IContentObserver o, boolean n, Object observersLock,
  1068. int _uid, int _pid, int _userHandle) {
  1069. this.observersLock = observersLock;
  1070. observer = o;
  1071. uid = _uid;
  1072. pid = _pid;
  1073. userHandle = _userHandle;
  1074. notifyForDescendants = n;
  1075. try {
  1076. observer.asBinder().linkToDeath(this, 0);
  1077. } catch (RemoteException e) {
  1078. binderDied();
  1079. }
  1080. }
  1081. @Override
  1082. public void binderDied() {
  1083. synchronized (observersLock) {
  1084. removeObserverLocked(observer);
  1085. }
  1086. }
  1087. public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
  1088. String name, String prefix, SparseIntArray pidCounts) {
  1089. pidCounts.put(pid, pidCounts.get(pid)+1);
  1090. pw.print(prefix); pw.print(name); pw.print(": pid=");
  1091. pw.print(pid); pw.print(" uid=");
  1092. pw.print(uid); pw.print(" user=");
  1093. pw.print(userHandle); pw.print(" target=");
  1094. pw.println(Integer.toHexString(System.identityHashCode(
  1095. observer != null ? observer.asBinder() : null)));
  1096. }
  1097. }
  1098. public static final int INSERT_TYPE = 0;
  1099. public static final int UPDATE_TYPE = 1;
  1100. public static final int DELETE_TYPE = 2;