• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ondevicepersonalization.services;
18 
19 import android.annotation.NonNull;
20 import android.content.Context;
21 import android.content.pm.PackageManager;
22 import android.ondevicepersonalization.aidl.IExecuteCallback;
23 import android.ondevicepersonalization.aidl.IOnDevicePersonalizationManagingService;
24 import android.ondevicepersonalization.aidl.IRequestSurfacePackageCallback;
25 import android.os.Binder;
26 import android.os.IBinder;
27 import android.os.PersistableBundle;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 import com.android.ondevicepersonalization.services.request.AppRequestFlow;
31 import com.android.ondevicepersonalization.services.request.RenderFlow;
32 
33 import java.util.Objects;
34 
35 /** Implementation of OnDevicePersonalizationManagingService */
36 public class OnDevicePersonalizationManagingServiceDelegate
37         extends IOnDevicePersonalizationManagingService.Stub {
38     @NonNull private final Context mContext;
39 
40     @VisibleForTesting
41     static class Injector {
getAppRequestFlow( String callingPackageName, String servicePackageName, PersistableBundle params, IExecuteCallback callback, Context context)42         AppRequestFlow getAppRequestFlow(
43                 String callingPackageName,
44                 String servicePackageName,
45                 PersistableBundle params,
46                 IExecuteCallback callback,
47                 Context context) {
48             return new AppRequestFlow(
49                     callingPackageName, servicePackageName, params, callback, context);
50         }
51 
getRenderFlow( String slotResultToken, IBinder hostToken, int displayId, int width, int height, IRequestSurfacePackageCallback callback, Context context)52         RenderFlow getRenderFlow(
53                 String slotResultToken,
54                 IBinder hostToken,
55                 int displayId,
56                 int width,
57                 int height,
58                 IRequestSurfacePackageCallback callback,
59                 Context context) {
60             return new RenderFlow(
61                     slotResultToken, hostToken, displayId, width, height, callback, context);
62         }
63     }
64 
65     @NonNull private final Injector mInjector;
66 
OnDevicePersonalizationManagingServiceDelegate(@onNull Context context)67     public OnDevicePersonalizationManagingServiceDelegate(@NonNull Context context) {
68         this(context, new Injector());
69     }
70 
71     @VisibleForTesting
OnDevicePersonalizationManagingServiceDelegate( @onNull Context context, @NonNull Injector injector)72     public OnDevicePersonalizationManagingServiceDelegate(
73             @NonNull Context context,
74             @NonNull Injector injector) {
75         mContext = Objects.requireNonNull(context);
76         mInjector = Objects.requireNonNull(injector);
77     }
78 
79     @Override
getVersion()80     public String getVersion() {
81         return "1.0";
82     }
83 
84     @Override
execute( @onNull String callingPackageName, @NonNull String servicePackageName, @NonNull PersistableBundle params, @NonNull IExecuteCallback callback)85     public void execute(
86             @NonNull String callingPackageName,
87             @NonNull String servicePackageName,
88             @NonNull PersistableBundle params,
89             @NonNull IExecuteCallback callback) {
90         Objects.requireNonNull(callingPackageName);
91         Objects.requireNonNull(servicePackageName);
92         Objects.requireNonNull(params);
93         Objects.requireNonNull(callback);
94 
95         final int uid = Binder.getCallingUid();
96         enforceCallingPackageBelongsToUid(callingPackageName, uid);
97 
98         AppRequestFlow flow = mInjector.getAppRequestFlow(
99                 callingPackageName,
100                 servicePackageName,
101                 params,
102                 callback,
103                 mContext);
104         flow.run();
105     }
106 
107     @Override
requestSurfacePackage( @onNull String slotResultToken, @NonNull IBinder hostToken, int displayId, int width, int height, @NonNull IRequestSurfacePackageCallback callback)108     public void requestSurfacePackage(
109             @NonNull String slotResultToken,
110             @NonNull IBinder hostToken,
111             int displayId,
112             int width,
113             int height,
114             @NonNull IRequestSurfacePackageCallback callback) {
115         Objects.requireNonNull(slotResultToken);
116         Objects.requireNonNull(hostToken);
117         Objects.requireNonNull(callback);
118         if (width <= 0) {
119             throw new IllegalArgumentException("width must be > 0");
120         }
121 
122         if (height <= 0) {
123             throw new IllegalArgumentException("height must be > 0");
124         }
125 
126         if (displayId < 0) {
127             throw new IllegalArgumentException("displayId must be >= 0");
128         }
129 
130         RenderFlow flow = mInjector.getRenderFlow(
131                 slotResultToken,
132                 hostToken,
133                 displayId,
134                 width,
135                 height,
136                 callback,
137                 mContext);
138         flow.run();
139     }
140 
enforceCallingPackageBelongsToUid(@onNull String packageName, int uid)141     private void enforceCallingPackageBelongsToUid(@NonNull String packageName, int uid) {
142         int packageUid;
143         PackageManager pm = mContext.getPackageManager();
144         try {
145             packageUid = pm.getPackageUid(packageName, 0);
146         } catch (PackageManager.NameNotFoundException e) {
147             throw new SecurityException(packageName + " not found");
148         }
149         if (packageUid != uid) {
150             throw new SecurityException(packageName + " does not belong to uid " + uid);
151         }
152         //TODO(b/242792629): Handle requests from the SDK sandbox.
153     }
154 }
155