Merge "Revert "Adding multiple provider support in AbstractMasterSystem..."" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
68688e2e19
@@ -4130,9 +4130,9 @@
|
|||||||
This service must be trusted, as it can be activated without explicit consent of the user.
|
This service must be trusted, as it can be activated without explicit consent of the user.
|
||||||
If no service with the specified name exists on the device, cloudsearch will be disabled.
|
If no service with the specified name exists on the device, cloudsearch will be disabled.
|
||||||
Example: "com.android.intelligence/.CloudSearchService"
|
Example: "com.android.intelligence/.CloudSearchService"
|
||||||
config_defaultCloudSearchServices is for the multiple provider case.
|
config_defaultCloudSearchService is for the single provider case.
|
||||||
-->
|
-->
|
||||||
<string-array name="config_defaultCloudSearchServices"></string-array>
|
<string name="config_defaultCloudSearchService" translatable="false"></string>
|
||||||
|
|
||||||
<!-- The package name for the system's translation service.
|
<!-- The package name for the system's translation service.
|
||||||
This service must be trusted, as it can be activated without explicit consent of the user.
|
This service must be trusted, as it can be activated without explicit consent of the user.
|
||||||
|
|||||||
@@ -3676,7 +3676,7 @@
|
|||||||
<java-symbol type="string" name="notification_channel_network_status" />
|
<java-symbol type="string" name="notification_channel_network_status" />
|
||||||
<java-symbol type="string" name="notification_channel_network_alerts" />
|
<java-symbol type="string" name="notification_channel_network_alerts" />
|
||||||
<java-symbol type="string" name="notification_channel_network_available" />
|
<java-symbol type="string" name="notification_channel_network_available" />
|
||||||
<java-symbol type="array" name="config_defaultCloudSearchServices" />
|
<java-symbol type="string" name="config_defaultCloudSearchService" />
|
||||||
<java-symbol type="string" name="notification_channel_vpn" />
|
<java-symbol type="string" name="notification_channel_vpn" />
|
||||||
<java-symbol type="string" name="notification_channel_device_admin" />
|
<java-symbol type="string" name="notification_channel_device_admin" />
|
||||||
<java-symbol type="string" name="notification_channel_alerts" />
|
<java-symbol type="string" name="notification_channel_alerts" />
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ import com.android.server.infra.FrameworkResourcesServiceNameResolver;
|
|||||||
import com.android.server.wm.ActivityTaskManagerInternal;
|
import com.android.server.wm.ActivityTaskManagerInternal;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,7 +62,7 @@ public class CloudSearchManagerService extends
|
|||||||
|
|
||||||
public CloudSearchManagerService(Context context) {
|
public CloudSearchManagerService(Context context) {
|
||||||
super(context, new FrameworkResourcesServiceNameResolver(context,
|
super(context, new FrameworkResourcesServiceNameResolver(context,
|
||||||
R.array.config_defaultCloudSearchServices, true), null,
|
R.string.config_defaultCloudSearchService), null,
|
||||||
PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
|
PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
|
||||||
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
|
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -72,25 +70,7 @@ public class CloudSearchManagerService extends
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CloudSearchPerUserService newServiceLocked(int resolvedUserId, boolean disabled) {
|
protected CloudSearchPerUserService newServiceLocked(int resolvedUserId, boolean disabled) {
|
||||||
return new CloudSearchPerUserService(this, mLock, resolvedUserId, "");
|
return new CloudSearchPerUserService(this, mLock, resolvedUserId);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<CloudSearchPerUserService> newServiceListLocked(int resolvedUserId,
|
|
||||||
boolean disabled, String[] serviceNames) {
|
|
||||||
if (serviceNames == null) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
List<CloudSearchPerUserService> serviceList =
|
|
||||||
new ArrayList<>(serviceNames.length);
|
|
||||||
for (int i = 0; i < serviceNames.length; i++) {
|
|
||||||
if (serviceNames[i] == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
serviceList.add(new CloudSearchPerUserService(this, mLock, resolvedUserId,
|
|
||||||
serviceNames[i]));
|
|
||||||
}
|
|
||||||
return serviceList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -131,28 +111,19 @@ public class CloudSearchManagerService extends
|
|||||||
@NonNull ICloudSearchManagerCallback callBack) {
|
@NonNull ICloudSearchManagerCallback callBack) {
|
||||||
searchRequest.setSource(
|
searchRequest.setSource(
|
||||||
mContext.getPackageManager().getNameForUid(Binder.getCallingUid()));
|
mContext.getPackageManager().getNameForUid(Binder.getCallingUid()));
|
||||||
runForUser("search", (service) -> {
|
runForUserLocked("search", searchRequest.getRequestId(), (service) ->
|
||||||
synchronized (service.mLock) {
|
service.onSearchLocked(searchRequest, callBack));
|
||||||
service.onSearchLocked(searchRequest, callBack);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void returnResults(IBinder token, String requestId, SearchResponse response) {
|
public void returnResults(IBinder token, String requestId, SearchResponse response) {
|
||||||
runForUser("returnResults", (service) -> {
|
runForUserLocked("returnResults", requestId, (service) ->
|
||||||
synchronized (service.mLock) {
|
service.onReturnResultsLocked(token, requestId, response));
|
||||||
service.onReturnResultsLocked(token, requestId, response);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy(@NonNull SearchRequest searchRequest) {
|
public void destroy(@NonNull SearchRequest searchRequest) {
|
||||||
runForUser("destroyCloudSearchSession", (service) -> {
|
runForUserLocked("destroyCloudSearchSession", searchRequest.getRequestId(),
|
||||||
synchronized (service.mLock) {
|
(service) -> service.onDestroyLocked(searchRequest.getRequestId()));
|
||||||
service.onDestroyLocked(searchRequest.getRequestId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
|
public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
|
||||||
@@ -163,7 +134,8 @@ public class CloudSearchManagerService extends
|
|||||||
.exec(this, in, out, err, args, callback, resultReceiver);
|
.exec(this, in, out, err, args, callback, resultReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runForUser(@NonNull final String func,
|
private void runForUserLocked(@NonNull final String func,
|
||||||
|
@NonNull final String requestId,
|
||||||
@NonNull final Consumer<CloudSearchPerUserService> c) {
|
@NonNull final Consumer<CloudSearchPerUserService> c) {
|
||||||
ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
|
ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
|
||||||
final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
|
final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
|
||||||
@@ -171,7 +143,7 @@ public class CloudSearchManagerService extends
|
|||||||
null, null);
|
null, null);
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "runForUser:" + func + " from pid=" + Binder.getCallingPid()
|
Slog.d(TAG, "runForUserLocked:" + func + " from pid=" + Binder.getCallingPid()
|
||||||
+ ", uid=" + Binder.getCallingUid());
|
+ ", uid=" + Binder.getCallingUid());
|
||||||
}
|
}
|
||||||
Context ctx = getContext();
|
Context ctx = getContext();
|
||||||
@@ -188,11 +160,8 @@ public class CloudSearchManagerService extends
|
|||||||
final long origId = Binder.clearCallingIdentity();
|
final long origId = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final List<CloudSearchPerUserService> services =
|
final CloudSearchPerUserService service = getServiceForUserLocked(userId);
|
||||||
getServiceListForUserLocked(userId);
|
c.accept(service);
|
||||||
for (int i = 0; i < services.size(); i++) {
|
|
||||||
c.accept(services.get(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(origId);
|
Binder.restoreCallingIdentity(origId);
|
||||||
|
|||||||
@@ -54,12 +54,7 @@ public class CloudSearchManagerServiceShellCommand extends ShellCommand {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
final int duration = Integer.parseInt(getNextArgRequired());
|
final int duration = Integer.parseInt(getNextArgRequired());
|
||||||
String[] services = serviceName.split(";");
|
mService.setTemporaryService(userId, serviceName, duration);
|
||||||
if (services.length == 0) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
mService.setTemporaryServices(userId, services, duration);
|
|
||||||
}
|
|
||||||
pw.println("CloudSearchService temporarily set to " + serviceName
|
pw.println("CloudSearchService temporarily set to " + serviceName
|
||||||
+ " for " + duration + "ms");
|
+ " for " + duration + "ms");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ public class CloudSearchPerUserService extends
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final CircularQueue<String, CloudSearchCallbackInfo> mCallbackQueue =
|
private final CircularQueue<String, CloudSearchCallbackInfo> mCallbackQueue =
|
||||||
new CircularQueue<>(QUEUE_SIZE);
|
new CircularQueue<>(QUEUE_SIZE);
|
||||||
private final String mServiceName;
|
|
||||||
private final ComponentName mRemoteComponentName;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private RemoteCloudSearchService mRemoteService;
|
private RemoteCloudSearchService mRemoteService;
|
||||||
@@ -62,10 +60,8 @@ public class CloudSearchPerUserService extends
|
|||||||
private boolean mZombie;
|
private boolean mZombie;
|
||||||
|
|
||||||
protected CloudSearchPerUserService(CloudSearchManagerService master,
|
protected CloudSearchPerUserService(CloudSearchManagerService master,
|
||||||
Object lock, int userId, String serviceName) {
|
Object lock, int userId) {
|
||||||
super(master, lock, userId);
|
super(master, lock, userId);
|
||||||
mServiceName = serviceName;
|
|
||||||
mRemoteComponentName = ComponentName.unflattenFromString(mServiceName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // from PerUserSystemService
|
@Override // from PerUserSystemService
|
||||||
@@ -112,7 +108,7 @@ public class CloudSearchPerUserService extends
|
|||||||
? searchRequest.getSearchConstraints().getString(
|
? searchRequest.getSearchConstraints().getString(
|
||||||
SearchRequest.CONSTRAINT_SEARCH_PROVIDER_FILTER) : "";
|
SearchRequest.CONSTRAINT_SEARCH_PROVIDER_FILTER) : "";
|
||||||
|
|
||||||
String remoteServicePackageName = mRemoteComponentName.getPackageName();
|
String remoteServicePackageName = getServiceComponentName().getPackageName();
|
||||||
// By default, all providers are marked as wanted.
|
// By default, all providers are marked as wanted.
|
||||||
boolean wantedProvider = true;
|
boolean wantedProvider = true;
|
||||||
if (filterList.length() > 0) {
|
if (filterList.length() > 0) {
|
||||||
@@ -154,19 +150,11 @@ public class CloudSearchPerUserService extends
|
|||||||
/**
|
/**
|
||||||
* Used to return results back to the clients.
|
* Used to return results back to the clients.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
public void onReturnResultsLocked(@NonNull IBinder token,
|
public void onReturnResultsLocked(@NonNull IBinder token,
|
||||||
@NonNull String requestId,
|
@NonNull String requestId,
|
||||||
@NonNull SearchResponse response) {
|
@NonNull SearchResponse response) {
|
||||||
if (mRemoteService == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ICloudSearchService serviceInterface = mRemoteService.getServiceInterface();
|
|
||||||
if (serviceInterface == null || token != serviceInterface.asBinder()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mCallbackQueue.containsKey(requestId)) {
|
if (mCallbackQueue.containsKey(requestId)) {
|
||||||
response.setSource(mServiceName);
|
response.setSource(mRemoteService.getComponentName().getPackageName());
|
||||||
final CloudSearchCallbackInfo sessionInfo = mCallbackQueue.getElement(requestId);
|
final CloudSearchCallbackInfo sessionInfo = mCallbackQueue.getElement(requestId);
|
||||||
try {
|
try {
|
||||||
if (response.getStatusCode() == SearchResponse.SEARCH_STATUS_OK) {
|
if (response.getStatusCode() == SearchResponse.SEARCH_STATUS_OK) {
|
||||||
@@ -175,10 +163,6 @@ public class CloudSearchPerUserService extends
|
|||||||
sessionInfo.mCallback.onSearchFailed(response);
|
sessionInfo.mCallback.onSearchFailed(response);
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
if (mMaster.debug) {
|
|
||||||
Slog.e(TAG, "Exception in posting results");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
onDestroyLocked(requestId);
|
onDestroyLocked(requestId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,7 +297,7 @@ public class CloudSearchPerUserService extends
|
|||||||
@Nullable
|
@Nullable
|
||||||
private RemoteCloudSearchService getRemoteServiceLocked() {
|
private RemoteCloudSearchService getRemoteServiceLocked() {
|
||||||
if (mRemoteService == null) {
|
if (mRemoteService == null) {
|
||||||
final String serviceName = getComponentNameForMultipleLocked(mServiceName);
|
final String serviceName = getComponentNameLocked();
|
||||||
if (serviceName == null) {
|
if (serviceName == null) {
|
||||||
if (mMaster.verbose) {
|
if (mMaster.verbose) {
|
||||||
Slog.v(TAG, "getRemoteServiceLocked(): not set");
|
Slog.v(TAG, "getRemoteServiceLocked(): not set");
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ import java.io.PrintWriter;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -169,10 +168,10 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
private final SparseBooleanArray mDisabledByUserRestriction;
|
private final SparseBooleanArray mDisabledByUserRestriction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache of service list per user id.
|
* Cache of services per user id.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final SparseArray<List<S>> mServicesCacheList = new SparseArray<>();
|
private final SparseArray<S> mServicesCache = new SparseArray<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value that determines whether the per-user service should be removed from the cache when its
|
* Value that determines whether the per-user service should be removed from the cache when its
|
||||||
@@ -253,7 +252,8 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
mServiceNameResolver = serviceNameResolver;
|
mServiceNameResolver = serviceNameResolver;
|
||||||
if (mServiceNameResolver != null) {
|
if (mServiceNameResolver != null) {
|
||||||
mServiceNameResolver.setOnTemporaryServiceNameChangedCallback(
|
mServiceNameResolver.setOnTemporaryServiceNameChangedCallback(
|
||||||
this::onServiceNameChanged);
|
(u, s, t) -> onServiceNameChanged(u, s, t));
|
||||||
|
|
||||||
}
|
}
|
||||||
if (disallowProperty == null) {
|
if (disallowProperty == null) {
|
||||||
mDisabledByUserRestriction = null;
|
mDisabledByUserRestriction = null;
|
||||||
@@ -308,7 +308,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
@Override // from SystemService
|
@Override // from SystemService
|
||||||
public void onUserStopped(@NonNull TargetUser user) {
|
public void onUserStopped(@NonNull TargetUser user) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
removeCachedServiceListLocked(user.getUserIdentifier());
|
removeCachedServiceLocked(user.getUserIdentifier());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,58 +386,21 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final S oldService = peekServiceForUserLocked(userId);
|
final S oldService = peekServiceForUserLocked(userId);
|
||||||
if (oldService != null) {
|
if (oldService != null) {
|
||||||
oldService.removeSelfFromCache();
|
oldService.removeSelfFromCacheLocked();
|
||||||
}
|
}
|
||||||
mServiceNameResolver.setTemporaryService(userId, componentName, durationMs);
|
mServiceNameResolver.setTemporaryService(userId, componentName, durationMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporarily sets the service implementation.
|
|
||||||
*
|
|
||||||
* <p>Typically used by Shell command and/or CTS tests.
|
|
||||||
*
|
|
||||||
* @param componentNames list of the names of the new component
|
|
||||||
* @param durationMs how long the change will be valid (the service will be automatically
|
|
||||||
* reset
|
|
||||||
* to the default component after this timeout expires).
|
|
||||||
* @throws SecurityException if caller is not allowed to manage this service's settings.
|
|
||||||
* @throws IllegalArgumentException if value of {@code durationMs} is higher than
|
|
||||||
* {@link #getMaximumTemporaryServiceDurationMs()}.
|
|
||||||
*/
|
|
||||||
public final void setTemporaryServices(@UserIdInt int userId, @NonNull String[] componentNames,
|
|
||||||
int durationMs) {
|
|
||||||
Slog.i(mTag, "setTemporaryService(" + userId + ") to " + Arrays.toString(componentNames)
|
|
||||||
+ " for " + durationMs + "ms");
|
|
||||||
if (mServiceNameResolver == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
enforceCallingPermissionForManagement();
|
|
||||||
|
|
||||||
Objects.requireNonNull(componentNames);
|
|
||||||
final int maxDurationMs = getMaximumTemporaryServiceDurationMs();
|
|
||||||
if (durationMs > maxDurationMs) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Max duration is " + maxDurationMs + " (called with " + durationMs + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mLock) {
|
|
||||||
final S oldService = peekServiceForUserLocked(userId);
|
|
||||||
if (oldService != null) {
|
|
||||||
oldService.removeSelfFromCache();
|
|
||||||
}
|
|
||||||
mServiceNameResolver.setTemporaryServices(userId, componentNames, durationMs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the default service should be used.
|
* Sets whether the default service should be used.
|
||||||
*
|
*
|
||||||
* <p>Typically used during CTS tests to make sure only the default service doesn't interfere
|
* <p>Typically used during CTS tests to make sure only the default service doesn't interfere
|
||||||
* with the test results.
|
* with the test results.
|
||||||
*
|
*
|
||||||
* @return whether the enabled state changed.
|
|
||||||
* @throws SecurityException if caller is not allowed to manage this service's settings.
|
* @throws SecurityException if caller is not allowed to manage this service's settings.
|
||||||
|
*
|
||||||
|
* @return whether the enabled state changed.
|
||||||
*/
|
*/
|
||||||
public final boolean setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
|
public final boolean setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
|
||||||
Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled);
|
Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled);
|
||||||
@@ -457,7 +420,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
|
|
||||||
final S oldService = peekServiceForUserLocked(userId);
|
final S oldService = peekServiceForUserLocked(userId);
|
||||||
if (oldService != null) {
|
if (oldService != null) {
|
||||||
oldService.removeSelfFromCache();
|
oldService.removeSelfFromCacheLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must update the service on cache so its initialization code is triggered
|
// Must update the service on cache so its initialization code is triggered
|
||||||
@@ -537,21 +500,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
@Nullable
|
@Nullable
|
||||||
protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled);
|
protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled);
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new service list that will be added to the cache.
|
|
||||||
*
|
|
||||||
* @param resolvedUserId the resolved user id for the service.
|
|
||||||
* @param disabled whether the service is currently disabled (due to {@link UserManager}
|
|
||||||
* restrictions).
|
|
||||||
* @return a new instance.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected List<S> newServiceListLocked(@UserIdInt int resolvedUserId, boolean disabled,
|
|
||||||
String[] serviceNames) {
|
|
||||||
throw new UnsupportedOperationException("newServiceListLocked not implemented. ");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the service for extra Settings changes (i.e., other than
|
* Register the service for extra Settings changes (i.e., other than
|
||||||
* {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
|
* {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
|
||||||
@@ -568,6 +516,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
* <p><b>NOTE: </p>it doesn't need to register for
|
* <p><b>NOTE: </p>it doesn't need to register for
|
||||||
* {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
|
* {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
|
||||||
* {@link #getServiceSettingsProperty()}.
|
* {@link #getServiceSettingsProperty()}.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver,
|
protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver,
|
||||||
@@ -590,38 +539,18 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@NonNull
|
@NonNull
|
||||||
protected S getServiceForUserLocked(@UserIdInt int userId) {
|
protected S getServiceForUserLocked(@UserIdInt int userId) {
|
||||||
List<S> services = getServiceListForUserLocked(userId);
|
|
||||||
return services == null || services.size() == 0 ? null : services.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the service instance list for a user, creating instances if not present in the cache.
|
|
||||||
*/
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected List<S> getServiceListForUserLocked(@UserIdInt int userId) {
|
|
||||||
final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
|
final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
|
||||||
Binder.getCallingUid(), userId, false, false, null, null);
|
Binder.getCallingUid(), userId, false, false, null, null);
|
||||||
List<S> services = mServicesCacheList.get(resolvedUserId);
|
S service = mServicesCache.get(resolvedUserId);
|
||||||
if (services == null || services.size() == 0) {
|
if (service == null) {
|
||||||
final boolean disabled = isDisabledLocked(userId);
|
final boolean disabled = isDisabledLocked(userId);
|
||||||
if (mServiceNameResolver == null) {
|
service = newServiceLocked(resolvedUserId, disabled);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (mServiceNameResolver.isConfiguredInMultipleMode()) {
|
|
||||||
services = newServiceListLocked(resolvedUserId, disabled,
|
|
||||||
mServiceNameResolver.getServiceNameList(userId));
|
|
||||||
} else {
|
|
||||||
services = new ArrayList<>();
|
|
||||||
services.add(newServiceLocked(resolvedUserId, disabled));
|
|
||||||
}
|
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
for (int i = 0; i < services.size(); i++) {
|
onServiceEnabledLocked(service, resolvedUserId);
|
||||||
onServiceEnabledLocked(services.get(i), resolvedUserId);
|
|
||||||
}
|
}
|
||||||
|
mServicesCache.put(userId, service);
|
||||||
}
|
}
|
||||||
mServicesCacheList.put(userId, services);
|
return service;
|
||||||
}
|
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -631,20 +560,9 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@Nullable
|
@Nullable
|
||||||
protected S peekServiceForUserLocked(@UserIdInt int userId) {
|
protected S peekServiceForUserLocked(@UserIdInt int userId) {
|
||||||
List<S> serviceList = peekServiceListForUserLocked(userId);
|
|
||||||
return serviceList == null || serviceList.size() == 0 ? null : serviceList.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the <b>existing</b> service instance for a user, returning {@code null} if not already
|
|
||||||
* present in the cache.
|
|
||||||
*/
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
@Nullable
|
|
||||||
protected List<S> peekServiceListForUserLocked(@UserIdInt int userId) {
|
|
||||||
final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
|
final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
|
||||||
Binder.getCallingUid(), userId, false, false, null, null);
|
Binder.getCallingUid(), userId, false, false, null, null);
|
||||||
return mServicesCacheList.get(resolvedUserId);
|
return mServicesCache.get(resolvedUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -652,16 +570,15 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
protected void updateCachedServiceLocked(@UserIdInt int userId) {
|
protected void updateCachedServiceLocked(@UserIdInt int userId) {
|
||||||
updateCachedServiceListLocked(userId, isDisabledLocked(userId));
|
updateCachedServiceLocked(userId, isDisabledLocked(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the service is disabled (through {@link UserManager} restrictions) for the
|
* Checks whether the service is disabled (through {@link UserManager} restrictions) for the
|
||||||
* given user.
|
* given user.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected boolean isDisabledLocked(@UserIdInt int userId) {
|
protected boolean isDisabledLocked(@UserIdInt int userId) {
|
||||||
return mDisabledByUserRestriction != null && mDisabledByUserRestriction.get(userId);
|
return mDisabledByUserRestriction == null ? false : mDisabledByUserRestriction.get(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -674,37 +591,15 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
protected S updateCachedServiceLocked(@UserIdInt int userId, boolean disabled) {
|
protected S updateCachedServiceLocked(@UserIdInt int userId, boolean disabled) {
|
||||||
final S service = getServiceForUserLocked(userId);
|
final S service = getServiceForUserLocked(userId);
|
||||||
updateCachedServiceListLocked(userId, disabled);
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a cached service for a given user.
|
|
||||||
*
|
|
||||||
* @param userId user handle.
|
|
||||||
* @param disabled whether the user is disabled.
|
|
||||||
* @return service for the user.
|
|
||||||
*/
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected List<S> updateCachedServiceListLocked(@UserIdInt int userId, boolean disabled) {
|
|
||||||
final List<S> services = getServiceListForUserLocked(userId);
|
|
||||||
if (services == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < services.size(); i++) {
|
|
||||||
S service = services.get(i);
|
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
synchronized (service.mLock) {
|
|
||||||
service.updateLocked(disabled);
|
service.updateLocked(disabled);
|
||||||
if (!service.isEnabledLocked()) {
|
if (!service.isEnabledLocked()) {
|
||||||
removeCachedServiceListLocked(userId);
|
removeCachedServiceLocked(userId);
|
||||||
} else {
|
} else {
|
||||||
onServiceEnabledLocked(services.get(i), userId);
|
onServiceEnabledLocked(service, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return service;
|
||||||
}
|
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -724,32 +619,28 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
* <p>By default doesn't do anything, but can be overridden by subclasses.
|
* <p>By default doesn't do anything, but can be overridden by subclasses.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected void onServiceEnabledLocked(@NonNull S service, @UserIdInt int userId) {
|
protected void onServiceEnabledLocked(@NonNull S service, @UserIdInt int userId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a cached service list for a given user.
|
* Removes a cached service for a given user.
|
||||||
*
|
*
|
||||||
* @return the removed service.
|
* @return the removed service.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@NonNull
|
@NonNull
|
||||||
protected final List<S> removeCachedServiceListLocked(@UserIdInt int userId) {
|
protected final S removeCachedServiceLocked(@UserIdInt int userId) {
|
||||||
final List<S> services = peekServiceListForUserLocked(userId);
|
final S service = peekServiceForUserLocked(userId);
|
||||||
if (services != null) {
|
if (service != null) {
|
||||||
mServicesCacheList.delete(userId);
|
mServicesCache.delete(userId);
|
||||||
for (int i = 0; i < services.size(); i++) {
|
onServiceRemoved(service, userId);
|
||||||
onServiceRemoved(services.get(i), userId);
|
|
||||||
}
|
}
|
||||||
}
|
return service;
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before the package that provides the service for the given user is being updated.
|
* Called before the package that provides the service for the given user is being updated.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected void onServicePackageUpdatingLocked(@UserIdInt int userId) {
|
protected void onServicePackageUpdatingLocked(@UserIdInt int userId) {
|
||||||
if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")");
|
if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")");
|
||||||
}
|
}
|
||||||
@@ -757,7 +648,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
/**
|
/**
|
||||||
* Called after the package that provides the service for the given user is being updated.
|
* Called after the package that provides the service for the given user is being updated.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
|
protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
|
||||||
if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
|
if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
|
||||||
}
|
}
|
||||||
@@ -765,7 +655,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
/**
|
/**
|
||||||
* Called after the package data that provides the service for the given user is cleared.
|
* Called after the package data that provides the service for the given user is cleared.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
|
protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
|
||||||
if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
|
if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
|
||||||
}
|
}
|
||||||
@@ -773,7 +662,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
/**
|
/**
|
||||||
* Called after the package that provides the service for the given user is restarted.
|
* Called after the package that provides the service for the given user is restarted.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
|
protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
|
||||||
if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
|
if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
|
||||||
}
|
}
|
||||||
@@ -798,24 +686,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName,
|
protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName,
|
||||||
boolean isTemporary) {
|
boolean isTemporary) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
updateCachedServiceListLocked(userId, isDisabledLocked(userId));
|
updateCachedServiceLocked(userId);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the service name list has changed (typically when using temporary services).
|
|
||||||
*
|
|
||||||
* <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call
|
|
||||||
* that same method, or {@code super.onServiceNameChanged()}.
|
|
||||||
*
|
|
||||||
* @param userId user handle.
|
|
||||||
* @param serviceNames the new service name list.
|
|
||||||
* @param isTemporary whether the new service is temporary.
|
|
||||||
*/
|
|
||||||
protected void onServiceNameListChanged(@UserIdInt int userId, @Nullable String[] serviceNames,
|
|
||||||
boolean isTemporary) {
|
|
||||||
synchronized (mLock) {
|
|
||||||
updateCachedServiceListLocked(userId, isDisabledLocked(userId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,12 +695,9 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
protected void visitServicesLocked(@NonNull Visitor<S> visitor) {
|
protected void visitServicesLocked(@NonNull Visitor<S> visitor) {
|
||||||
final int size = mServicesCacheList.size();
|
final int size = mServicesCache.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
List<S> services = mServicesCacheList.valueAt(i);
|
visitor.visit(mServicesCache.valueAt(i));
|
||||||
for (int j = 0; j < services.size(); j++) {
|
|
||||||
visitor.visit(services.get(j));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,7 +706,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
protected void clearCacheLocked() {
|
protected void clearCacheLocked() {
|
||||||
mServicesCacheList.clear();
|
mServicesCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -889,7 +757,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/117779333): support proto
|
// TODO(b/117779333): support proto
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
|
protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
|
||||||
boolean realDebug = debug;
|
boolean realDebug = debug;
|
||||||
boolean realVerbose = verbose;
|
boolean realVerbose = verbose;
|
||||||
@@ -898,64 +765,40 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
try {
|
try {
|
||||||
// Temporarily turn on full logging;
|
// Temporarily turn on full logging;
|
||||||
debug = verbose = true;
|
debug = verbose = true;
|
||||||
final int size = mServicesCacheList.size();
|
final int size = mServicesCache.size();
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
|
||||||
pw.print("Debug: ");
|
pw.print(" Verbose: "); pw.println(realVerbose);
|
||||||
pw.print(realDebug);
|
pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags);
|
||||||
pw.print(" Verbose: ");
|
|
||||||
pw.println(realVerbose);
|
|
||||||
pw.print("Package policy flags: ");
|
|
||||||
pw.println(mServicePackagePolicyFlags);
|
|
||||||
if (mUpdatingPackageNames != null) {
|
if (mUpdatingPackageNames != null) {
|
||||||
pw.print("Packages being updated: ");
|
pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
|
||||||
pw.println(mUpdatingPackageNames);
|
|
||||||
}
|
}
|
||||||
dumpSupportedUsers(pw, prefix);
|
dumpSupportedUsers(pw, prefix);
|
||||||
if (mServiceNameResolver != null) {
|
if (mServiceNameResolver != null) {
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Name resolver: ");
|
||||||
pw.print("Name resolver: ");
|
mServiceNameResolver.dumpShort(pw); pw.println();
|
||||||
mServiceNameResolver.dumpShort(pw);
|
|
||||||
pw.println();
|
|
||||||
final List<UserInfo> users = getSupportedUsers();
|
final List<UserInfo> users = getSupportedUsers();
|
||||||
for (int i = 0; i < users.size(); i++) {
|
for (int i = 0; i < users.size(); i++) {
|
||||||
final int userId = users.get(i).id;
|
final int userId = users.get(i).id;
|
||||||
pw.print(prefix2);
|
pw.print(prefix2); pw.print(userId); pw.print(": ");
|
||||||
pw.print(userId);
|
mServiceNameResolver.dumpShort(pw, userId); pw.println();
|
||||||
pw.print(": ");
|
|
||||||
mServiceNameResolver.dumpShort(pw, userId);
|
|
||||||
pw.println();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Users disabled by restriction: ");
|
||||||
pw.print("Users disabled by restriction: ");
|
|
||||||
pw.println(mDisabledByUserRestriction);
|
pw.println(mDisabledByUserRestriction);
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService);
|
||||||
pw.print("Allow instant service: ");
|
|
||||||
pw.println(mAllowInstantService);
|
|
||||||
final String settingsProperty = getServiceSettingsProperty();
|
final String settingsProperty = getServiceSettingsProperty();
|
||||||
if (settingsProperty != null) {
|
if (settingsProperty != null) {
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Settings property: "); pw.println(settingsProperty);
|
||||||
pw.print("Settings property: ");
|
|
||||||
pw.println(settingsProperty);
|
|
||||||
}
|
}
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Cached services: ");
|
||||||
pw.print("Cached services: ");
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
pw.println("none");
|
pw.println("none");
|
||||||
} else {
|
} else {
|
||||||
pw.println(size);
|
pw.println(size);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Service at "); pw.print(i); pw.println(": ");
|
||||||
pw.print("Service at ");
|
final S service = mServicesCache.valueAt(i);
|
||||||
pw.print(i);
|
|
||||||
pw.println(": ");
|
|
||||||
final List<S> services = mServicesCacheList.valueAt(i);
|
|
||||||
for (int j = 0; j < services.size(); j++) {
|
|
||||||
S service = services.get(i);
|
|
||||||
synchronized (service.mLock) {
|
|
||||||
service.dumpLocked(prefix2, pw);
|
service.dumpLocked(prefix2, pw);
|
||||||
}
|
|
||||||
}
|
|
||||||
pw.println();
|
pw.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -977,7 +820,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
final int userId = getChangingUserId();
|
final int userId = getChangingUserId();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (mUpdatingPackageNames == null) {
|
if (mUpdatingPackageNames == null) {
|
||||||
mUpdatingPackageNames = new SparseArray<String>(mServicesCacheList.size());
|
mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size());
|
||||||
}
|
}
|
||||||
mUpdatingPackageNames.put(userId, packageName);
|
mUpdatingPackageNames.put(userId, packageName);
|
||||||
onServicePackageUpdatingLocked(userId);
|
onServicePackageUpdatingLocked(userId);
|
||||||
@@ -992,7 +835,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
+ " because package " + activePackageName
|
+ " because package " + activePackageName
|
||||||
+ " is being updated");
|
+ " is being updated");
|
||||||
}
|
}
|
||||||
removeCachedServiceListLocked(userId);
|
removeCachedServiceLocked(userId);
|
||||||
|
|
||||||
if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
|
if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
@@ -1058,7 +901,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
|
if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
|
||||||
handleActiveServiceRestartedLocked(activePackageName, userId);
|
handleActiveServiceRestartedLocked(activePackageName, userId);
|
||||||
} else {
|
} else {
|
||||||
removeCachedServiceListLocked(userId);
|
removeCachedServiceLocked(userId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
handlePackageUpdateLocked(pkg);
|
handlePackageUpdateLocked(pkg);
|
||||||
@@ -1087,7 +930,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
|
|
||||||
private void handleActiveServiceRemoved(@UserIdInt int userId) {
|
private void handleActiveServiceRemoved(@UserIdInt int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
removeCachedServiceListLocked(userId);
|
removeCachedServiceLocked(userId);
|
||||||
}
|
}
|
||||||
final String serviceSettingsProperty = getServiceSettingsProperty();
|
final String serviceSettingsProperty = getServiceSettingsProperty();
|
||||||
if (serviceSettingsProperty != null) {
|
if (serviceSettingsProperty != null) {
|
||||||
@@ -1096,7 +939,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
private void handleActiveServiceRestartedLocked(String activePackageName,
|
private void handleActiveServiceRestartedLocked(String activePackageName,
|
||||||
@UserIdInt int userId) {
|
@UserIdInt int userId) {
|
||||||
if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
|
if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
|
||||||
@@ -1110,7 +952,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
+ " because package " + activePackageName
|
+ " because package " + activePackageName
|
||||||
+ " is being restarted");
|
+ " is being restarted");
|
||||||
}
|
}
|
||||||
removeCachedServiceListLocked(userId);
|
removeCachedServiceLocked(userId);
|
||||||
|
|
||||||
if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
|
if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
@@ -1124,7 +966,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPackageModified(String packageName) {
|
public void onPackageModified(String packageName) {
|
||||||
synchronized (mLock) {
|
|
||||||
if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName);
|
if (verbose) Slog.v(mTag, "onPackageModified(): " + packageName);
|
||||||
|
|
||||||
if (mServiceNameResolver == null) {
|
if (mServiceNameResolver == null) {
|
||||||
@@ -1132,19 +973,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
final int userId = getChangingUserId();
|
final int userId = getChangingUserId();
|
||||||
final String[] serviceNames = mServiceNameResolver.getDefaultServiceNameList(
|
final String serviceName = mServiceNameResolver.getDefaultServiceName(userId);
|
||||||
userId);
|
|
||||||
if (serviceNames != null) {
|
|
||||||
for (int i = 0; i < serviceNames.length; i++) {
|
|
||||||
peekAndUpdateCachedServiceLocked(packageName, userId, serviceNames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
private void peekAndUpdateCachedServiceLocked(String packageName, int userId,
|
|
||||||
String serviceName) {
|
|
||||||
if (serviceName == null) {
|
if (serviceName == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1168,7 +997,6 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
private String getActiveServicePackageNameLocked() {
|
private String getActiveServicePackageNameLocked() {
|
||||||
final int userId = getChangingUserId();
|
final int userId = getChangingUserId();
|
||||||
final S service = peekServiceForUserLocked(userId);
|
final S service = peekServiceForUserLocked(userId);
|
||||||
|
|||||||
@@ -43,13 +43,14 @@ import java.io.PrintWriter;
|
|||||||
*
|
*
|
||||||
* @param <M> "main" service class.
|
* @param <M> "main" service class.
|
||||||
* @param <S> "real" service class.
|
* @param <S> "real" service class.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S, M>,
|
public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S, M>,
|
||||||
M extends AbstractMasterSystemService<M, S>> {
|
M extends AbstractMasterSystemService<M, S>> {
|
||||||
|
|
||||||
@UserIdInt protected final int mUserId;
|
protected final @UserIdInt int mUserId;
|
||||||
public final Object mLock;
|
protected final Object mLock;
|
||||||
protected final String mTag = getClass().getSimpleName();
|
protected final String mTag = getClass().getSimpleName();
|
||||||
|
|
||||||
protected final M mMaster;
|
protected final M mMaster;
|
||||||
@@ -90,14 +91,14 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
* <p><b>MUST</b> be overridden by subclasses that bind to an
|
* <p><b>MUST</b> be overridden by subclasses that bind to an
|
||||||
* {@link com.android.internal.infra.AbstractRemoteService}.
|
* {@link com.android.internal.infra.AbstractRemoteService}.
|
||||||
*
|
*
|
||||||
* @return new {@link ServiceInfo},
|
|
||||||
* @throws NameNotFoundException if the service does not exist.
|
* @throws NameNotFoundException if the service does not exist.
|
||||||
* @throws SecurityException if the service does not have the proper permissions to
|
* @throws SecurityException if the service does not have the proper permissions to be bound to.
|
||||||
* be bound to.
|
|
||||||
* @throws UnsupportedOperationException if subclass binds to a remote service but does not
|
* @throws UnsupportedOperationException if subclass binds to a remote service but does not
|
||||||
* overrides it.
|
* overrides it.
|
||||||
|
*
|
||||||
|
* @return new {@link ServiceInfo},
|
||||||
*/
|
*/
|
||||||
@NonNull protected ServiceInfo newServiceInfoLocked(
|
protected @NonNull ServiceInfo newServiceInfoLocked(
|
||||||
@SuppressWarnings("unused") @NonNull ComponentName serviceComponent)
|
@SuppressWarnings("unused") @NonNull ComponentName serviceComponent)
|
||||||
throws NameNotFoundException {
|
throws NameNotFoundException {
|
||||||
throw new UnsupportedOperationException("not overridden");
|
throw new UnsupportedOperationException("not overridden");
|
||||||
@@ -136,6 +137,7 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
* previous state.
|
* previous state.
|
||||||
*
|
*
|
||||||
* @param disabled whether the service is disabled (due to {@link UserManager} restrictions).
|
* @param disabled whether the service is disabled (due to {@link UserManager} restrictions).
|
||||||
|
*
|
||||||
* @return whether the disabled state changed.
|
* @return whether the disabled state changed.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@@ -152,48 +154,18 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
updateIsSetupComplete(mUserId);
|
updateIsSetupComplete(mUserId);
|
||||||
mDisabled = disabled;
|
mDisabled = disabled;
|
||||||
|
|
||||||
if (mMaster.mServiceNameResolver.isConfiguredInMultipleMode()) {
|
|
||||||
updateServiceInfoListLocked();
|
|
||||||
} else {
|
|
||||||
updateServiceInfoLocked();
|
updateServiceInfoLocked();
|
||||||
}
|
|
||||||
return wasEnabled != isEnabledLocked();
|
return wasEnabled != isEnabledLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the internal reference to the service info, and returns the service's component.
|
* Updates the internal reference to the service info, and returns the service's component.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected final ComponentName updateServiceInfoLocked() {
|
protected final ComponentName updateServiceInfoLocked() {
|
||||||
ComponentName[] componentNames = updateServiceInfoListLocked();
|
|
||||||
return componentNames == null || componentNames.length == 0 ? null : componentNames[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the internal reference to the service info, and returns the service's component.
|
|
||||||
*/
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected final ComponentName[] updateServiceInfoListLocked() {
|
|
||||||
if (mMaster.mServiceNameResolver == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!mMaster.mServiceNameResolver.isConfiguredInMultipleMode()) {
|
|
||||||
final String componentName = getComponentNameLocked();
|
|
||||||
return new ComponentName[] { getServiceComponent(componentName) };
|
|
||||||
}
|
|
||||||
final String[] componentNames = mMaster.mServiceNameResolver.getServiceNameList(
|
|
||||||
mUserId);
|
|
||||||
ComponentName[] serviceComponents = new ComponentName[componentNames.length];
|
|
||||||
for (int i = 0; i < componentNames.length; i++) {
|
|
||||||
serviceComponents[i] = getServiceComponent(componentNames[i]);
|
|
||||||
}
|
|
||||||
return serviceComponents;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ComponentName getServiceComponent(String componentName) {
|
|
||||||
synchronized (mLock) {
|
|
||||||
ServiceInfo serviceInfo = null;
|
|
||||||
ComponentName serviceComponent = null;
|
ComponentName serviceComponent = null;
|
||||||
|
if (mMaster.mServiceNameResolver != null) {
|
||||||
|
ServiceInfo serviceInfo = null;
|
||||||
|
final String componentName = getComponentNameLocked();
|
||||||
if (!TextUtils.isEmpty(componentName)) {
|
if (!TextUtils.isEmpty(componentName)) {
|
||||||
try {
|
try {
|
||||||
serviceComponent = ComponentName.unflattenFromString(componentName);
|
serviceComponent = ComponentName.unflattenFromString(componentName);
|
||||||
@@ -224,14 +196,14 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
Slog.e(mTag, "Bad ServiceInfo for '" + componentName + "': " + e);
|
Slog.e(mTag, "Bad ServiceInfo for '" + componentName + "': " + e);
|
||||||
mServiceInfo = null;
|
mServiceInfo = null;
|
||||||
}
|
}
|
||||||
return serviceComponent;
|
|
||||||
}
|
}
|
||||||
|
return serviceComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the user associated with this service.
|
* Gets the user associated with this service.
|
||||||
*/
|
*/
|
||||||
@UserIdInt public final int getUserId() {
|
public final @UserIdInt int getUserId() {
|
||||||
return mUserId;
|
return mUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,32 +231,13 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
* Gets the current name of the service, which is either the default service or the
|
* Gets the current name of the service, which is either the default service or the
|
||||||
* {@link AbstractMasterSystemService#setTemporaryService(int, String, int) temporary one}.
|
* {@link AbstractMasterSystemService#setTemporaryService(int, String, int) temporary one}.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
protected final @Nullable String getComponentNameLocked() {
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected final String getComponentNameLocked() {
|
|
||||||
return mMaster.mServiceNameResolver.getServiceName(mUserId);
|
return mMaster.mServiceNameResolver.getServiceName(mUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current name of the service, which is either the default service or the
|
|
||||||
* {@link AbstractMasterSystemService#setTemporaryService(int, String, int) temporary one}.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected final String getComponentNameForMultipleLocked(String serviceName) {
|
|
||||||
String[] services = mMaster.mServiceNameResolver.getServiceNameList(mUserId);
|
|
||||||
for (int i = 0; i < services.length; i++) {
|
|
||||||
if (serviceName.equals(services[i])) {
|
|
||||||
return services[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the current service for the user was temporarily set.
|
* Checks whether the current service for the user was temporarily set.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
public final boolean isTemporaryServiceSetLocked() {
|
public final boolean isTemporaryServiceSetLocked() {
|
||||||
return mMaster.mServiceNameResolver.isTemporary(mUserId);
|
return mMaster.mServiceNameResolver.isTemporary(mUserId);
|
||||||
}
|
}
|
||||||
@@ -292,7 +245,6 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
/**
|
/**
|
||||||
* Resets the temporary service implementation to the default component.
|
* Resets the temporary service implementation to the default component.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected final void resetTemporaryServiceLocked() {
|
protected final void resetTemporaryServiceLocked() {
|
||||||
mMaster.mServiceNameResolver.resetTemporaryService(mUserId);
|
mMaster.mServiceNameResolver.resetTemporaryService(mUserId);
|
||||||
}
|
}
|
||||||
@@ -316,7 +268,6 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
return mServiceInfo == null ? null : mServiceInfo.getComponentName();
|
return mServiceInfo == null ? null : mServiceInfo.getComponentName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of the of the app this service binds to, or {@code null} if the service is
|
* Gets the name of the of the app this service binds to, or {@code null} if the service is
|
||||||
* disabled.
|
* disabled.
|
||||||
@@ -352,10 +303,8 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
/**
|
/**
|
||||||
* Removes the service from the main service's cache.
|
* Removes the service from the main service's cache.
|
||||||
*/
|
*/
|
||||||
protected final void removeSelfFromCache() {
|
protected final void removeSelfFromCacheLocked() {
|
||||||
synchronized (mMaster.mLock) {
|
mMaster.removeCachedServiceLocked(mUserId);
|
||||||
mMaster.removeCachedServiceListLocked(mUserId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -378,7 +327,6 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
* Gets the target SDK level of the service this service binds to,
|
* Gets the target SDK level of the service this service binds to,
|
||||||
* or {@code 0} if the service is disabled.
|
* or {@code 0} if the service is disabled.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
public final int getTargedSdkLocked() {
|
public final int getTargedSdkLocked() {
|
||||||
return mServiceInfo == null ? 0 : mServiceInfo.applicationInfo.targetSdkVersion;
|
return mServiceInfo == null ? 0 : mServiceInfo.applicationInfo.targetSdkVersion;
|
||||||
}
|
}
|
||||||
@@ -386,7 +334,6 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
/**
|
/**
|
||||||
* Gets whether the device already finished setup.
|
* Gets whether the device already finished setup.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
|
||||||
protected final boolean isSetupCompletedLocked() {
|
protected final boolean isSetupCompletedLocked() {
|
||||||
return mSetupComplete;
|
return mSetupComplete;
|
||||||
}
|
}
|
||||||
@@ -401,32 +348,19 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
|
|||||||
// TODO(b/117779333): support proto
|
// TODO(b/117779333): support proto
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
|
protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("User: "); pw.println(mUserId);
|
||||||
pw.print("User: ");
|
|
||||||
pw.println(mUserId);
|
|
||||||
if (mServiceInfo != null) {
|
if (mServiceInfo != null) {
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Service Label: "); pw.println(getServiceLabelLocked());
|
||||||
pw.print("Service Label: ");
|
pw.print(prefix); pw.print("Target SDK: "); pw.println(getTargedSdkLocked());
|
||||||
pw.println(getServiceLabelLocked());
|
|
||||||
pw.print(prefix);
|
|
||||||
pw.print("Target SDK: ");
|
|
||||||
pw.println(getTargedSdkLocked());
|
|
||||||
}
|
}
|
||||||
if (mMaster.mServiceNameResolver != null) {
|
if (mMaster.mServiceNameResolver != null) {
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Name resolver: ");
|
||||||
pw.print("Name resolver: ");
|
mMaster.mServiceNameResolver.dumpShort(pw, mUserId); pw.println();
|
||||||
mMaster.mServiceNameResolver.dumpShort(pw, mUserId);
|
|
||||||
pw.println();
|
|
||||||
}
|
}
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Disabled by UserManager: "); pw.println(mDisabled);
|
||||||
pw.print("Disabled by UserManager: ");
|
pw.print(prefix); pw.print("Setup complete: "); pw.println(mSetupComplete);
|
||||||
pw.println(mDisabled);
|
|
||||||
pw.print(prefix);
|
|
||||||
pw.print("Setup complete: ");
|
|
||||||
pw.println(mSetupComplete);
|
|
||||||
if (mServiceInfo != null) {
|
if (mServiceInfo != null) {
|
||||||
pw.print(prefix);
|
pw.print(prefix); pw.print("Service UID: ");
|
||||||
pw.print("Service UID: ");
|
|
||||||
pw.println(mServiceInfo.applicationInfo.uid);
|
pw.println(mServiceInfo.applicationInfo.uid);
|
||||||
}
|
}
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.server.infra;
|
package com.android.server.infra;
|
||||||
|
|
||||||
import android.annotation.ArrayRes;
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.StringRes;
|
import android.annotation.StringRes;
|
||||||
@@ -34,7 +33,6 @@ import android.util.TimeUtils;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the service name using a framework resources, temporarily changing the service if necessary
|
* Gets the service name using a framework resources, temporarily changing the service if necessary
|
||||||
@@ -49,20 +47,20 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
/** Handler message to {@link #resetTemporaryService(int)} */
|
/** Handler message to {@link #resetTemporaryService(int)} */
|
||||||
private static final int MSG_RESET_TEMPORARY_SERVICE = 0;
|
private static final int MSG_RESET_TEMPORARY_SERVICE = 0;
|
||||||
|
|
||||||
@NonNull private final Context mContext;
|
private final @NonNull Context mContext;
|
||||||
@NonNull private final Object mLock = new Object();
|
private final @NonNull Object mLock = new Object();
|
||||||
@StringRes private final int mStringResourceId;
|
private final @StringRes int mResourceId;
|
||||||
@ArrayRes private final int mArrayResourceId;
|
private @Nullable NameResolverListener mOnSetCallback;
|
||||||
private final boolean mIsMultiple;
|
|
||||||
/**
|
/**
|
||||||
* Map of temporary service name list set by {@link #setTemporaryServices(int, String[], int)},
|
* Map of temporary service name set by {@link #setTemporaryService(int, String, int)},
|
||||||
* keyed by {@code userId}.
|
* keyed by {@code userId}.
|
||||||
*
|
*
|
||||||
* <p>Typically used by Shell command and/or CTS tests to configure temporary services if
|
* <p>Typically used by Shell command and/or CTS tests.
|
||||||
* mIsMultiple is true.
|
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final SparseArray<String[]> mTemporaryServiceNamesList = new SparseArray<>();
|
private final SparseArray<String> mTemporaryServiceNames = new SparseArray<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of default services that have been disabled by
|
* Map of default services that have been disabled by
|
||||||
* {@link #setDefaultServiceEnabled(int, boolean)},keyed by {@code userId}.
|
* {@link #setDefaultServiceEnabled(int, boolean)},keyed by {@code userId}.
|
||||||
@@ -71,7 +69,7 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final SparseBooleanArray mDefaultServicesDisabled = new SparseBooleanArray();
|
private final SparseBooleanArray mDefaultServicesDisabled = new SparseBooleanArray();
|
||||||
@Nullable private NameResolverListener mOnSetCallback;
|
|
||||||
/**
|
/**
|
||||||
* When the temporary service will expire (and reset back to the default).
|
* When the temporary service will expire (and reset back to the default).
|
||||||
*/
|
*/
|
||||||
@@ -87,22 +85,7 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
public FrameworkResourcesServiceNameResolver(@NonNull Context context,
|
public FrameworkResourcesServiceNameResolver(@NonNull Context context,
|
||||||
@StringRes int resourceId) {
|
@StringRes int resourceId) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mStringResourceId = resourceId;
|
mResourceId = resourceId;
|
||||||
mArrayResourceId = -1;
|
|
||||||
mIsMultiple = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FrameworkResourcesServiceNameResolver(@NonNull Context context,
|
|
||||||
@ArrayRes int resourceId, boolean isMultiple) {
|
|
||||||
if (!isMultiple) {
|
|
||||||
throw new UnsupportedOperationException("Please use "
|
|
||||||
+ "FrameworkResourcesServiceNameResolver(context, @StringRes int) constructor "
|
|
||||||
+ "if single service mode is requested.");
|
|
||||||
}
|
|
||||||
mContext = context;
|
|
||||||
mStringResourceId = -1;
|
|
||||||
mArrayResourceId = resourceId;
|
|
||||||
mIsMultiple = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,32 +95,23 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getServiceName(@UserIdInt int userId) {
|
|
||||||
String[] serviceNames = getServiceNameList(userId);
|
|
||||||
return (serviceNames == null || serviceNames.length == 0) ? null : serviceNames[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDefaultServiceName(@UserIdInt int userId) {
|
public String getDefaultServiceName(@UserIdInt int userId) {
|
||||||
String[] serviceNames = getDefaultServiceNameList(userId);
|
synchronized (mLock) {
|
||||||
return (serviceNames == null || serviceNames.length == 0) ? null : serviceNames[0];
|
final String name = mContext.getString(mResourceId);
|
||||||
|
return TextUtils.isEmpty(name) ? null : name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the default list of the service names for the given user.
|
|
||||||
*
|
|
||||||
* <p>Typically implemented by services which want to provide multiple backends.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getServiceNameList(int userId) {
|
public String getServiceName(@UserIdInt int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
String[] temporaryNames = mTemporaryServiceNamesList.get(userId);
|
final String temporaryName = mTemporaryServiceNames.get(userId);
|
||||||
if (temporaryNames != null) {
|
if (temporaryName != null) {
|
||||||
// Always log it, as it should only be used on CTS or during development
|
// Always log it, as it should only be used on CTS or during development
|
||||||
Slog.w(TAG, "getServiceName(): using temporary name "
|
Slog.w(TAG, "getServiceName(): using temporary name " + temporaryName
|
||||||
+ Arrays.toString(temporaryNames) + " for user " + userId);
|
+ " for user " + userId);
|
||||||
return temporaryNames;
|
return temporaryName;
|
||||||
}
|
}
|
||||||
final boolean disabled = mDefaultServicesDisabled.get(userId);
|
final boolean disabled = mDefaultServicesDisabled.get(userId);
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
@@ -146,50 +120,22 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
+ "user " + userId);
|
+ "user " + userId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getDefaultServiceNameList(userId);
|
return getDefaultServiceName(userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the default list of the service names for the given user.
|
|
||||||
*
|
|
||||||
* <p>Typically implemented by services which want to provide multiple backends.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String[] getDefaultServiceNameList(int userId) {
|
|
||||||
synchronized (mLock) {
|
|
||||||
if (mIsMultiple) {
|
|
||||||
return mContext.getResources().getStringArray(mArrayResourceId);
|
|
||||||
} else {
|
|
||||||
final String name = mContext.getString(mStringResourceId);
|
|
||||||
return TextUtils.isEmpty(name) ? new String[0] : new String[] { name };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isConfiguredInMultipleMode() {
|
|
||||||
return mIsMultiple;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTemporary(@UserIdInt int userId) {
|
public boolean isTemporary(@UserIdInt int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return mTemporaryServiceNamesList.get(userId) != null;
|
return mTemporaryServiceNames.get(userId) != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
|
public void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
|
||||||
int durationMs) {
|
int durationMs) {
|
||||||
setTemporaryServices(userId, new String[]{componentName}, durationMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTemporaryServices(int userId, @NonNull String[] componentNames, int durationMs) {
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mTemporaryServiceNamesList.put(userId, componentNames);
|
mTemporaryServiceNames.put(userId, componentName);
|
||||||
|
|
||||||
if (mTemporaryHandler == null) {
|
if (mTemporaryHandler == null) {
|
||||||
mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
|
mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
|
||||||
@@ -209,19 +155,17 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
}
|
}
|
||||||
mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs;
|
mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs;
|
||||||
mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs);
|
mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs);
|
||||||
for (int i = 0; i < componentNames.length; i++) {
|
notifyTemporaryServiceNameChangedLocked(userId, componentName,
|
||||||
notifyTemporaryServiceNameChangedLocked(userId, componentNames[i],
|
|
||||||
/* isTemporary= */ true);
|
/* isTemporary= */ true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetTemporaryService(@UserIdInt int userId) {
|
public void resetTemporaryService(@UserIdInt int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
Slog.i(TAG, "resetting temporary service for user " + userId + " from "
|
Slog.i(TAG, "resetting temporary service for user " + userId + " from "
|
||||||
+ Arrays.toString(mTemporaryServiceNamesList.get(userId)));
|
+ mTemporaryServiceNames.get(userId));
|
||||||
mTemporaryServiceNamesList.remove(userId);
|
mTemporaryServiceNames.remove(userId);
|
||||||
if (mTemporaryHandler != null) {
|
if (mTemporaryHandler != null) {
|
||||||
mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE);
|
mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE);
|
||||||
mTemporaryHandler = null;
|
mTemporaryHandler = null;
|
||||||
@@ -263,21 +207,16 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
synchronized (mLock) {
|
return "FrameworkResourcesServiceNamer[temps=" + mTemporaryServiceNames + "]";
|
||||||
return "FrameworkResourcesServiceNamer[temps=" + mTemporaryServiceNamesList + "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/117779333): support proto
|
// TODO(b/117779333): support proto
|
||||||
@Override
|
@Override
|
||||||
public void dumpShort(@NonNull PrintWriter pw) {
|
public void dumpShort(@NonNull PrintWriter pw) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
pw.print("FrameworkResourcesServiceNamer: resId=");
|
pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId);
|
||||||
pw.print(mStringResourceId);
|
pw.print(", numberTemps="); pw.print(mTemporaryServiceNames.size());
|
||||||
pw.print(", numberTemps=");
|
pw.print(", enabledDefaults="); pw.print(mDefaultServicesDisabled.size());
|
||||||
pw.print(mTemporaryServiceNamesList.size());
|
|
||||||
pw.print(", enabledDefaults=");
|
|
||||||
pw.print(mDefaultServicesDisabled.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,17 +224,13 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR
|
|||||||
@Override
|
@Override
|
||||||
public void dumpShort(@NonNull PrintWriter pw, @UserIdInt int userId) {
|
public void dumpShort(@NonNull PrintWriter pw, @UserIdInt int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final String[] temporaryNames = mTemporaryServiceNamesList.get(userId);
|
final String temporaryName = mTemporaryServiceNames.get(userId);
|
||||||
if (temporaryNames != null) {
|
if (temporaryName != null) {
|
||||||
pw.print("tmpName=");
|
pw.print("tmpName="); pw.print(temporaryName);
|
||||||
pw.print(Arrays.toString(temporaryNames));
|
|
||||||
final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime();
|
final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime();
|
||||||
pw.print(" (expires in ");
|
pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print("), ");
|
||||||
TimeUtils.formatDuration(ttl, pw);
|
|
||||||
pw.print("), ");
|
|
||||||
}
|
}
|
||||||
pw.print("defaultName=");
|
pw.print("defaultName="); pw.print(getDefaultServiceName(userId));
|
||||||
pw.print(getDefaultServiceName(userId));
|
|
||||||
final boolean disabled = mDefaultServicesDisabled.get(userId);
|
final boolean disabled = mDefaultServicesDisabled.get(userId);
|
||||||
pw.println(disabled ? " (disabled)" : " (enabled)");
|
pw.println(disabled ? " (disabled)" : " (enabled)");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public interface ServiceNameResolver {
|
|||||||
/**
|
/**
|
||||||
* Listener for name changes.
|
* Listener for name changes.
|
||||||
*/
|
*/
|
||||||
interface NameResolverListener {
|
public interface NameResolverListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name change callback.
|
* The name change callback.
|
||||||
@@ -63,30 +63,6 @@ public interface ServiceNameResolver {
|
|||||||
@Nullable
|
@Nullable
|
||||||
String getDefaultServiceName(@UserIdInt int userId);
|
String getDefaultServiceName(@UserIdInt int userId);
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the default list of names of the services for the given user.
|
|
||||||
*
|
|
||||||
* <p>Typically implemented by reading a Settings property or framework resource.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default String[] getDefaultServiceNameList(@UserIdInt int userId) {
|
|
||||||
if (isConfiguredInMultipleMode()) {
|
|
||||||
throw new UnsupportedOperationException("getting default service list not supported");
|
|
||||||
} else {
|
|
||||||
return new String[] { getDefaultServiceName(userId) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the resolver is configured to connect to multiple backend services.
|
|
||||||
* The default return type is false.
|
|
||||||
*
|
|
||||||
* <p>Typically implemented by reading a Settings property or framework resource.
|
|
||||||
*/
|
|
||||||
default boolean isConfiguredInMultipleMode() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current name of the service for the given user
|
* Gets the current name of the service for the given user
|
||||||
*
|
*
|
||||||
@@ -99,18 +75,6 @@ public interface ServiceNameResolver {
|
|||||||
return getDefaultServiceName(userId);
|
return getDefaultServiceName(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current name of the service for the given user
|
|
||||||
*
|
|
||||||
* @return either the temporary name (set by
|
|
||||||
* {@link #setTemporaryService(int, String, int)}, or the
|
|
||||||
* {@link #getDefaultServiceName(int) default name}.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default String[] getServiceNameList(@UserIdInt int userId) {
|
|
||||||
return getDefaultServiceNameList(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the current service is temporary for the given user.
|
* Checks whether the current service is temporary for the given user.
|
||||||
*/
|
*/
|
||||||
@@ -123,9 +87,9 @@ public interface ServiceNameResolver {
|
|||||||
*
|
*
|
||||||
* @param userId user handle
|
* @param userId user handle
|
||||||
* @param componentName name of the new component
|
* @param componentName name of the new component
|
||||||
* @param durationMs how long the change will be valid (the service will be automatically
|
* @param durationMs how long the change will be valid (the service will be automatically reset
|
||||||
* reset
|
|
||||||
* to the default component after this timeout expires).
|
* to the default component after this timeout expires).
|
||||||
|
*
|
||||||
* @throws UnsupportedOperationException if not implemented.
|
* @throws UnsupportedOperationException if not implemented.
|
||||||
*/
|
*/
|
||||||
default void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
|
default void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
|
||||||
@@ -133,25 +97,11 @@ public interface ServiceNameResolver {
|
|||||||
throw new UnsupportedOperationException("temporary user not supported");
|
throw new UnsupportedOperationException("temporary user not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporarily sets the service implementation for the given user.
|
|
||||||
*
|
|
||||||
* @param userId user handle
|
|
||||||
* @param componentNames list of the names of the new component
|
|
||||||
* @param durationMs how long the change will be valid (the service will be automatically
|
|
||||||
* reset
|
|
||||||
* to the default component after this timeout expires).
|
|
||||||
* @throws UnsupportedOperationException if not implemented.
|
|
||||||
*/
|
|
||||||
default void setTemporaryServices(@UserIdInt int userId, @NonNull String[] componentNames,
|
|
||||||
int durationMs) {
|
|
||||||
throw new UnsupportedOperationException("temporary user not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the temporary service implementation to the default component for the given user.
|
* Resets the temporary service implementation to the default component for the given user.
|
||||||
*
|
*
|
||||||
* @param userId user handle
|
* @param userId user handle
|
||||||
|
*
|
||||||
* @throws UnsupportedOperationException if not implemented.
|
* @throws UnsupportedOperationException if not implemented.
|
||||||
*/
|
*/
|
||||||
default void resetTemporaryService(@UserIdInt int userId) {
|
default void resetTemporaryService(@UserIdInt int userId) {
|
||||||
@@ -166,9 +116,9 @@ public interface ServiceNameResolver {
|
|||||||
*
|
*
|
||||||
* @param userId user handle
|
* @param userId user handle
|
||||||
* @param enabled whether the default service should be used when the temporary service is not
|
* @param enabled whether the default service should be used when the temporary service is not
|
||||||
* set. If the service enabled state is already that value, the command is
|
* set. If the service enabled state is already that value, the command is ignored and this
|
||||||
* ignored and this
|
|
||||||
* method return {@code false}.
|
* method return {@code false}.
|
||||||
|
*
|
||||||
* @return whether the enabled state changed.
|
* @return whether the enabled state changed.
|
||||||
* @throws UnsupportedOperationException if not implemented.
|
* @throws UnsupportedOperationException if not implemented.
|
||||||
*/
|
*/
|
||||||
@@ -183,6 +133,7 @@ public interface ServiceNameResolver {
|
|||||||
* with the test results.
|
* with the test results.
|
||||||
*
|
*
|
||||||
* @param userId user handle
|
* @param userId user handle
|
||||||
|
*
|
||||||
* @throws UnsupportedOperationException if not implemented.
|
* @throws UnsupportedOperationException if not implemented.
|
||||||
*/
|
*/
|
||||||
default boolean isDefaultServiceEnabled(@UserIdInt int userId) {
|
default boolean isDefaultServiceEnabled(@UserIdInt int userId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user