Merge "Enable WearableSensingService."

This commit is contained in:
Charlie Wang
2022-12-07 14:09:47 +00:00
committed by Android (Google) Code Review
4 changed files with 261 additions and 0 deletions

View File

@@ -51,6 +51,8 @@ import android.app.usage.StorageStatsManager;
import android.app.usage.UsageStatsManager;
import android.app.wallpapereffectsgeneration.IWallpaperEffectsGenerationManager;
import android.app.wallpapereffectsgeneration.WallpaperEffectsGenerationManager;
import android.app.wearable.IWearableSensingManager;
import android.app.wearable.WearableSensingManager;
import android.apphibernation.AppHibernationManager;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothFrameworkInitializer;
@@ -1544,6 +1546,17 @@ public final class SystemServiceRegistry {
IAmbientContextManager.Stub.asInterface(iBinder);
return new AmbientContextManager(ctx.getOuterContext(), manager);
}});
registerService(Context.WEARABLE_SENSING_SERVICE, WearableSensingManager.class,
new CachedServiceFetcher<WearableSensingManager>() {
@Override
public WearableSensingManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
IBinder iBinder = ServiceManager.getServiceOrThrow(
Context.WEARABLE_SENSING_SERVICE);
IWearableSensingManager manager =
IWearableSensingManager.Stub.asInterface(iBinder);
return new WearableSensingManager(ctx.getOuterContext(), manager);
}});
sInitializing = true;
try {

View File

@@ -161,6 +161,32 @@ public class WearableSensingManagerService extends
return null;
}
// Used in testing.
void provideDataStream(@UserIdInt int userId, ParcelFileDescriptor parcelFileDescriptor,
RemoteCallback callback) {
synchronized (mLock) {
final WearableSensingManagerPerUserService mService = getServiceForUserLocked(userId);
if (mService != null) {
mService.onProvideDataStream(parcelFileDescriptor, callback);
} else {
Slog.w(TAG, "Service not available.");
}
}
}
// Used in testing.
void provideData(@UserIdInt int userId, PersistableBundle data, SharedMemory sharedMemory,
RemoteCallback callback) {
synchronized (mLock) {
final WearableSensingManagerPerUserService mService = getServiceForUserLocked(userId);
if (mService != null) {
mService.onProvidedData(data, sharedMemory, callback);
} else {
Slog.w(TAG, "Service not available.");
}
}
}
private final class WearableSensingManagerInternal extends IWearableSensingManager.Stub {
final WearableSensingManagerPerUserService mService = getServiceForUserLocked(
UserHandle.getCallingUserId());
@@ -205,6 +231,8 @@ public class WearableSensingManagerService extends
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
new WearableSensingShellCommand(WearableSensingManagerService.this).exec(
this, in, out, err, args, callback, resultReceiver);
}
}
}

View File

@@ -0,0 +1,212 @@
/*
* Copyright (C) 2022 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.wearable;
import android.annotation.NonNull;
import android.app.wearable.WearableSensingManager;
import android.content.ComponentName;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.ShellCommand;
import android.util.Slog;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
final class WearableSensingShellCommand extends ShellCommand {
private static final String TAG = WearableSensingShellCommand.class.getSimpleName();
static final TestableCallbackInternal sTestableCallbackInternal =
new TestableCallbackInternal();
@NonNull
private final WearableSensingManagerService mService;
private static ParcelFileDescriptor[] sPipe;
WearableSensingShellCommand(@NonNull WearableSensingManagerService service) {
mService = service;
}
/** Callbacks for WearableSensingService results used internally for testing. */
static class TestableCallbackInternal {
private int mLastStatus;
public int getLastStatus() {
return mLastStatus;
}
@NonNull
private RemoteCallback createRemoteStatusCallback() {
return new RemoteCallback(result -> {
int status = result.getInt(WearableSensingManager.STATUS_RESPONSE_BUNDLE_KEY);
final long token = Binder.clearCallingIdentity();
try {
mLastStatus = status;
} finally {
Binder.restoreCallingIdentity(token);
}
});
}
}
@Override
public int onCommand(String cmd) {
if (cmd == null) {
return handleDefaultCommands(cmd);
}
switch (cmd) {
case "create-data-stream":
return createDataStream();
case "destroy-data-stream":
return destroyDataStream();
case "provide-data-stream":
return provideDataStream();
case "write-to-data-stream":
return writeToDataStream();
case "provide-data":
return provideData();
case "get-last-status-code":
return getLastStatusCode();
case "get-bound-package":
return getBoundPackageName();
case "set-temporary-service":
return setTemporaryService();
default:
return handleDefaultCommands(cmd);
}
}
@Override
public void onHelp() {
PrintWriter pw = getOutPrintWriter();
pw.println("WearableSensingCommands commands: ");
pw.println(" help");
pw.println(" Print this help text.");
pw.println();
pw.println(" create-data-stream: Creates a data stream to be provided.");
pw.println(" destroy-data-stream: Destroys a data stream if one was previously created.");
pw.println(" provide-data-stream USER_ID: "
+ "Provides data stream to WearableSensingService.");
pw.println(" write-to-data-stream STRING: writes string to data stream.");
pw.println(" provide-data USER_ID KEY INTEGER: provide integer as data with key.");
pw.println(" get-last-status-code: Prints the latest request status code.");
pw.println(" get-bound-package USER_ID:"
+ " Print the bound package that implements the service.");
pw.println(" set-temporary-service USER_ID [PACKAGE_NAME] [COMPONENT_NAME DURATION]");
pw.println(" Temporarily (for DURATION ms) changes the service implementation.");
pw.println(" To reset, call with just the USER_ID argument.");
}
private int createDataStream() {
Slog.d(TAG, "createDataStream");
try {
sPipe = ParcelFileDescriptor.createPipe();
} catch (IOException e) {
Slog.d(TAG, "Failed to createDataStream.", e);
}
return 0;
}
private int destroyDataStream() {
Slog.d(TAG, "destroyDataStream");
try {
if (sPipe != null) {
sPipe[0].close();
sPipe[1].close();
}
} catch (IOException e) {
Slog.d(TAG, "Failed to destroyDataStream.", e);
}
return 0;
}
private int provideDataStream() {
Slog.d(TAG, "provideDataStream");
if (sPipe != null) {
final int userId = Integer.parseInt(getNextArgRequired());
mService.provideDataStream(userId, sPipe[0],
sTestableCallbackInternal.createRemoteStatusCallback());
}
return 0;
}
private int writeToDataStream() {
Slog.d(TAG, "writeToDataStream");
if (sPipe != null) {
final String value = getNextArgRequired();
try {
ParcelFileDescriptor writePipe = sPipe[1].dup();
OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(writePipe);
os.write(value.getBytes());
} catch (IOException e) {
Slog.d(TAG, "Failed to writeToDataStream.", e);
}
}
return 0;
}
private int provideData() {
Slog.d(TAG, "provideData");
final int userId = Integer.parseInt(getNextArgRequired());
final String key = getNextArgRequired();
final int value = Integer.parseInt(getNextArgRequired());
PersistableBundle data = new PersistableBundle();
data.putInt(key, value);
mService.provideData(userId, data, null,
sTestableCallbackInternal.createRemoteStatusCallback());
return 0;
}
private int getLastStatusCode() {
Slog.d(TAG, "getLastStatusCode");
final PrintWriter resultPrinter = getOutPrintWriter();
int lastStatus = sTestableCallbackInternal.getLastStatus();
resultPrinter.println(lastStatus);
return 0;
}
private int setTemporaryService() {
final PrintWriter out = getOutPrintWriter();
final int userId = Integer.parseInt(getNextArgRequired());
final String serviceName = getNextArg();
if (serviceName == null) {
mService.resetTemporaryService(userId);
out.println("WearableSensingManagerService temporary reset. ");
return 0;
}
final int duration = Integer.parseInt(getNextArgRequired());
mService.setTemporaryService(userId, serviceName, duration);
out.println("WearableSensingService temporarily set to " + serviceName
+ " for " + duration + "ms");
return 0;
}
private int getBoundPackageName() {
final PrintWriter resultPrinter = getOutPrintWriter();
final int userId = Integer.parseInt(getNextArgRequired());
final ComponentName componentName = mService.getComponentName(userId);
resultPrinter.println(componentName == null ? "" : componentName.getPackageName());
return 0;
}
}

View File

@@ -211,6 +211,7 @@ import com.android.server.usage.UsageStatsService;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.vibrator.VibratorManagerService;
import com.android.server.vr.VrManagerService;
import com.android.server.wearable.WearableSensingManagerService;
import com.android.server.webkit.WebViewUpdateService;
import com.android.server.wm.ActivityTaskManagerService;
import com.android.server.wm.WindowManagerGlobalLock;
@@ -1830,6 +1831,7 @@ public final class SystemServer implements Dumpable {
startSystemCaptionsManagerService(context, t);
startTextToSpeechManagerService(context, t);
startAmbientContextService(t);
startWearableSensingService(t);
// System Speech Recognition Service
t.traceBegin("StartSpeechRecognitionManagerService");
@@ -3170,6 +3172,12 @@ public final class SystemServer implements Dumpable {
t.traceEnd();
}
private void startWearableSensingService(@NonNull TimingsTraceAndSlog t) {
t.traceBegin("startWearableSensingService");
mSystemServiceManager.startService(WearableSensingManagerService.class);
t.traceEnd();
}
private static void startSystemUi(Context context, WindowManagerService windowManager) {
PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
Intent intent = new Intent();