ContentService.java revision b752098e8d12d6e7925d97458078dbb896ca8a05
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; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 25231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.Parcel; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.Manifest; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 39231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornpublic final class ContentService extends IContentService.Stub { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentService"; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFactoryTest; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ObserverNode mRootNode = new ObserverNode(""); 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SyncManager mSyncManager = null; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Object mSyncManagerLock = new Object(); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SyncManager getSyncManager() { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mSyncManagerLock) { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try to create the SyncManager, return null if it fails (e.g. the disk is full). 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SQLiteException e) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Can't create SyncManager", e); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSyncManager; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP, 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "caller doesn't have the DUMP permission"); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSyncManager == null) { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("No SyncManager created! (Disk full?)"); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSyncManager.dump(fd, pw); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn @Override 79231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 80231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn throws RemoteException { 81231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 82231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return super.onTransact(code, data, reply, flags); 83231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } catch (RuntimeException e) { 84231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // The content service only throws security exceptions, so let's 85231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn // log all others. 86231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (!(e instanceof SecurityException)) { 87231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn Log.e(TAG, "Content Service Crash", e); 88231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 89231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn throw e; 90231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 91231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 92231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*package*/ ContentService(Context context, boolean factoryTest) { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFactoryTest = factoryTest; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getSyncManager(); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void registerContentObserver(Uri uri, boolean notifyForDescendents, 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver observer) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer == null || uri == null) { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("You must pass a valid uri and observer"); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootNode.addObserver(uri, observer, notifyForDescendents); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "Registered observer " + observer + " at " + uri + 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " with notifyForDescendents " + notifyForDescendents); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterContentObserver(IContentObserver observer) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (observer == null) { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("You must pass a valid observer"); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootNode.removeObserver(observer); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "Unregistered observer " + observer); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, IContentObserver observer, 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean observerWantsSelfNotifications, boolean syncToNetwork) { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "Notifying update of " + uri + " from observer " + observer 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", syncToNetwork " + syncToNetwork); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRootNode.collectObservers(uri, 0, observer, observerWantsSelfNotifications, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calls); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numCalls = calls.size(); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<numCalls; i++) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverCall oc = calls.get(i); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oc.mObserver.onChange(oc.mSelfNotify); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException ex) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mRootNode) { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Found dead observer, removing"); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder binder = oc.mObserver.asBinder(); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<ObserverNode.ObserverEntry> list 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = oc.mNode.mObservers; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numList = list.size(); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0; j<numList; j++) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode.ObserverEntry oe = list.get(j); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oe.observer.asBinder() == binder) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.remove(j); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j--; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numList--; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (syncToNetwork) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncManager syncManager = getSyncManager(); 164ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (syncManager != null) { 165ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.scheduleLocalSync(null /* all accounts */, uri.getAuthority()); 166ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hide this class since it is not part of api, 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but current unittest framework requires it to be public 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final class ObserverCall { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ObserverNode mNode; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IContentObserver mObserver; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean mSelfNotify; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverCall(ObserverNode node, IContentObserver observer, 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selfNotify) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNode = node; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mObserver = observer; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSelfNotify = selfNotify; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 192ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void requestSync(Account account, String authority, Bundle extras) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.validateSyncExtrasBundle(extras); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncManager syncManager = getSyncManager(); 199ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (syncManager != null) { 2004a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana syncManager.scheduleSync(account, authority, extras, 0 /* no delay */, 2014a6679b97e0285c5b65ec5c0d9080ff90d3e9e81Fred Quintana false /* onlyThoseWithUnkownSyncableState */); 202ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Clear all scheduled sync operations that match the uri and cancel the active sync 210ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * if they match the authority and account, if they are present. 211ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filter the pending and active syncs to cancel using this account 212ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filter the pending and active syncs to cancel using this authority 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 214ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void cancelSync(Account account, String authority) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This makes it so that future permission checks will be in the context of this 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // process rather than the caller's process. We will restore this before returning. 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identityToken = clearCallingIdentity(); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SyncManager syncManager = getSyncManager(); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (syncManager != null) { 221ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.clearScheduledSyncOperations(account, authority); 222ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.cancelActiveSync(account, authority); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project restoreCallingIdentity(identityToken); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 230ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 231ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 232ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 233ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public SyncAdapterType[] getSyncAdapterTypes() { 234ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // This makes it so that future permission checks will be in the context of this 235ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // process rather than the caller's process. We will restore this before returning. 236ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana long identityToken = clearCallingIdentity(); 237ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 238ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana SyncManager syncManager = getSyncManager(); 239ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncAdapterTypes(); 240ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } finally { 241ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana restoreCallingIdentity(identityToken); 242ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 243ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 244b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 245ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public boolean getSyncAutomatically(Account account, String providerName) { 246231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS, 247231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync settings"); 248231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 249231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 250231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 251231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 252ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncStorageEngine().getSyncAutomatically( 253ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana account, providerName); 254231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 255231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 256231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 257231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 258231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 259231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 260231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 261ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void setSyncAutomatically(Account account, String providerName, boolean sync) { 262231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 263231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to write the sync settings"); 264231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 265231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 266231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 267231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 268ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().setSyncAutomatically( 269ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana account, providerName, sync); 270231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 271231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 272231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 273231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 274231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 275231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 2765e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana public int getIsSyncable(Account account, String providerName) { 2775e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS, 2785e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana "no permission to read the sync settings"); 2795e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana long identityToken = clearCallingIdentity(); 2805e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 2815e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana SyncManager syncManager = getSyncManager(); 2825e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (syncManager != null) { 2835e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return syncManager.getSyncStorageEngine().getIsSyncable( 2845e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana account, providerName); 2855e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 2865e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } finally { 2875e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana restoreCallingIdentity(identityToken); 2885e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 2895e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return -1; 2905e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 2915e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 2925e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana public void setIsSyncable(Account account, String providerName, int syncable) { 2935e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 2945e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana "no permission to write the sync settings"); 2955e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana long identityToken = clearCallingIdentity(); 2965e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 2975e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana SyncManager syncManager = getSyncManager(); 2985e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana if (syncManager != null) { 2995e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana syncManager.getSyncStorageEngine().setIsSyncable( 3005e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana account, providerName, syncable); 3015e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3025e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } finally { 3035e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana restoreCallingIdentity(identityToken); 3045e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3055e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 3065e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 307ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public boolean getMasterSyncAutomatically() { 308231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS, 309231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync settings"); 310231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 311231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 312231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 313231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 314ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncStorageEngine().getMasterSyncAutomatically(); 315231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 316231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 317231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 318231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 319231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 320231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 321b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 322ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void setMasterSyncAutomatically(boolean flag) { 323231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS, 324231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to write the sync settings"); 325231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 326231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 327231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 328231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 329ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().setMasterSyncAutomatically(flag); 330231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 331231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 332231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 333231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 334231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 335231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 3367a1355950172b7a549820e9a2cd4a9b2099ec32fDianne Hackborn public boolean isSyncActive(Account account, String authority) { 337231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 338231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 339231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 340231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 341231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 342231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 343231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return syncManager.getSyncStorageEngine().isSyncActive( 344231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn account, authority); 345231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 346231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 347231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 348231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 349231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 350231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 351b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 352231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ActiveSyncInfo getActiveSync() { 353231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 354231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 355231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 356231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 357231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 358231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 359231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return syncManager.getSyncStorageEngine().getActiveSync(); 360231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 361231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 362231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 363231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 364231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return null; 365231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 366b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 367ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public SyncStatusInfo getSyncStatus(Account account, String authority) { 368231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 369231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 370231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 371231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 372231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 373231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 374b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache return syncManager.getSyncStorageEngine().getStatusByAccountAndAuthority( 375b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache account, authority); 376231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 377231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 378231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 379231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 380231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return null; 381231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 382b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 383ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public boolean isSyncPending(Account account, String authority) { 384231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS, 385231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn "no permission to read the sync stats"); 386231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 387231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 388231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 389231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 390ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return syncManager.getSyncStorageEngine().isSyncPending(account, authority); 391231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 392231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 393231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 394231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 395231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return false; 396231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 397b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 398231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void addStatusChangeListener(int mask, ISyncStatusObserver callback) { 399231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 400231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 401231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 402231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 403ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().addStatusChangeListener(mask, callback); 404231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 405231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 406231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 407231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 408231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 409b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 410231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public void removeStatusChangeListener(ISyncStatusObserver callback) { 411231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn long identityToken = clearCallingIdentity(); 412231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn try { 413231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn SyncManager syncManager = getSyncManager(); 414231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (syncManager != null) { 415ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana syncManager.getSyncStorageEngine().removeStatusChangeListener(callback); 416231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 417231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } finally { 418231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn restoreCallingIdentity(identityToken); 419231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 420231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 421b752098e8d12d6e7925d97458078dbb896ca8a05Costin Manolache 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static IContentService main(Context context, boolean factoryTest) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentService service = new ContentService(context, factoryTest); 424231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return service; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hide this class since it is not part of api, 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but current unittest framework requires it to be public 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final class ObserverNode { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class ObserverEntry implements IBinder.DeathRecipient { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public IContentObserver observer; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean notifyForDescendents; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ObserverEntry(IContentObserver o, boolean n) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer = o; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyForDescendents = n; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer.asBinder().linkToDeath(this, 0); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binderDied(); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeObserver(observer); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INSERT_TYPE = 0; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int UPDATE_TYPE = 1; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DELETE_TYPE = 2; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mName; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<ObserverNode> mChildren = new ArrayList<ObserverNode>(); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<ObserverEntry> mObservers = new ArrayList<ObserverEntry>(); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ObserverNode(String name) { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mName = name; 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String getUriSegment(Uri uri, int index) { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (uri != null) { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == 0) { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return uri.getAuthority(); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return uri.getPathSegments().get(index - 1); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int countUriSegments(Uri uri) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (uri == null) { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return uri.getPathSegments().size() + 1; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addObserver(Uri uri, IContentObserver observer, boolean notifyForDescendents) { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addObserver(uri, 0, observer, notifyForDescendents); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void addObserver(Uri uri, int index, IContentObserver observer, 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean notifyForDescendents) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this is the leaf node add the observer 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == countUriSegments(uri)) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mObservers.add(new ObserverEntry(observer, notifyForDescendents)); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Look to see if the proper child already exists 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String segment = getUriSegment(uri, index); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mChildren.size(); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode node = mChildren.get(i); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (node.mName.equals(segment)) { 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.addObserver(uri, index + 1, observer, notifyForDescendents); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No child found, create one 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode node = new ObserverNode(segment); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.add(node); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.addObserver(uri, index + 1, observer, notifyForDescendents); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean removeObserver(IContentObserver observer) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mChildren.size(); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean empty = mChildren.get(i).removeObserver(observer); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (empty) { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChildren.remove(i); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i--; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder observerBinder = observer.asBinder(); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = mObservers.size(); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverEntry entry = mObservers.get(i); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entry.observer.asBinder() == observerBinder) { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mObservers.remove(i); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We no longer need to listen for death notifications. Remove it. 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observerBinder.unlinkToDeath(entry, 0); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mChildren.size() == 0 && mObservers.size() == 0) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void collectMyObservers(Uri uri, 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean leaf, IContentObserver observer, boolean selfNotify, 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<ObserverCall> calls) 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mObservers.size(); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder observerBinder = observer == null ? null : observer.asBinder(); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverEntry entry = mObservers.get(i); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't notify the observer if it sent the notification and isn't interesed 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in self notifications 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entry.observer.asBinder() == observerBinder && !selfNotify) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure the observer is interested in the notification 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leaf || (!leaf && entry.notifyForDescendents)) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calls.add(new ObserverCall(this, entry.observer, selfNotify)); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void collectObservers(Uri uri, int index, IContentObserver observer, 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selfNotify, ArrayList<ObserverCall> calls) { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String segment = null; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int segmentCount = countUriSegments(uri); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= segmentCount) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is the leaf node, notify all observers 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project collectMyObservers(uri, true, observer, selfNotify, calls); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (index < segmentCount){ 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project segment = getUriSegment(uri, index); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Notify any observers at this level who are interested in descendents 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project collectMyObservers(uri, false, observer, selfNotify, calls); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mChildren.size(); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ObserverNode node = mChildren.get(i); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (segment == null || node.mName.equals(segment)) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We found the child, 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project node.collectObservers(uri, index + 1, observer, selfNotify, calls); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (segment != null) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 592