summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/RegisteredServicesCache.java48
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java3
-rw-r--r--services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java4
4 files changed, 57 insertions, 4 deletions
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 6162d1aeeceb..a1103838280c 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -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;
@@ -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;
@@ -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);
@@ -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 {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 9108acf9c40a..c9bbb7609f13 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -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 =
@@ -947,8 +948,6 @@ public class AccountManagerService
return types;
}
-
-
private boolean isCrossUser(int callingUid, int userId) {
return (userId != UserHandle.getCallingUserId()
&& callingUid != Process.myUid()
diff --git a/services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java b/services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java
index bb09687720cc..2c7d921edbcb 100644
--- a/services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java
+++ b/services/core/java/com/android/server/accounts/IAccountAuthenticatorCache.java
@@ -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);
}
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index ef9739da0094..404c14271b89 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -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 {