ContentService.java revision 86de0590b94bcce27e3038c27464bed510bb564a
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 197a1355950172b7a549820e9a2cd4a9b2099ec32fDianne Hackbornimport android.accounts.Account; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.sqlite.SQLiteException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 231b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackbornimport android.os.Binder; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 26231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.Parcel; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 301b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackbornimport android.util.SparseIntArray; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.Manifest; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 361b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackbornimport java.util.Collections; 371b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackbornimport java.util.Comparator; 38c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintanaimport java.util.List; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 43231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornpublic final class ContentService extends IContentService.Stub { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentService"; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFactoryTest; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ObserverNode mRootNode = new ObserverNode(""); 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SyncManager mSyncManager = null; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Object mSyncManagerLock = new Object(); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SyncManager getSyncManager() { 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mSyncManagerLock) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try to create the SyncManager, return null if it fails (e.g. the disk is full). 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SQLiteException e) { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Can't create SyncManager", e); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSyncManager; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP, 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "caller doesn't have the DUMP permission"); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncManager == null) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("No SyncManager created! (Disk full?)"); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncManager.dump(fd, pw); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 771b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.println(); 781b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.println("Observer tree:"); 791b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn synchronized (mRootNode) { 801b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn int[] counts = new int[2]; 811b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn final SparseIntArray pidCounts = new SparseIntArray(); 821b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn mRootNode.dumpLocked(fd, pw, args, "", " ", counts, pidCounts); 831b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.println(); 841b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn ArrayList<Integer> sorted = new ArrayList<Integer>(); 851b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn for (int i=0; i<pidCounts.size(); i++) { 861b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn sorted.add(pidCounts.keyAt(i)); 871b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 881b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn Collections.sort(sorted, new Comparator<Integer>() { 891b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn @Override 901b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn public int compare(Integer lhs, Integer rhs) { 911b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn int lc = pidCounts.get(lhs); 921b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn int rc = pidCounts.get(rhs); 931b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn if (lc < rc) { 941b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn return 1; 951b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } else if (lc > rc) { 961b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn return -1; 971b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 981b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn return 0; 991b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 1001b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn 1011b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn }); 1021b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn for (int i=0; i<sorted.size(); i++) { 1031b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn int pid = sorted.get(i); 1041b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.print(" pid "); pw.print(pid); pw.print(": "); 1051b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.print(pidCounts.get(pid)); pw.println(" observers"); 1061b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 1071b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.println(); 1081b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.print(" Total number of nodes: "); pw.println(counts[0]); 1091b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.print(" Total number of observers: "); pw.println(counts[1]); 1101b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 116231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn @Override 117231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 118231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn throws RemoteException { 119231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 120231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return super.onTransact(code, data, reply, flags); 121231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (RuntimeException e) { 122231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // The content service only throws security exceptions, so let's 123231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // log all others. 124231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (!(e instanceof SecurityException)) { 125231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.e(TAG, "Content Service Crash", e); 126231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 127231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn throw e; 128231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 129231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 130231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*package*/ ContentService(Context context, boolean factoryTest) { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFactoryTest = factoryTest; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getSyncManager(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void registerContentObserver(Uri uri, boolean notifyForDescendents, 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver observer) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer == null || uri == null) { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("You must pass a valid uri and observer"); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 1431b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn mRootNode.addObserverLocked(uri, observer, notifyForDescendents, mRootNode, 1441b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn Binder.getCallingUid(), Binder.getCallingPid()); 14543a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v(TAG, "Registered observer " + observer + " at " + uri + 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " with notifyForDescendents " + notifyForDescendents); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterContentObserver(IContentObserver observer) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer == null) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("You must pass a valid observer"); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 155002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana mRootNode.removeObserverLocked(observer); 15643a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v(TAG, "Unregistered observer " + observer); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, IContentObserver observer, 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean observerWantsSelfNotifications, boolean syncToNetwork) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "Notifying update of " + uri + " from observer " + observer 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", syncToNetwork " + syncToNetwork); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 172002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications, 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calls); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numCalls = calls.size(); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<numCalls; i++) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverCall oc = calls.get(i); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 17986de0590b94bcce27e3038c27464bed510bb564aJeff Brown oc.mObserver.onChange(oc.mSelfChange); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException ex) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Found dead observer, removing"); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder binder = oc.mObserver.asBinder(); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<ObserverNode.ObserverEntry> list 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = oc.mNode.mObservers; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numList = list.size(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0; j<numList; j++) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode.ObserverEntry oe = list.get(j); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oe.observer.asBinder() == binder) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.remove(j); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j--; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numList--; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (syncToNetwork) { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncManager syncManager = getSyncManager(); 203ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (syncManager != null) { 204ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.scheduleLocalSync(null /* all accounts */, uri.getAuthority()); 205ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hide this class since it is not part of api, 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but current unittest framework requires it to be public 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final class ObserverCall { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ObserverNode mNode; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IContentObserver mObserver; 22186de0590b94bcce27e3038c27464bed510bb564aJeff Brown final boolean mSelfChange; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22386de0590b94bcce27e3038c27464bed510bb564aJeff Brown ObserverCall(ObserverNode node, IContentObserver observer, boolean selfChange) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNode = node; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mObserver = observer; 22686de0590b94bcce27e3038c27464bed510bb564aJeff Brown mSelfChange = selfChange; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 230ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void requestSync(Account account, String authority, Bundle extras) { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.validateSyncExtrasBundle(extras); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncManager syncManager = getSyncManager(); 237ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (syncManager != null) { 2384a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana syncManager.scheduleSync(account, authority, extras, 0 /* no delay */, 2394a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana false /* onlyThoseWithUnkownSyncableState */); 240ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Clear all scheduled sync operations that match the uri and cancel the active sync 248ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * if they match the authority and account, if they are present. 249ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filter the pending and active syncs to cancel using this account 250ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filter the pending and active syncs to cancel using this authority 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 252ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void cancelSync(Account account, String authority) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncManager syncManager = getSyncManager(); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (syncManager != null) { 259ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.clearScheduledSyncOperations(account, authority); 260ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.cancelActiveSync(account, authority); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 267ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 268ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 269ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 270ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 271ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public SyncAdapterType[] getSyncAdapterTypes() { 272ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // This makes it so that future permission checks will be in the context of this 273ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // process rather than the caller's process. We will restore this before returning. 274ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana long identityToken = clearCallingIdentity(); 275ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 276ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana SyncManager syncManager = getSyncManager(); 277ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncAdapterTypes(); 278ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } finally { 279ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana restoreCallingIdentity(identityToken); 280ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 281ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 282b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 283ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public boolean getSyncAutomatically(Account account, String providerName) { 284231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS, 285231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync settings"); 286231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 287231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 288231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 289231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 290ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncStorageEngine().getSyncAutomatically( 291ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana account, providerName); 292231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 293231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 294231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 295231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 296231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 297231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 298231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 299ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void setSyncAutomatically(Account account, String providerName, boolean sync) { 300231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 301231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to write the sync settings"); 302231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 303231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 304231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 305231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 306ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().setSyncAutomatically( 307ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana account, providerName, sync); 308231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 309231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 310231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 311231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 312231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 313231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 314c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public void addPeriodicSync(Account account, String authority, Bundle extras, 315c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long pollFrequency) { 316c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 317c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana "no permission to write the sync settings"); 318c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long identityToken = clearCallingIdentity(); 319c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 320c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getSyncManager().getSyncStorageEngine().addPeriodicSync( 321c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana account, authority, extras, pollFrequency); 322c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } finally { 323c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana restoreCallingIdentity(identityToken); 324c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 325c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 326c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 327c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public void removePeriodicSync(Account account, String authority, Bundle extras) { 328c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 329c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana "no permission to write the sync settings"); 330c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long identityToken = clearCallingIdentity(); 331c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 332c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana getSyncManager().getSyncStorageEngine().removePeriodicSync(account, authority, extras); 333c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } finally { 334c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana restoreCallingIdentity(identityToken); 335c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 336c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 337c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 338c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName) { 339c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS, 340c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana "no permission to read the sync settings"); 341c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana long identityToken = clearCallingIdentity(); 342c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana try { 343c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana return getSyncManager().getSyncStorageEngine().getPeriodicSyncs( 344c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana account, providerName); 345c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } finally { 346c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana restoreCallingIdentity(identityToken); 347c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 348c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana } 349c5d1c6db61f208b206b260f897bb5bbc64be4d97Fred Quintana 3505e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana public int getIsSyncable(Account account, String providerName) { 3515e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS, 3525e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana "no permission to read the sync settings"); 3535e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana long identityToken = clearCallingIdentity(); 3545e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 3555e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana SyncManager syncManager = getSyncManager(); 3565e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (syncManager != null) { 3575e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return syncManager.getSyncStorageEngine().getIsSyncable( 3585e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana account, providerName); 3595e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3605e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } finally { 3615e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana restoreCallingIdentity(identityToken); 3625e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3635e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return -1; 3645e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3655e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 3665e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana public void setIsSyncable(Account account, String providerName, int syncable) { 3675e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 3685e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana "no permission to write the sync settings"); 3695e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana long identityToken = clearCallingIdentity(); 3705e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 3715e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana SyncManager syncManager = getSyncManager(); 3725e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (syncManager != null) { 3735e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana syncManager.getSyncStorageEngine().setIsSyncable( 3745e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana account, providerName, syncable); 3755e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3765e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } finally { 3775e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana restoreCallingIdentity(identityToken); 3785e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3795e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3805e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 381ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public boolean getMasterSyncAutomatically() { 382231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS, 383231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync settings"); 384231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 385231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 386231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 387231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 388ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncStorageEngine().getMasterSyncAutomatically(); 389231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 390231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 391231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 392231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 393231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 394231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 395b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 396ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void setMasterSyncAutomatically(boolean flag) { 397231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 398231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to write the sync settings"); 399231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 400231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 401231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 402231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 403ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().setMasterSyncAutomatically(flag); 404231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 405231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 406231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 407231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 408231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 409231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 4107a1355950172b7a549820e9a2cd4a9b2099ec32fDianne Hackborn public boolean isSyncActive(Account account, String authority) { 411231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 412231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 413231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 414231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 415231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 416231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 417231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return syncManager.getSyncStorageEngine().isSyncActive( 418231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn account, authority); 419231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 420231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 421231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 422231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 423231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 424231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 425b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 426c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana public List<SyncInfo> getCurrentSyncs() { 427231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 428231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 429231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 430231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 431c6a69559cb62bd20166c0c9684e64c60d779da38Fred Quintana return getSyncManager().getSyncStorageEngine().getCurrentSyncs(); 432231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 433231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 434231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 435231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 436b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 437ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public SyncStatusInfo getSyncStatus(Account account, String authority) { 438231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 439231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 440231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 441231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 442231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 443231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 444b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache return syncManager.getSyncStorageEngine().getStatusByAccountAndAuthority( 445b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache account, authority); 446231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 447231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 448231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 449231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 450231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return null; 451231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 452b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 453ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public boolean isSyncPending(Account account, String authority) { 454231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 455231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 456231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 457231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 458231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 459231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 460ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncStorageEngine().isSyncPending(account, authority); 461231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 462231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 463231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 464231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 465231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 466231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 467b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 468231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void addStatusChangeListener(int mask, ISyncStatusObserver callback) { 469231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 470231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 471231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 4721b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (syncManager != null && callback != null) { 473ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().addStatusChangeListener(mask, callback); 474231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 475231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 476231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 477231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 478231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 479b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 480231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void removeStatusChangeListener(ISyncStatusObserver callback) { 481231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 482231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 483231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 4841b487ec44b6b5594914d52fa427bec4f29a60541Fred Quintana if (syncManager != null && callback != null) { 485ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().removeStatusChangeListener(callback); 486231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 487231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 488231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 489231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 490231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 491b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static IContentService main(Context context, boolean factoryTest) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentService service = new ContentService(context, factoryTest); 494231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return service; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hide this class since it is not part of api, 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but current unittest framework requires it to be public 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final class ObserverNode { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class ObserverEntry implements IBinder.DeathRecipient { 505002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana public final IContentObserver observer; 5061b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn public final int uid; 5071b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn public final int pid; 508002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana public final boolean notifyForDescendents; 509002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana private final Object observersLock; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5111b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn public ObserverEntry(IContentObserver o, boolean n, Object observersLock, 5121b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn int _uid, int _pid) { 513002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana this.observersLock = observersLock; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer = o; 5151b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn uid = _uid; 5161b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pid = _pid; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyForDescendents = n; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer.asBinder().linkToDeath(this, 0); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binderDied(); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 526002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana synchronized (observersLock) { 527002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana removeObserverLocked(observer); 528002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5301b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn 5311b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args, 5321b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn String name, String prefix, SparseIntArray pidCounts) { 5331b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pidCounts.put(pid, pidCounts.get(pid)+1); 5341b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.print(prefix); pw.print(name); pw.print(": pid="); 5351b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.print(pid); pw.print(" uid="); 5361b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.print(uid); pw.print(" target="); 5371b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pw.println(Integer.toHexString(System.identityHashCode( 5381b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn observer != null ? observer.asBinder() : null))); 5391b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INSERT_TYPE = 0; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int UPDATE_TYPE = 1; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DELETE_TYPE = 2; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mName; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<ObserverNode> mChildren = new ArrayList<ObserverNode>(); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<ObserverEntry> mObservers = new ArrayList<ObserverEntry>(); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ObserverNode(String name) { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mName = name; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5541b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args, 5551b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn String name, String prefix, int[] counts, SparseIntArray pidCounts) { 5561b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn String innerName = null; 5571b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn if (mObservers.size() > 0) { 5581b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn if ("".equals(name)) { 5591b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn innerName = mName; 5601b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } else { 5611b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn innerName = name + "/" + mName; 5621b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5631b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn for (int i=0; i<mObservers.size(); i++) { 5641b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn counts[1]++; 5651b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn mObservers.get(i).dumpLocked(fd, pw, args, innerName, prefix, 5661b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn pidCounts); 5671b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5681b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5691b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn if (mChildren.size() > 0) { 5701b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn if (innerName == null) { 5711b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn if ("".equals(name)) { 5721b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn innerName = mName; 5731b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } else { 5741b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn innerName = name + "/" + mName; 5751b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5761b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5771b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn for (int i=0; i<mChildren.size(); i++) { 5781b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn counts[0]++; 5791b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn mChildren.get(i).dumpLocked(fd, pw, args, innerName, prefix, 5801b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn counts, pidCounts); 5811b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5821b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5831b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn } 5841b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String getUriSegment(Uri uri, int index) { 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (uri != null) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == 0) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return uri.getAuthority(); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return uri.getPathSegments().get(index - 1); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int countUriSegments(Uri uri) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (uri == null) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return uri.getPathSegments().size() + 1; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 604002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana public void addObserverLocked(Uri uri, IContentObserver observer, 6051b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn boolean notifyForDescendents, Object observersLock, int uid, int pid) { 6061b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn addObserverLocked(uri, 0, observer, notifyForDescendents, observersLock, uid, pid); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana private void addObserverLocked(Uri uri, int index, IContentObserver observer, 6101b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn boolean notifyForDescendents, Object observersLock, int uid, int pid) { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this is the leaf node add the observer 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == countUriSegments(uri)) { 6131b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn mObservers.add(new ObserverEntry(observer, notifyForDescendents, observersLock, 6141b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn uid, pid)); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Look to see if the proper child already exists 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String segment = getUriSegment(uri, index); 620f51266471cb6c3e824435ae6e416012a62266d52Anthony Newnam if (segment == null) { 621f51266471cb6c3e824435ae6e416012a62266d52Anthony Newnam throw new IllegalArgumentException("Invalid Uri (" + uri + ") used for observer"); 622f51266471cb6c3e824435ae6e416012a62266d52Anthony Newnam } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mChildren.size(); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode node = mChildren.get(i); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (node.mName.equals(segment)) { 6271b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn node.addObserverLocked(uri, index + 1, observer, notifyForDescendents, 6281b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn observersLock, uid, pid); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No child found, create one 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode node = new ObserverNode(segment); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.add(node); 6361b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn node.addObserverLocked(uri, index + 1, observer, notifyForDescendents, 6371b64e0d8657463c0f7ce9b068a16a522cdfe7d28Dianne Hackborn observersLock, uid, pid); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 640002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana public boolean removeObserverLocked(IContentObserver observer) { 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mChildren.size(); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 643002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana boolean empty = mChildren.get(i).removeObserverLocked(observer); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (empty) { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.remove(i); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i--; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder observerBinder = observer.asBinder(); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = mObservers.size(); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverEntry entry = mObservers.get(i); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entry.observer.asBinder() == observerBinder) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mObservers.remove(i); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We no longer need to listen for death notifications. Remove it. 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observerBinder.unlinkToDeath(entry, 0); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mChildren.size() == 0 && mObservers.size() == 0) { 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana private void collectMyObserversLocked(boolean leaf, IContentObserver observer, 67086de0590b94bcce27e3038c27464bed510bb564aJeff Brown boolean observerWantsSelfNotifications, ArrayList<ObserverCall> calls) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mObservers.size(); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder observerBinder = observer == null ? null : observer.asBinder(); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverEntry entry = mObservers.get(i); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't notify the observer if it sent the notification and isn't interesed 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in self notifications 67886de0590b94bcce27e3038c27464bed510bb564aJeff Brown boolean selfChange = (entry.observer.asBinder() == observerBinder); 67986de0590b94bcce27e3038c27464bed510bb564aJeff Brown if (selfChange && !observerWantsSelfNotifications) { 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure the observer is interested in the notification 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leaf || (!leaf && entry.notifyForDescendents)) { 68586de0590b94bcce27e3038c27464bed510bb564aJeff Brown calls.add(new ObserverCall(this, entry.observer, selfChange)); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 690002ffad599964653186c01f8e07fadc82dc0aceeFred Quintana public void collectObserversLocked(Uri uri, int index, IContentObserver observer, 69186de0590b94bcce27e3038c27464bed510bb564aJeff Brown boolean observerWantsSelfNotifications, ArrayList<ObserverCall> calls) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String segment = null; 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int segmentCount = countUriSegments(uri); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= segmentCount) { 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is the leaf node, notify all observers 69686de0590b94bcce27e3038c27464bed510bb564aJeff Brown collectMyObserversLocked(true, observer, observerWantsSelfNotifications, calls); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (index < segmentCount){ 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project segment = getUriSegment(uri, index); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Notify any observers at this level who are interested in descendents 70086de0590b94bcce27e3038c27464bed510bb564aJeff Brown collectMyObserversLocked(false, observer, observerWantsSelfNotifications, calls); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mChildren.size(); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode node = mChildren.get(i); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (segment == null || node.mName.equals(segment)) { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We found the child, 70886de0590b94bcce27e3038c27464bed510bb564aJeff Brown node.collectObserversLocked(uri, index + 1, 70986de0590b94bcce27e3038c27464bed510bb564aJeff Brown observer, observerWantsSelfNotifications, calls); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (segment != null) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 718