Merge "Introduce run-cleanup adb command for CTS test" into tm-dev am: ea8aa9e338

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17623973

Change-Id: I524ba61eb3bff52d1bfb7ae96e2f59ce7244c227
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Sergey Nikolaienkov
2022-05-14 06:39:37 +00:00
committed by Automerger Merge Worker
5 changed files with 56 additions and 38 deletions

View File

@@ -7044,7 +7044,7 @@
android:permission="android.permission.BIND_JOB_SERVICE"> android:permission="android.permission.BIND_JOB_SERVICE">
</service> </service>
<service android:name="com.android.server.companion.AssociationCleanUpService" <service android:name="com.android.server.companion.InactiveAssociationsRemovalService"
android:permission="android.permission.BIND_JOB_SERVICE"> android:permission="android.permission.BIND_JOB_SERVICE">
</service> </service>

View File

@@ -78,6 +78,7 @@ import android.os.RemoteException;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.ShellCallback; import android.os.ShellCallback;
import android.os.SystemProperties;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.util.ArraySet; import android.util.ArraySet;
@@ -121,8 +122,10 @@ public class CompanionDeviceManagerService extends SystemService {
private static final String PREF_FILE_NAME = "companion_device_preferences.xml"; private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done"; private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done";
private static final String SYS_PROP_DEBUG_REMOVAL_TIME_WINDOW =
"debug.cdm.cdmservice.removal_time_window";
private static final long ASSOCIATION_CLEAN_UP_TIME_WINDOW = DAYS.toMillis(3 * 30); // 3 months private static final long ASSOCIATION_REMOVAL_TIME_WINDOW_DEFAULT = DAYS.toMillis(90);
private PersistentDataStore mPersistentStore; private PersistentDataStore mPersistentStore;
private final PersistUserStateHandler mUserPersistenceHandler; private final PersistUserStateHandler mUserPersistenceHandler;
@@ -211,8 +214,8 @@ public class CompanionDeviceManagerService extends SystemService {
mPackageMonitor.register(context, FgThread.get().getLooper(), UserHandle.ALL, true); mPackageMonitor.register(context, FgThread.get().getLooper(), UserHandle.ALL, true);
mDevicePresenceMonitor.init(context); mDevicePresenceMonitor.init(context);
} else if (phase == PHASE_BOOT_COMPLETED) { } else if (phase == PHASE_BOOT_COMPLETED) {
// Run the Association CleanUp job service daily. // Run the Inactive Association Removal job service daily.
AssociationCleanUpService.schedule(getContext()); InactiveAssociationsRemovalService.schedule(getContext());
} }
} }
@@ -410,17 +413,20 @@ public class CompanionDeviceManagerService extends SystemService {
mCompanionAppController.onPackagesChanged(userId); mCompanionAppController.onPackagesChanged(userId);
} }
// Revoke associations if the selfManaged companion device does not connect for 3 // Revoke associations if the selfManaged companion device does not connect for 3 months.
// months for specific profile. void removeInactiveSelfManagedAssociations() {
private void associationCleanUp(String profile) { final long currentTime = System.currentTimeMillis();
long removalWindow = SystemProperties.getLong(SYS_PROP_DEBUG_REMOVAL_TIME_WINDOW, -1);
if (removalWindow <= 0) {
// 0 or negative values indicate that the sysprop was never set or should be ignored.
removalWindow = ASSOCIATION_REMOVAL_TIME_WINDOW_DEFAULT;
}
for (AssociationInfo ai : mAssociationStore.getAssociations()) { for (AssociationInfo ai : mAssociationStore.getAssociations()) {
if (ai.isSelfManaged() if (!ai.isSelfManaged()) continue;
&& profile.equals(ai.getDeviceProfile()) final boolean isInactive = currentTime - ai.getLastTimeConnectedMs() >= removalWindow;
&& System.currentTimeMillis() - ai.getLastTimeConnectedMs() if (isInactive) {
>= ASSOCIATION_CLEAN_UP_TIME_WINDOW) { Slog.i(TAG, "Removing inactive self-managed association: " + ai.getId());
Slog.i(TAG, "Removing the association for associationId: "
+ ai.getId()
+ " due to the device does not connect for 3 months.");
disassociateInternal(ai.getId()); disassociateInternal(ai.getId());
} }
} }
@@ -1078,10 +1084,10 @@ public class CompanionDeviceManagerService extends SystemService {
return ArrayUtils.contains(array, a) || ArrayUtils.contains(array, b); return ArrayUtils.contains(array, a) || ArrayUtils.contains(array, b);
} }
private class LocalService extends CompanionDeviceManagerServiceInternal { private class LocalService implements CompanionDeviceManagerServiceInternal {
@Override @Override
public void associationCleanUp(String profile) { public void removeInactiveSelfManagedAssociations() {
CompanionDeviceManagerService.this.associationCleanUp(profile); CompanionDeviceManagerService.this.removeInactiveSelfManagedAssociations();
} }
} }

View File

@@ -18,12 +18,10 @@ package com.android.server.companion;
/** /**
* Companion Device Manager Local System Service Interface. * Companion Device Manager Local System Service Interface.
*
* @hide Only for use within the system server.
*/ */
public abstract class CompanionDeviceManagerServiceInternal { interface CompanionDeviceManagerServiceInternal {
/** /**
* @see CompanionDeviceManagerService#associationCleanUp * @see CompanionDeviceManagerService#removeInactiveSelfManagedAssociations
*/ */
public abstract void associationCleanUp(String profile); void removeInactiveSelfManagedAssociations();
} }

View File

@@ -17,6 +17,7 @@
package com.android.server.companion; package com.android.server.companion;
import android.companion.AssociationInfo; import android.companion.AssociationInfo;
import android.os.Binder;
import android.os.ShellCommand; import android.os.ShellCommand;
import android.util.Log; import android.util.Log;
import android.util.Slog; import android.util.Slog;
@@ -96,6 +97,16 @@ class CompanionDeviceShellCommand extends ShellCommand {
mDevicePresenceMonitor.simulateDeviceDisappeared(associationId); mDevicePresenceMonitor.simulateDeviceDisappeared(associationId);
break; break;
case "remove-inactive-associations": {
// This command should trigger the same "clean-up" job as performed by the
// InactiveAssociationsRemovalService JobService. However, since the
// InactiveAssociationsRemovalService run as system, we want to run this
// as system (not as shell/root) as well.
Binder.withCleanCallingIdentity(
mService::removeInactiveSelfManagedAssociations);
}
break;
default: default:
return handleDefaultCommands(cmd); return handleDefaultCommands(cmd);
} }
@@ -142,6 +153,12 @@ class CompanionDeviceShellCommand extends ShellCommand {
pw.println(" invoked for the same device (same ASSOCIATION_ID) no longer than"); pw.println(" invoked for the same device (same ASSOCIATION_ID) no longer than");
pw.println(" 60 seconds ago."); pw.println(" 60 seconds ago.");
pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY."); pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");
pw.println(" remove-inactive-associations");
pw.println(" Remove self-managed associations that have not been active ");
pw.println(" for a long time (90 days or as configured via ");
pw.println(" \"debug.cdm.cdmservice.cleanup_time_window\" system property). ");
pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");
} }
private int getNextIntArgRequired() { private int getNextIntArgRequired() {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2021 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -24,10 +24,8 @@ import android.app.job.JobInfo;
import android.app.job.JobParameters; import android.app.job.JobParameters;
import android.app.job.JobScheduler; import android.app.job.JobScheduler;
import android.app.job.JobService; import android.app.job.JobService;
import android.companion.AssociationRequest;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask;
import android.util.Slog; import android.util.Slog;
import com.android.server.LocalServices; import com.android.server.LocalServices;
@@ -37,26 +35,24 @@ import com.android.server.LocalServices;
* The job will be executed only if the device is charging and in idle mode due to the application * The job will be executed only if the device is charging and in idle mode due to the application
* will be killed if association/role are revoked. * will be killed if association/role are revoked.
*/ */
public class AssociationCleanUpService extends JobService { public class InactiveAssociationsRemovalService extends JobService {
private static final int JOB_ID = AssociationCleanUpService.class.hashCode(); private static final int JOB_ID = InactiveAssociationsRemovalService.class.hashCode();
private static final long ONE_DAY_INTERVAL = DAYS.toMillis(1); private static final long ONE_DAY_INTERVAL = DAYS.toMillis(1);
@Override @Override
public boolean onStartJob(final JobParameters params) { public boolean onStartJob(final JobParameters params) {
Slog.i(TAG, "Execute the Association CleanUp job"); Slog.i(TAG, "Execute the Association Removal job");
// Special policy for APP_STREAMING role that need to revoke associations if the device // Special policy for selfManaged that need to revoke associations if the device
// does not connect for 3 months. // does not connect for 90 days.
AsyncTask.execute(() -> {
LocalServices.getService(CompanionDeviceManagerServiceInternal.class) LocalServices.getService(CompanionDeviceManagerServiceInternal.class)
.associationCleanUp(AssociationRequest.DEVICE_PROFILE_APP_STREAMING); .removeInactiveSelfManagedAssociations();
jobFinished(params, false); jobFinished(params, false);
});
return true; return true;
} }
@Override @Override
public boolean onStopJob(final JobParameters params) { public boolean onStopJob(final JobParameters params) {
Slog.i(TAG, "Association cleanup job stopped; id=" + params.getJobId() Slog.i(TAG, "Association removal job stopped; id=" + params.getJobId()
+ ", reason=" + ", reason="
+ JobParameters.getInternalReasonCodeDescription( + JobParameters.getInternalReasonCodeDescription(
params.getInternalStopReasonCode())); params.getInternalStopReasonCode()));
@@ -64,10 +60,10 @@ public class AssociationCleanUpService extends JobService {
} }
static void schedule(Context context) { static void schedule(Context context) {
Slog.i(TAG, "Scheduling the Association Cleanup job"); Slog.i(TAG, "Scheduling the Association Removal job");
final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
final JobInfo job = new JobInfo.Builder(JOB_ID, final JobInfo job = new JobInfo.Builder(JOB_ID,
new ComponentName(context, AssociationCleanUpService.class)) new ComponentName(context, InactiveAssociationsRemovalService.class))
.setRequiresCharging(true) .setRequiresCharging(true)
.setRequiresDeviceIdle(true) .setRequiresDeviceIdle(true)
.setPeriodic(ONE_DAY_INTERVAL) .setPeriodic(ONE_DAY_INTERVAL)
@@ -75,3 +71,4 @@ public class AssociationCleanUpService extends JobService {
jobScheduler.schedule(job); jobScheduler.schedule(job);
} }
} }