Enable WearableSensingService.
This change includes: 1. Enabling WearableSensingManager to be retrievable. 2. Starts WearableSensingService from system server. 3. Introduces WearableSensingShellComamnd for testing. Bug: 249135378, 244181656 Test: Builds. Ignore-AOSP-First: to prevent new feature leak. Change-Id: I4ffaac37c0fe8874ae8b0ae6fec086e4cd27b2f1
This commit is contained in:
@@ -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;
|
||||
@@ -1540,6 +1542,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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user