blob: 49151c34136fc22b66ff588f004282289be60e55 [file]
/*
* 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.ondevicepersonalization.services;
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
import android.ondevicepersonalization.aidl.IExecuteCallback;
import android.ondevicepersonalization.aidl.IOnDevicePersonalizationManagingService;
import android.ondevicepersonalization.aidl.IRequestSurfacePackageCallback;
import android.os.Binder;
import android.os.IBinder;
import android.os.PersistableBundle;
import com.android.internal.annotations.VisibleForTesting;
import com.android.ondevicepersonalization.services.request.AppRequestFlow;
import com.android.ondevicepersonalization.services.request.RenderFlow;
import java.util.Objects;
/** Implementation of OnDevicePersonalizationManagingService */
public class OnDevicePersonalizationManagingServiceDelegate
extends IOnDevicePersonalizationManagingService.Stub {
@NonNull private final Context mContext;
@VisibleForTesting
static class Injector {
AppRequestFlow getAppRequestFlow(
String callingPackageName,
String servicePackageName,
PersistableBundle params,
IExecuteCallback callback,
Context context) {
return new AppRequestFlow(
callingPackageName, servicePackageName, params, callback, context);
}
RenderFlow getRenderFlow(
String slotResultToken,
IBinder hostToken,
int displayId,
int width,
int height,
IRequestSurfacePackageCallback callback,
Context context) {
return new RenderFlow(
slotResultToken, hostToken, displayId, width, height, callback, context);
}
}
@NonNull private final Injector mInjector;
public OnDevicePersonalizationManagingServiceDelegate(@NonNull Context context) {
this(context, new Injector());
}
@VisibleForTesting
public OnDevicePersonalizationManagingServiceDelegate(
@NonNull Context context,
@NonNull Injector injector) {
mContext = Objects.requireNonNull(context);
mInjector = Objects.requireNonNull(injector);
}
@Override
public String getVersion() {
return "1.0";
}
@Override
public void execute(
@NonNull String callingPackageName,
@NonNull String servicePackageName,
@NonNull PersistableBundle params,
@NonNull IExecuteCallback callback) {
Objects.requireNonNull(callingPackageName);
Objects.requireNonNull(servicePackageName);
Objects.requireNonNull(params);
Objects.requireNonNull(callback);
final int uid = Binder.getCallingUid();
enforceCallingPackageBelongsToUid(callingPackageName, uid);
AppRequestFlow flow = mInjector.getAppRequestFlow(
callingPackageName,
servicePackageName,
params,
callback,
mContext);
flow.run();
}
@Override
public void requestSurfacePackage(
@NonNull String slotResultToken,
@NonNull IBinder hostToken,
int displayId,
int width,
int height,
@NonNull IRequestSurfacePackageCallback callback) {
Objects.requireNonNull(slotResultToken);
Objects.requireNonNull(hostToken);
Objects.requireNonNull(callback);
if (width <= 0) {
throw new IllegalArgumentException("width must be > 0");
}
if (height <= 0) {
throw new IllegalArgumentException("height must be > 0");
}
if (displayId < 0) {
throw new IllegalArgumentException("displayId must be >= 0");
}
RenderFlow flow = mInjector.getRenderFlow(
slotResultToken,
hostToken,
displayId,
width,
height,
callback,
mContext);
flow.run();
}
private void enforceCallingPackageBelongsToUid(@NonNull String packageName, int uid) {
int packageUid;
PackageManager pm = mContext.getPackageManager();
try {
packageUid = pm.getPackageUid(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new SecurityException(packageName + " not found");
}
if (packageUid != uid) {
throw new SecurityException(packageName + " does not belong to uid " + uid);
}
//TODO(b/242792629): Handle requests from the SDK sandbox.
}
}