Update services info before returning authenticators
Added RegisteredServicesCache.updateServices method which allows callers
to request an update to services for which package has been updated.
Added a call to updateServices in getAuthenticatorTypesInternal
Test: Manually tested update flow on test authenticator with an artificial
delay in broadcast handling
Bug: 30979262
Change-Id: I499b2ee0be53fed01201c56068d929b6d621a78e
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user