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 android.app.sdksandbox;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.sdksandbox.sdkprovider.SdkSandboxController;
22 import android.content.Context;
23 import android.os.Bundle;
24 import android.view.SurfaceControlViewHost.SurfacePackage;
25 import android.view.View;
26 
27 import java.util.Objects;
28 
29 /**
30  * Encapsulates API which SDK sandbox can use to interact with SDKs loaded into it.
31  *
32  * <p>SDK has to implement this abstract class to generate an entry point for SDK sandbox to be able
33  * to call it through.
34  */
35 public abstract class SandboxedSdkProvider {
36     private Context mContext;
37     private SdkSandboxController mSdkSandboxController;
38 
39     /**
40      * Sets the SDK {@link Context} which can then be received using {@link
41      * SandboxedSdkProvider#getContext()}. This is called before {@link
42      * SandboxedSdkProvider#onLoadSdk} is invoked. No operations requiring a {@link Context} should
43      * be performed before then, as {@link SandboxedSdkProvider#getContext} will return null until
44      * this method has been called.
45      *
46      * <p>Throws IllegalStateException if a base context has already been set.
47      *
48      * @param context The new base context.
49      */
attachContext(@onNull Context context)50     public final void attachContext(@NonNull Context context) {
51         if (mContext != null) {
52             throw new IllegalStateException("Context already set");
53         }
54         Objects.requireNonNull(context, "Context cannot be null");
55         mContext = context;
56     }
57 
58     /**
59      * Return the {@link Context} previously set through {@link SandboxedSdkProvider#attachContext}.
60      * This will return null if no context has been previously set.
61      */
62     @Nullable
getContext()63     public final Context getContext() {
64         return mContext;
65     }
66 
67     /**
68      * Does the work needed for the SDK to start handling requests.
69      *
70      * <p>This function is called by the SDK sandbox after it loads the SDK.
71      *
72      * <p>SDK should do any work to be ready to handle upcoming requests. It should not do any
73      * long-running tasks here, like I/O and network calls. Doing so can prevent the SDK from
74      * receiving requests from the client. Additionally, it should not do initialization that
75      * depends on other SDKs being loaded into the SDK sandbox.
76      *
77      * <p>The SDK should not do any operations requiring a {@link Context} object before this method
78      * has been called.
79      *
80      * @param params list of params passed from the client when it loads the SDK. This can be empty.
81      * @return Returns a {@link SandboxedSdk}, passed back to the client. The IBinder used to create
82      *     the {@link SandboxedSdk} object will be used by the client to call into the SDK.
83      */
onLoadSdk(@onNull Bundle params)84     public abstract @NonNull SandboxedSdk onLoadSdk(@NonNull Bundle params) throws LoadSdkException;
85     /**
86      * Does the work needed for the SDK to free its resources before being unloaded.
87      *
88      * <p>This function is called by the SDK sandbox manager before it unloads the SDK. The SDK
89      * should fail any invocations on the Binder previously returned to the client through {@link
90      * SandboxedSdk#getInterface}.
91      *
92      * <p>The SDK should not do any long-running tasks here, like I/O and network calls.
93      */
beforeUnloadSdk()94     public void beforeUnloadSdk() {}
95 
96     /**
97      * Requests a view to be remotely rendered to the client app process.
98      *
99      * <p>Returns {@link View} will be wrapped into {@link SurfacePackage}. the resulting {@link
100      * SurfacePackage} will be sent back to the client application.
101      *
102      * <p>The SDK should not do any long-running tasks here, like I/O and network calls. Doing so
103      * can prevent the SDK from receiving requests from the client.
104      *
105      * @param windowContext the {@link Context} of the display which meant to show the view
106      * @param params list of params passed from the client application requesting the view
107      * @param width The view returned will be laid as if in a window of this width, in pixels.
108      * @param height The view returned will be laid as if in a window of this height, in pixels.
109      * @return a {@link View} which SDK sandbox pass to the client application requesting the view
110      * @deprecated This method will no longer be supported as it is being used by {@link
111      *     SdkSandboxManager#requestSurfacePackage} which is getting deprecated.
112      */
113     @NonNull
114     @Deprecated
getView( @onNull Context windowContext, @NonNull Bundle params, int width, int height)115     public abstract View getView(
116             @NonNull Context windowContext, @NonNull Bundle params, int width, int height);
117 }
118