Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b94761d0 authored by Amith Yamasani's avatar Amith Yamasani Committed by Android (Google) Code Review
Browse files

Merge "App Standby : Association between content providers and their sync adapter" into mnc-dev

parents a36de70a 37a40c24
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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.
     */
+15 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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.
+62 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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);
    }
@@ -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);
+10 −2
Original line number Diff line number Diff line
@@ -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);
@@ -232,6 +232,7 @@ public abstract class RegisteredServicesCache<V> {
        synchronized (mServicesLock) {
            final UserServices<V> user = findOrCreateUserLocked(userId);
            user.services = null;
            onServicesChangedLocked(userId);
        }
    }

@@ -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.
@@ -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