Loading core/java/android/app/usage/UsageStatsManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,14 @@ public abstract class UsageStatsManagerInternal { */ public abstract void reportConfigurationChange(Configuration config, int userId); /** * Reports that a content provider has been accessed by a foreground app. * @param name The authority of the content provider * @param pkgName The package name of the content provider * @param userId The user in which the content provider was accessed. */ public abstract void reportContentProviderUsage(String name, String pkgName, int userId); /** * Prepares the UsageStatsService for shutdown. */ Loading core/java/android/content/ContentResolver.java +15 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.util.Log; import dalvik.system.CloseGuard; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import java.io.File; Loading @@ -57,6 +58,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; Loading Loading @@ -1935,6 +1937,19 @@ public abstract class ContentResolver { } } /** * @hide * Returns the package names of syncadapters that match a given user and authority. */ public static String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) { try { return getContentService().getSyncAdapterPackagesForAuthorityAsUser(authority, userId); } catch (RemoteException e) { } return ArrayUtils.emptyArray(String.class); } /** * Check if the provider should be synced when a network tickle is received * <p>This method requires the caller to hold the permission Loading core/java/android/content/IContentService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,8 @@ interface IContentService { SyncAdapterType[] getSyncAdapterTypes(); SyncAdapterType[] getSyncAdapterTypesAsUser(int userId); String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId); /** * Returns true if there is currently a operation for the given account/authority or service * actively being processed. Loading core/java/android/content/SyncAdaptersCache.java +62 −0 Original line number Diff line number Diff line Loading @@ -20,12 +20,19 @@ import android.content.pm.RegisteredServicesCache; import android.content.pm.XmlSerializerAndParser; import android.content.res.Resources; import android.content.res.TypedArray; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; /** * A cache of services that export the {@link android.content.ISyncAdapter} interface. Loading @@ -39,6 +46,10 @@ public class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> private static final String ATTRIBUTES_NAME = "sync-adapter"; private static final MySerializer sSerializer = new MySerializer(); @GuardedBy("mServicesLock") private SparseArray<ArrayMap<String,String[]>> mAuthorityToSyncAdapters = new SparseArray<>(); public SyncAdaptersCache(Context context) { super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, sSerializer); } Loading Loading @@ -76,6 +87,57 @@ public class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> } } @Override protected void onServicesChangedLocked(int userId) { synchronized (mServicesLock) { ArrayMap<String,String[]> adapterMap = mAuthorityToSyncAdapters.get(userId); if (adapterMap != null) { adapterMap.clear(); } } super.onServicesChangedLocked(userId); } public String[] getSyncAdapterPackagesForAuthority(String authority, int userId) { synchronized (mServicesLock) { ArrayMap<String,String[]> adapterMap = mAuthorityToSyncAdapters.get(userId); if (adapterMap == null) { adapterMap = new ArrayMap<>(); mAuthorityToSyncAdapters.put(userId, adapterMap); } // If the mapping exists, return it if (adapterMap.containsKey(authority)) { return adapterMap.get(authority); } // Create the mapping and cache it String[] syncAdapterPackages; final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> serviceInfos; serviceInfos = getAllServices(userId); ArrayList<String> packages = new ArrayList<>(); for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> serviceInfo : serviceInfos) { if (authority.equals(serviceInfo.type.authority) && serviceInfo.componentName != null) { packages.add(serviceInfo.componentName.getPackageName()); } } syncAdapterPackages = new String[packages.size()]; packages.toArray(syncAdapterPackages); adapterMap.put(authority, syncAdapterPackages); return syncAdapterPackages; } } @Override protected void onUserRemoved(int userId) { synchronized (mServicesLock) { mAuthorityToSyncAdapters.remove(userId); } super.onUserRemoved(userId); } static class MySerializer implements XmlSerializerAndParser<SyncAdapterType> { public void writeAsXml(SyncAdapterType item, XmlSerializer out) throws IOException { out.attribute(null, "authority", item.authority); Loading core/java/android/content/pm/RegisteredServicesCache.java +10 −2 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ public abstract class RegisteredServicesCache<V> { private final String mAttributesName; private final XmlSerializerAndParser<V> mSerializerAndParser; private final Object mServicesLock = new Object(); protected final Object mServicesLock = new Object(); @GuardedBy("mServicesLock") private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2); Loading Loading @@ -232,6 +232,7 @@ public abstract class RegisteredServicesCache<V> { synchronized (mServicesLock) { final UserServices<V> user = findOrCreateUserLocked(userId); user.services = null; onServicesChangedLocked(userId); } } Loading Loading @@ -489,11 +490,16 @@ public abstract class RegisteredServicesCache<V> { } } if (changed) { onServicesChangedLocked(userId); writePersistentServicesLocked(user, userId); } } } protected void onServicesChangedLocked(int userId) { // Feel free to override } /** * Returns true if the list of changed uids is null (wildcard) or the specified uid * is contained in the list of changed uids. Loading Loading @@ -687,8 +693,10 @@ public abstract class RegisteredServicesCache<V> { @VisibleForTesting protected void onUserRemoved(int userId) { synchronized (mServicesLock) { mUserServices.remove(userId); } } @VisibleForTesting protected List<UserInfo> getUsers() { Loading Loading
core/java/android/app/usage/UsageStatsManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,14 @@ public abstract class UsageStatsManagerInternal { */ public abstract void reportConfigurationChange(Configuration config, int userId); /** * Reports that a content provider has been accessed by a foreground app. * @param name The authority of the content provider * @param pkgName The package name of the content provider * @param userId The user in which the content provider was accessed. */ public abstract void reportContentProviderUsage(String name, String pkgName, int userId); /** * Prepares the UsageStatsService for shutdown. */ Loading
core/java/android/content/ContentResolver.java +15 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.util.Log; import dalvik.system.CloseGuard; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import java.io.File; Loading @@ -57,6 +58,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; Loading Loading @@ -1935,6 +1937,19 @@ public abstract class ContentResolver { } } /** * @hide * Returns the package names of syncadapters that match a given user and authority. */ public static String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId) { try { return getContentService().getSyncAdapterPackagesForAuthorityAsUser(authority, userId); } catch (RemoteException e) { } return ArrayUtils.emptyArray(String.class); } /** * Check if the provider should be synced when a network tickle is received * <p>This method requires the caller to hold the permission Loading
core/java/android/content/IContentService.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,8 @@ interface IContentService { SyncAdapterType[] getSyncAdapterTypes(); SyncAdapterType[] getSyncAdapterTypesAsUser(int userId); String[] getSyncAdapterPackagesForAuthorityAsUser(String authority, int userId); /** * Returns true if there is currently a operation for the given account/authority or service * actively being processed. Loading
core/java/android/content/SyncAdaptersCache.java +62 −0 Original line number Diff line number Diff line Loading @@ -20,12 +20,19 @@ import android.content.pm.RegisteredServicesCache; import android.content.pm.XmlSerializerAndParser; import android.content.res.Resources; import android.content.res.TypedArray; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; /** * A cache of services that export the {@link android.content.ISyncAdapter} interface. Loading @@ -39,6 +46,10 @@ public class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> private static final String ATTRIBUTES_NAME = "sync-adapter"; private static final MySerializer sSerializer = new MySerializer(); @GuardedBy("mServicesLock") private SparseArray<ArrayMap<String,String[]>> mAuthorityToSyncAdapters = new SparseArray<>(); public SyncAdaptersCache(Context context) { super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, sSerializer); } Loading Loading @@ -76,6 +87,57 @@ public class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> } } @Override protected void onServicesChangedLocked(int userId) { synchronized (mServicesLock) { ArrayMap<String,String[]> adapterMap = mAuthorityToSyncAdapters.get(userId); if (adapterMap != null) { adapterMap.clear(); } } super.onServicesChangedLocked(userId); } public String[] getSyncAdapterPackagesForAuthority(String authority, int userId) { synchronized (mServicesLock) { ArrayMap<String,String[]> adapterMap = mAuthorityToSyncAdapters.get(userId); if (adapterMap == null) { adapterMap = new ArrayMap<>(); mAuthorityToSyncAdapters.put(userId, adapterMap); } // If the mapping exists, return it if (adapterMap.containsKey(authority)) { return adapterMap.get(authority); } // Create the mapping and cache it String[] syncAdapterPackages; final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> serviceInfos; serviceInfos = getAllServices(userId); ArrayList<String> packages = new ArrayList<>(); for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> serviceInfo : serviceInfos) { if (authority.equals(serviceInfo.type.authority) && serviceInfo.componentName != null) { packages.add(serviceInfo.componentName.getPackageName()); } } syncAdapterPackages = new String[packages.size()]; packages.toArray(syncAdapterPackages); adapterMap.put(authority, syncAdapterPackages); return syncAdapterPackages; } } @Override protected void onUserRemoved(int userId) { synchronized (mServicesLock) { mAuthorityToSyncAdapters.remove(userId); } super.onUserRemoved(userId); } static class MySerializer implements XmlSerializerAndParser<SyncAdapterType> { public void writeAsXml(SyncAdapterType item, XmlSerializer out) throws IOException { out.attribute(null, "authority", item.authority); Loading
core/java/android/content/pm/RegisteredServicesCache.java +10 −2 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ public abstract class RegisteredServicesCache<V> { private final String mAttributesName; private final XmlSerializerAndParser<V> mSerializerAndParser; private final Object mServicesLock = new Object(); protected final Object mServicesLock = new Object(); @GuardedBy("mServicesLock") private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2); Loading Loading @@ -232,6 +232,7 @@ public abstract class RegisteredServicesCache<V> { synchronized (mServicesLock) { final UserServices<V> user = findOrCreateUserLocked(userId); user.services = null; onServicesChangedLocked(userId); } } Loading Loading @@ -489,11 +490,16 @@ public abstract class RegisteredServicesCache<V> { } } if (changed) { onServicesChangedLocked(userId); writePersistentServicesLocked(user, userId); } } } protected void onServicesChangedLocked(int userId) { // Feel free to override } /** * Returns true if the list of changed uids is null (wildcard) or the specified uid * is contained in the list of changed uids. Loading Loading @@ -687,8 +693,10 @@ public abstract class RegisteredServicesCache<V> { @VisibleForTesting protected void onUserRemoved(int userId) { synchronized (mServicesLock) { mUserServices.remove(userId); } } @VisibleForTesting protected List<UserInfo> getUsers() { Loading