Loading core/java/android/content/pm/RegisteredServicesCache.java +46 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.AtomicFile; import android.util.AttributeSet; import android.util.IntArray; import android.util.Log; import android.util.Slog; import android.util.SparseArray; Loading @@ -54,6 +55,7 @@ import java.io.InputStream; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; Loading Loading @@ -344,6 +346,47 @@ public abstract class RegisteredServicesCache<V> { } } public void updateServices(int userId) { if (DEBUG) { Slog.d(TAG, "updateServices u" + userId); } List<ServiceInfo<V>> allServices; synchronized (mServicesLock) { final UserServices<V> user = findOrCreateUserLocked(userId); // If services haven't been initialized yet - no updates required if (user.services == null) { return; } allServices = new ArrayList<>(user.services.values()); } IntArray updatedUids = null; for (ServiceInfo<V> service : allServices) { int versionCode = service.componentInfo.applicationInfo.versionCode; String pkg = service.componentInfo.packageName; ApplicationInfo newAppInfo = null; try { newAppInfo = mContext.getPackageManager().getApplicationInfoAsUser(pkg, 0, userId); } catch (NameNotFoundException e) { // Package uninstalled - treat as null app info } // If package updated or removed if ((newAppInfo == null) || (newAppInfo.versionCode != versionCode)) { if (DEBUG) { Slog.d(TAG, "Package " + pkg + " uid=" + service.uid + " updated. New appInfo: " + newAppInfo); } if (updatedUids == null) { updatedUids = new IntArray(); } updatedUids.add(service.uid); } } if (updatedUids != null && updatedUids.size() > 0) { int[] updatedUidsArray = updatedUids.toArray(); generateServicesMap(updatedUidsArray, userId); } } @VisibleForTesting protected boolean inSystemImage(int callerUid) { String[] packages = mContext.getPackageManager().getPackagesForUid(callerUid); Loading Loading @@ -379,10 +422,11 @@ public abstract class RegisteredServicesCache<V> { */ private void generateServicesMap(int[] changedUids, int userId) { if (DEBUG) { Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + changedUids); Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + Arrays.toString(changedUids)); } final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<ServiceInfo<V>>(); final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<>(); final List<ResolveInfo> resolveInfos = queryIntentServices(userId); for (ResolveInfo resolveInfo : resolveInfos) { try { Loading services/core/java/com/android/server/accounts/AccountManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -934,6 +934,7 @@ public class AccountManagerService * Should only be called inside of a clearCallingIdentity block. */ private AuthenticatorDescription[] getAuthenticatorTypesInternal(int userId) { mAuthenticatorCache.updateServices(userId); Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> authenticatorCollection = mAuthenticatorCache.getAllServices(userId); AuthenticatorDescription[] types = Loading @@ -947,8 +948,6 @@ public class AccountManagerService return types; } private boolean isCrossUser(int callingUid, int userId) { return (userId != UserHandle.getCallingUserId() && callingUid != Process.myUid() Loading services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java +6 −0 Original line number Diff line number Diff line Loading @@ -64,4 +64,10 @@ public interface IAccountAuthenticatorCache { Handler handler); void invalidateCache(int userId); /** * Request to update services info for which package has been updated, but hasn't been * picked up by the cache. */ void updateServices(int userId); } services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,10 @@ public class AccountManagerServiceTest extends AndroidTestCase { @Override public void invalidateCache(int userId) { } @Override public void updateServices(int userId) { } } static public class MyMockContext extends MockContext { Loading Loading
core/java/android/content/pm/RegisteredServicesCache.java +46 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.AtomicFile; import android.util.AttributeSet; import android.util.IntArray; import android.util.Log; import android.util.Slog; import android.util.SparseArray; Loading @@ -54,6 +55,7 @@ import java.io.InputStream; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; Loading Loading @@ -344,6 +346,47 @@ public abstract class RegisteredServicesCache<V> { } } public void updateServices(int userId) { if (DEBUG) { Slog.d(TAG, "updateServices u" + userId); } List<ServiceInfo<V>> allServices; synchronized (mServicesLock) { final UserServices<V> user = findOrCreateUserLocked(userId); // If services haven't been initialized yet - no updates required if (user.services == null) { return; } allServices = new ArrayList<>(user.services.values()); } IntArray updatedUids = null; for (ServiceInfo<V> service : allServices) { int versionCode = service.componentInfo.applicationInfo.versionCode; String pkg = service.componentInfo.packageName; ApplicationInfo newAppInfo = null; try { newAppInfo = mContext.getPackageManager().getApplicationInfoAsUser(pkg, 0, userId); } catch (NameNotFoundException e) { // Package uninstalled - treat as null app info } // If package updated or removed if ((newAppInfo == null) || (newAppInfo.versionCode != versionCode)) { if (DEBUG) { Slog.d(TAG, "Package " + pkg + " uid=" + service.uid + " updated. New appInfo: " + newAppInfo); } if (updatedUids == null) { updatedUids = new IntArray(); } updatedUids.add(service.uid); } } if (updatedUids != null && updatedUids.size() > 0) { int[] updatedUidsArray = updatedUids.toArray(); generateServicesMap(updatedUidsArray, userId); } } @VisibleForTesting protected boolean inSystemImage(int callerUid) { String[] packages = mContext.getPackageManager().getPackagesForUid(callerUid); Loading Loading @@ -379,10 +422,11 @@ public abstract class RegisteredServicesCache<V> { */ private void generateServicesMap(int[] changedUids, int userId) { if (DEBUG) { Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + changedUids); Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = " + Arrays.toString(changedUids)); } final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<ServiceInfo<V>>(); final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<>(); final List<ResolveInfo> resolveInfos = queryIntentServices(userId); for (ResolveInfo resolveInfo : resolveInfos) { try { Loading
services/core/java/com/android/server/accounts/AccountManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -934,6 +934,7 @@ public class AccountManagerService * Should only be called inside of a clearCallingIdentity block. */ private AuthenticatorDescription[] getAuthenticatorTypesInternal(int userId) { mAuthenticatorCache.updateServices(userId); Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>> authenticatorCollection = mAuthenticatorCache.getAllServices(userId); AuthenticatorDescription[] types = Loading @@ -947,8 +948,6 @@ public class AccountManagerService return types; } private boolean isCrossUser(int callingUid, int userId) { return (userId != UserHandle.getCallingUserId() && callingUid != Process.myUid() Loading
services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java +6 −0 Original line number Diff line number Diff line Loading @@ -64,4 +64,10 @@ public interface IAccountAuthenticatorCache { Handler handler); void invalidateCache(int userId); /** * Request to update services info for which package has been updated, but hasn't been * picked up by the cache. */ void updateServices(int userId); }
services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +4 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,10 @@ public class AccountManagerServiceTest extends AndroidTestCase { @Override public void invalidateCache(int userId) { } @Override public void updateServices(int userId) { } } static public class MyMockContext extends MockContext { Loading