Merge "Rebind to the remote service if AppPrediction is restarted or updated" into qt-qpr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
edafb21d84
@@ -23,6 +23,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.app.prediction.AppPredictionContext;
|
import android.app.prediction.AppPredictionContext;
|
||||||
import android.app.prediction.AppPredictionSessionId;
|
import android.app.prediction.AppPredictionSessionId;
|
||||||
import android.app.prediction.AppTargetEvent;
|
import android.app.prediction.AppTargetEvent;
|
||||||
@@ -61,7 +62,8 @@ public class AppPredictionManagerService extends
|
|||||||
|
|
||||||
public AppPredictionManagerService(Context context) {
|
public AppPredictionManagerService(Context context) {
|
||||||
super(context, new FrameworkResourcesServiceNameResolver(context,
|
super(context, new FrameworkResourcesServiceNameResolver(context,
|
||||||
com.android.internal.R.string.config_defaultAppPredictionService), null);
|
com.android.internal.R.string.config_defaultAppPredictionService), null,
|
||||||
|
PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
|
||||||
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
|
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +82,22 @@ public class AppPredictionManagerService extends
|
|||||||
getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG);
|
getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // from AbstractMasterSystemService
|
||||||
|
protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
|
||||||
|
final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
|
||||||
|
if (service != null) {
|
||||||
|
service.onPackageUpdatedLocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // from AbstractMasterSystemService
|
||||||
|
protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
|
||||||
|
final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
|
||||||
|
if (service != null) {
|
||||||
|
service.onPackageRestartedLocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getMaximumTemporaryServiceDurationMs() {
|
protected int getMaximumTemporaryServiceDurationMs() {
|
||||||
return MAX_TEMP_SERVICE_DURATION_MS;
|
return MAX_TEMP_SERVICE_DURATION_MS;
|
||||||
|
|||||||
@@ -251,6 +251,40 @@ public class AppPredictionPerUserService extends
|
|||||||
// Do nothing, eventually the system will bind to the remote service again...
|
// Do nothing, eventually the system will bind to the remote service again...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onPackageUpdatedLocked() {
|
||||||
|
if (isDebug()) {
|
||||||
|
Slog.v(TAG, "onPackageUpdatedLocked()");
|
||||||
|
}
|
||||||
|
destroyAndRebindRemoteService();
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPackageRestartedLocked() {
|
||||||
|
if (isDebug()) {
|
||||||
|
Slog.v(TAG, "onPackageRestartedLocked()");
|
||||||
|
}
|
||||||
|
destroyAndRebindRemoteService();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void destroyAndRebindRemoteService() {
|
||||||
|
if (mRemoteService == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDebug()) {
|
||||||
|
Slog.d(TAG, "Destroying the old remote service.");
|
||||||
|
}
|
||||||
|
mRemoteService.destroy();
|
||||||
|
mRemoteService = null;
|
||||||
|
|
||||||
|
mRemoteService = getRemoteServiceLocked();
|
||||||
|
if (mRemoteService != null) {
|
||||||
|
if (isDebug()) {
|
||||||
|
Slog.d(TAG, "Rebinding to the new remote service.");
|
||||||
|
}
|
||||||
|
mRemoteService.reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after the remote service connected, it's used to restore state from a 'zombie'
|
* Called after the remote service connected, it's used to restore state from a 'zombie'
|
||||||
* service (i.e., after it died).
|
* service (i.e., after it died).
|
||||||
|
|||||||
@@ -134,6 +134,13 @@ public class RemoteAppPredictionService extends
|
|||||||
scheduleAsyncRequest((s) -> s.onDestroyPredictionSession(sessionId));
|
scheduleAsyncRequest((s) -> s.onDestroyPredictionSession(sessionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a request to bind to the remote service.
|
||||||
|
*/
|
||||||
|
public void reconnect() {
|
||||||
|
super.scheduleBind();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Failure callback
|
* Failure callback
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
S extends AbstractPerUserSystemService<S, M>> extends SystemService {
|
S extends AbstractPerUserSystemService<S, M>> extends SystemService {
|
||||||
|
|
||||||
/** On a package update, does not refresh the per-user service in the cache. */
|
/** On a package update, does not refresh the per-user service in the cache. */
|
||||||
public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0;
|
public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0x00000001;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On a package update, removes any existing per-user services in the cache.
|
* On a package update, removes any existing per-user services in the cache.
|
||||||
@@ -87,20 +87,40 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
* <p>This does not immediately recreate these services. It is assumed they will be recreated
|
* <p>This does not immediately recreate these services. It is assumed they will be recreated
|
||||||
* for the next user request.
|
* for the next user request.
|
||||||
*/
|
*/
|
||||||
public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1;
|
public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 0x00000002;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On a package update, removes and recreates any existing per-user services in the cache.
|
* On a package update, removes and recreates any existing per-user services in the cache.
|
||||||
*/
|
*/
|
||||||
public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2;
|
public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 0x00000004;
|
||||||
|
|
||||||
@IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = {
|
/** On a package restart, does not refresh the per-user service in the cache. */
|
||||||
|
public static final int PACKAGE_RESTART_POLICY_NO_REFRESH = 0x00000010;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On a package restart, removes any existing per-user services in the cache.
|
||||||
|
*
|
||||||
|
* <p>This does not immediately recreate these services. It is assumed they will be recreated
|
||||||
|
* for the next user request.
|
||||||
|
*/
|
||||||
|
public static final int PACKAGE_RESTART_POLICY_REFRESH_LAZY = 0x00000020;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On a package restart, removes and recreates any existing per-user services in the cache.
|
||||||
|
*/
|
||||||
|
public static final int PACKAGE_RESTART_POLICY_REFRESH_EAGER = 0x00000040;
|
||||||
|
|
||||||
|
@IntDef(flag = true, prefix = { "PACKAGE_" }, value = {
|
||||||
PACKAGE_UPDATE_POLICY_NO_REFRESH,
|
PACKAGE_UPDATE_POLICY_NO_REFRESH,
|
||||||
PACKAGE_UPDATE_POLICY_REFRESH_LAZY,
|
PACKAGE_UPDATE_POLICY_REFRESH_LAZY,
|
||||||
PACKAGE_UPDATE_POLICY_REFRESH_EAGER
|
PACKAGE_UPDATE_POLICY_REFRESH_EAGER,
|
||||||
|
PACKAGE_RESTART_POLICY_NO_REFRESH,
|
||||||
|
PACKAGE_RESTART_POLICY_REFRESH_LAZY,
|
||||||
|
PACKAGE_RESTART_POLICY_REFRESH_EAGER
|
||||||
})
|
})
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface PackageUpdatePolicy {}
|
public @interface ServicePackagePolicyFlags {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log tag
|
* Log tag
|
||||||
@@ -153,12 +173,10 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
private final SparseArray<S> mServicesCache = new SparseArray<>();
|
private final SparseArray<S> mServicesCache = new SparseArray<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the per-user service should be removed from the cache when its apk is updated.
|
* Value that determines whether the per-user service should be removed from the cache when its
|
||||||
*
|
* apk is updated or restarted.
|
||||||
* <p>One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
|
|
||||||
* {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}.
|
|
||||||
*/
|
*/
|
||||||
private final @PackageUpdatePolicy int mPackageUpdatePolicy;
|
private final @ServicePackagePolicyFlags int mServicePackagePolicyFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the service packages whose APK are being updated, keyed by user id.
|
* Name of the service packages whose APK are being updated, keyed by user id.
|
||||||
@@ -184,11 +202,11 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
@Nullable ServiceNameResolver serviceNameResolver,
|
@Nullable ServiceNameResolver serviceNameResolver,
|
||||||
@Nullable String disallowProperty) {
|
@Nullable String disallowProperty) {
|
||||||
this(context, serviceNameResolver, disallowProperty,
|
this(context, serviceNameResolver, disallowProperty,
|
||||||
/*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY);
|
PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_LAZY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Full constructor.
|
* Full Constructor.
|
||||||
*
|
*
|
||||||
* @param context system context.
|
* @param context system context.
|
||||||
* @param serviceNameResolver resolver for
|
* @param serviceNameResolver resolver for
|
||||||
@@ -197,19 +215,32 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
* @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
|
* @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
|
||||||
* disables the service. <b>NOTE: </b> you'll also need to add it to
|
* disables the service. <b>NOTE: </b> you'll also need to add it to
|
||||||
* {@code UserRestrictionsUtils.USER_RESTRICTIONS}.
|
* {@code UserRestrictionsUtils.USER_RESTRICTIONS}.
|
||||||
* @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the
|
* @param servicePackagePolicyFlags a combination of
|
||||||
* {@link AbstractPerUserSystemService} is removed from the cache when the service
|
* {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
|
||||||
* package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the
|
* {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY},
|
||||||
* {@link AbstractPerUserSystemService} is removed from the cache and immediately
|
* {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER},
|
||||||
* re-added when the service package is updated; when
|
* {@link #PACKAGE_RESTART_POLICY_NO_REFRESH},
|
||||||
* {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update.
|
* {@link #PACKAGE_RESTART_POLICY_REFRESH_LAZY} or
|
||||||
|
* {@link #PACKAGE_RESTART_POLICY_REFRESH_EAGER}
|
||||||
*/
|
*/
|
||||||
protected AbstractMasterSystemService(@NonNull Context context,
|
protected AbstractMasterSystemService(@NonNull Context context,
|
||||||
@Nullable ServiceNameResolver serviceNameResolver,
|
@Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty,
|
||||||
@Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) {
|
@ServicePackagePolicyFlags int servicePackagePolicyFlags) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
mPackageUpdatePolicy = packageUpdatePolicy;
|
final int updatePolicyMask = PACKAGE_UPDATE_POLICY_NO_REFRESH
|
||||||
|
| PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_UPDATE_POLICY_REFRESH_EAGER;
|
||||||
|
if ((servicePackagePolicyFlags & updatePolicyMask) == 0) {
|
||||||
|
// If the package update policy is not set, add the default flag
|
||||||
|
servicePackagePolicyFlags |= PACKAGE_UPDATE_POLICY_REFRESH_LAZY;
|
||||||
|
}
|
||||||
|
final int restartPolicyMask = PACKAGE_RESTART_POLICY_NO_REFRESH
|
||||||
|
| PACKAGE_RESTART_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_EAGER;
|
||||||
|
if ((servicePackagePolicyFlags & restartPolicyMask) == 0) {
|
||||||
|
// If the package restart policy is not set, add the default flag
|
||||||
|
servicePackagePolicyFlags |= PACKAGE_RESTART_POLICY_REFRESH_LAZY;
|
||||||
|
}
|
||||||
|
mServicePackagePolicyFlags = servicePackagePolicyFlags;
|
||||||
|
|
||||||
mServiceNameResolver = serviceNameResolver;
|
mServiceNameResolver = serviceNameResolver;
|
||||||
if (mServiceNameResolver != null) {
|
if (mServiceNameResolver != null) {
|
||||||
@@ -605,6 +636,20 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
|
if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the package data that provides the service for the given user is cleared.
|
||||||
|
*/
|
||||||
|
protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
|
||||||
|
if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the package that provides the service for the given user is restarted.
|
||||||
|
*/
|
||||||
|
protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
|
||||||
|
if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after the service is removed from the cache.
|
* Called after the service is removed from the cache.
|
||||||
*/
|
*/
|
||||||
@@ -677,7 +722,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
final int size = mServicesCache.size();
|
final int size = mServicesCache.size();
|
||||||
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
|
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
|
||||||
pw.print(" Verbose: "); pw.println(realVerbose);
|
pw.print(" Verbose: "); pw.println(realVerbose);
|
||||||
pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy);
|
pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags);
|
||||||
if (mUpdatingPackageNames != null) {
|
if (mUpdatingPackageNames != null) {
|
||||||
pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
|
pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
|
||||||
}
|
}
|
||||||
@@ -733,7 +778,12 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
}
|
}
|
||||||
mUpdatingPackageNames.put(userId, packageName);
|
mUpdatingPackageNames.put(userId, packageName);
|
||||||
onServicePackageUpdatingLocked(userId);
|
onServicePackageUpdatingLocked(userId);
|
||||||
if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) {
|
if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) {
|
||||||
|
if (debug) {
|
||||||
|
Slog.d(mTag, "Holding service for user " + userId + " while package "
|
||||||
|
+ activePackageName + " is being updated");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
Slog.d(mTag, "Removing service for user " + userId
|
Slog.d(mTag, "Removing service for user " + userId
|
||||||
+ " because package " + activePackageName
|
+ " because package " + activePackageName
|
||||||
@@ -741,18 +791,14 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
}
|
}
|
||||||
removeCachedServiceLocked(userId);
|
removeCachedServiceLocked(userId);
|
||||||
|
|
||||||
if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) {
|
if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
|
||||||
|
!= 0) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
Slog.d(mTag, "Eagerly recreating service for user "
|
Slog.d(mTag, "Eagerly recreating service for user "
|
||||||
+ userId);
|
+ userId);
|
||||||
}
|
}
|
||||||
getServiceForUserLocked(userId);
|
getServiceForUserLocked(userId);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (debug) {
|
|
||||||
Slog.d(mTag, "Holding service for user " + userId + " while package "
|
|
||||||
+ activePackageName + " is being updated");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -804,7 +850,13 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
if (!doit) {
|
if (!doit) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
removeCachedServiceLocked(getChangingUserId());
|
final String action = intent.getAction();
|
||||||
|
final int userId = getChangingUserId();
|
||||||
|
if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
|
||||||
|
handleActiveServiceRestartedLocked(activePackageName, userId);
|
||||||
|
} else {
|
||||||
|
removeCachedServiceLocked(userId);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
handlePackageUpdateLocked(pkg);
|
handlePackageUpdateLocked(pkg);
|
||||||
}
|
}
|
||||||
@@ -813,6 +865,23 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPackageDataCleared(String packageName, int uid) {
|
||||||
|
if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName);
|
||||||
|
final int userId = getChangingUserId();
|
||||||
|
synchronized (mLock) {
|
||||||
|
final S service = peekServiceForUserLocked(userId);
|
||||||
|
if (service != null) {
|
||||||
|
final ComponentName componentName = service.getServiceComponentName();
|
||||||
|
if (componentName != null) {
|
||||||
|
if (packageName.equals(componentName.getPackageName())) {
|
||||||
|
onServicePackageDataClearedLocked(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleActiveServiceRemoved(@UserIdInt int userId) {
|
private void handleActiveServiceRemoved(@UserIdInt int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
removeCachedServiceLocked(userId);
|
removeCachedServiceLocked(userId);
|
||||||
@@ -824,6 +893,31 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleActiveServiceRestartedLocked(String activePackageName,
|
||||||
|
@UserIdInt int userId) {
|
||||||
|
if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
|
||||||
|
if (debug) {
|
||||||
|
Slog.d(mTag, "Holding service for user " + userId + " while package "
|
||||||
|
+ activePackageName + " is being restarted");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (debug) {
|
||||||
|
Slog.d(mTag, "Removing service for user " + userId
|
||||||
|
+ " because package " + activePackageName
|
||||||
|
+ " is being restarted");
|
||||||
|
}
|
||||||
|
removeCachedServiceLocked(userId);
|
||||||
|
|
||||||
|
if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
|
||||||
|
if (debug) {
|
||||||
|
Slog.d(mTag, "Eagerly recreating service for user " + userId);
|
||||||
|
}
|
||||||
|
getServiceForUserLocked(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onServicePackageRestartedLocked(userId);
|
||||||
|
}
|
||||||
|
|
||||||
private String getActiveServicePackageNameLocked() {
|
private String getActiveServicePackageNameLocked() {
|
||||||
final int userId = getChangingUserId();
|
final int userId = getChangingUserId();
|
||||||
final S service = peekServiceForUserLocked(userId);
|
final S service = peekServiceForUserLocked(userId);
|
||||||
|
|||||||
Reference in New Issue
Block a user