Add app hibernation service stubs

Add app hibernation system service and manager class and start it when
app hibernation flag is enabled.

The actual API is currently stubbed and will be implemented in further
CLs.

Bug: 175829330
Test: adb shell device_config put app_hibernation
app_hibernation_enabled true
adb reboot
adb shell services list

Change-Id: Ide2758d3eaabae7d3df6356d4b6435c5137c554d
This commit is contained in:
Kevin Han
2021-01-05 14:03:58 -08:00
parent 7ae76a2f3f
commit 63576ff7d3
6 changed files with 246 additions and 0 deletions

View File

@@ -1409,6 +1409,15 @@ package android.app.usage {
}
package android.apphibernation {
public final class AppHibernationManager {
method public boolean isHibernating(@NonNull String);
method public void setHibernating(@NonNull String, boolean);
}
}
package android.bluetooth {
public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
@@ -1680,6 +1689,7 @@ package android.content {
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, @Nullable android.os.Bundle);
method public abstract void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
field public static final String APP_HIBERNATION_SERVICE = "app_hibernation";
field public static final String APP_INTEGRITY_SERVICE = "app_integrity";
field public static final String APP_PREDICTION_SERVICE = "app_prediction";
field public static final String BACKUP_SERVICE = "backup";

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.apphibernation;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
/**
* This class provides an API surface for system apps to manipulate the app hibernation
* state of a package for the user provided in the context.
* @hide
*/
@SystemApi
@SystemService(Context.APP_HIBERNATION_SERVICE)
public final class AppHibernationManager {
private static final String TAG = "AppHibernationManager";
private final Context mContext;
private final IAppHibernationService mIAppHibernationService;
/**
* Creates a new instance.
*
* @param context The current context associated with the user
*
* @hide
*/
public AppHibernationManager(@NonNull Context context) {
mContext = context;
mIAppHibernationService = IAppHibernationService.Stub.asInterface(
ServiceManager.getService(Context.APP_HIBERNATION_SERVICE));
}
/**
* Returns true if the package is hibernating, false otherwise.
*
* @hide
*/
@SystemApi
public boolean isHibernating(@NonNull String packageName) {
try {
return mIAppHibernationService.isHibernating(packageName, mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Set whether the package is hibernating.
*
* @hide
*/
@SystemApi
public void setHibernating(@NonNull String packageName, boolean isHibernating) {
try {
mIAppHibernationService.setHibernating(packageName, mContext.getUserId(),
isHibernating);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.apphibernation;
/**
* Binder interface to communicate with AppHibernationService.
* @hide
*/
interface IAppHibernationService {
boolean isHibernating(String packageName, int userId);
void setHibernating(String packageName, int userId, boolean isHibernating);
}

View File

@@ -4508,6 +4508,17 @@ public abstract class Context {
*/
public static final String PERMISSION_CONTROLLER_SERVICE = "permission_controller";
/**
* Use with {@link #getSystemService(String) to retrieve an
* {@link android.apphibernation.AppHibernationManager}} for
* communicating with the hibernation service.
* @hide
*
* @see #getSystemService(String)
*/
@SystemApi
public static final String APP_HIBERNATION_SERVICE = "app_hibernation";
/**
* Use with {@link #getSystemService(String)} to retrieve an
* {@link android.app.backup.IBackupManager IBackupManager} for communicating

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.apphibernation;
import static android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
import android.annotation.NonNull;
import android.apphibernation.IAppHibernationService;
import android.content.Context;
import android.provider.DeviceConfig;
import com.android.server.SystemService;
/**
* System service that manages app hibernation state, a state apps can enter that means they are
* not being actively used and can be optimized for storage. The actual policy for determining
* if an app should hibernate is managed by PermissionController code.
*/
public final class AppHibernationService extends SystemService {
private final Context mContext;
/**
* Initializes the system service.
* <p>
* Subclasses must define a single argument constructor that accepts the context
* and passes it to super.
* </p>
*
* @param context The system server context.
*/
public AppHibernationService(@NonNull Context context) {
super(context);
mContext = context;
}
@Override
public void onStart() {
publishBinderService(Context.APP_HIBERNATION_SERVICE, mServiceStub);
}
/**
* Whether a package is hibernating for a given user.
*
* @param packageName the package to check
* @param userId the user to check
* @return true if package is hibernating for the user
*/
public boolean isHibernating(String packageName, int userId) {
// Stub
throw new UnsupportedOperationException("Hibernation state management not implemented yet");
}
/**
* Set whether the package is hibernating for the given user.
*
* @param packageName package to modify state
* @param userId user
* @param isHibernating new hibernation state
*/
public void setHibernating(String packageName, int userId, boolean isHibernating) {
// Stub
throw new UnsupportedOperationException("Hibernation state management not implemented yet");
}
private final AppHibernationServiceStub mServiceStub = new AppHibernationServiceStub(this);
static final class AppHibernationServiceStub extends IAppHibernationService.Stub {
final AppHibernationService mService;
AppHibernationServiceStub(AppHibernationService service) {
mService = service;
}
@Override
public boolean isHibernating(String packageName, int userId) {
return mService.isHibernating(packageName, userId);
}
@Override
public void setHibernating(String packageName, int userId, boolean isHibernating) {
mService.setHibernating(packageName, userId, isHibernating);
}
}
/**
* Whether app hibernation is enabled on this device.
*
* @return true if enabled, false otherwise
*/
public static boolean isAppHibernationEnabled() {
return DeviceConfig.getBoolean(
NAMESPACE_APP_HIBERNATION,
AppHibernationConstants.KEY_APP_HIBERNATION_ENABLED,
false /* defaultValue */);
}
}

View File

@@ -93,6 +93,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.ILockSettings;
import com.android.server.am.ActivityManagerService;
import com.android.server.appbinding.AppBindingService;
import com.android.server.apphibernation.AppHibernationService;
import com.android.server.attention.AttentionManagerService;
import com.android.server.audio.AudioService;
import com.android.server.biometrics.AuthService;
@@ -215,6 +216,8 @@ public final class SystemServer {
"com.android.server.appwidget.AppWidgetService";
private static final String VOICE_RECOGNITION_MANAGER_SERVICE_CLASS =
"com.android.server.voiceinteraction.VoiceInteractionManagerService";
private static final String APP_HIBERNATION_SERVICE_CLASS =
"com.android.server.apphibernation.AppHibernationService";
private static final String PRINT_MANAGER_SERVICE_CLASS =
"com.android.server.print.PrintManagerService";
private static final String COMPANION_DEVICE_MANAGER_SERVICE_CLASS =
@@ -1798,6 +1801,12 @@ public final class SystemServer {
mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS);
t.traceEnd();
if (AppHibernationService.isAppHibernationEnabled()) {
t.traceBegin("StartAppHibernationService");
mSystemServiceManager.startService(APP_HIBERNATION_SERVICE_CLASS);
t.traceEnd();
}
if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) {
t.traceBegin("StartGestureLauncher");
mSystemServiceManager.startService(GestureLauncherService.class);