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.server.sdksandbox; 18 19 import static android.app.sdksandbox.SdkSandboxManager.REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED; 20 import static android.app.sdksandbox.SdkSandboxManager.SDK_SANDBOX_PROCESS_NOT_AVAILABLE; 21 22 23 import android.annotation.IntDef; 24 import android.annotation.Nullable; 25 import android.app.sdksandbox.ILoadSdkCallback; 26 import android.app.sdksandbox.IRequestSurfacePackageCallback; 27 import android.app.sdksandbox.IUnloadSdkCallback; 28 import android.app.sdksandbox.LoadSdkException; 29 import android.app.sdksandbox.LogUtil; 30 import android.app.sdksandbox.SandboxLatencyInfo; 31 import android.app.sdksandbox.SandboxedSdk; 32 import android.app.sdksandbox.SdkSandboxManager; 33 import android.content.Context; 34 import android.content.pm.ApplicationInfo; 35 import android.content.pm.PackageManager; 36 import android.content.pm.SharedLibraryInfo; 37 import android.os.Bundle; 38 import android.os.DeadObjectException; 39 import android.os.IBinder; 40 import android.os.RemoteException; 41 import android.util.ArraySet; 42 import android.util.Log; 43 import android.view.SurfaceControlViewHost; 44 45 import com.android.internal.annotations.GuardedBy; 46 import com.android.sdksandbox.ILoadSdkInSandboxCallback; 47 import com.android.sdksandbox.IRequestSurfacePackageFromSdkCallback; 48 import com.android.sdksandbox.ISdkSandboxManagerToSdkSandboxCallback; 49 import com.android.sdksandbox.ISdkSandboxService; 50 import com.android.sdksandbox.IUnloadSdkInSandboxCallback; 51 import com.android.server.sdksandbox.helpers.PackageManagerHelper; 52 53 import java.lang.annotation.Retention; 54 import java.lang.annotation.RetentionPolicy; 55 56 /** 57 * Represents the lifecycle of a single request to load an SDK for a specific app. 58 * 59 * <p>A new instance of this class must be created for every load request of an SDK. This class also 60 * maintains a link to the remote SDK loaded in the sandbox if any, and communicates with it. 61 */ 62 class LoadSdkSession { 63 64 private static final String TAG = "SdkSandboxManager"; 65 private static final String PROPERTY_SDK_PROVIDER_CLASS_NAME = 66 "android.sdksandbox.PROPERTY_SDK_PROVIDER_CLASS_NAME"; 67 68 /** @hide */ 69 @IntDef(value = {LOAD_PENDING, LOADED, LOAD_FAILED, UNLOADED}) 70 @Retention(RetentionPolicy.SOURCE) 71 public @interface LoadStatus {} 72 73 /** 74 * Represents the initial state of the SDK, when a request to load it has arrived but not yet 75 * been completed. 76 * 77 * <p>Once the state of an SDK transitions out of LOAD_PENDING, it cannot be reset to 78 * LOAD_PENDING as this state is the representation of a specific load request for an SDK. 79 * 80 * <ul> 81 * <li>LOAD_PENDING --> onLoadSdkSuccess() --> LOADED 82 * <li>LOAD_PENDING --> onLoadSdkError() --> LOAD_FAILED 83 * <li>LOAD_PENDING --> unload() --> IllegalArgumentException 84 * <li>LOAD_PENDING --> onSandboxDeath() --> LOAD_FAILED 85 * </ul> 86 */ 87 public static final int LOAD_PENDING = 1; 88 89 /** 90 * Represents the state when the SDK has been successfully loaded into the sandbox. 91 * 92 * <ul> 93 * <li>LOADED --> load() --> IllegalArgumentException 94 * <li>LOADED --> unload() --> UNLOADED 95 * <li>LOADED --> onSandboxDeath() --> UNLOADED 96 * </ul> 97 */ 98 public static final int LOADED = 2; 99 100 /** 101 * Represents the state when the SDK has failed to load into the sandbox. 102 * 103 * <p>The state can be LOAD_FAILED if the sandbox could not properly initialize the SDK, SDK is 104 * invalid, the sandbox died while in the middle of loading etc. If the SDK load failed, this 105 * same session cannot be used to load the SDK again. 106 * 107 * <ul> 108 * <li>LOAD_FAILED --> load() --> IllegalArgumentException 109 * <li>LOAD_FAILED --> unload() --> LOAD_FAILED 110 * <li>LOAD_FAILED --> onSandboxDeath() --> LOAD_FAILED 111 * </ul> 112 */ 113 public static final int LOAD_FAILED = 3; 114 115 /** 116 * Represents the state when the SDK has either been unloaded from the sandbox, or the sandbox 117 * has died. 118 * 119 * <ul> 120 * <li>UNLOADED --> load() --> IllegalArgumentException 121 * <li>UNLOADED --> unload() --> UNLOADED 122 * <li>UNLOADED --> onSandboxDeath() --> UNLOADED 123 * </ul> 124 */ 125 public static final int UNLOADED = 4; 126 127 private final Object mLock = new Object(); 128 129 private final Context mContext; 130 private final SdkSandboxManagerService mSdkSandboxManagerService; 131 private final SdkSandboxManagerService.Injector mInjector; 132 133 final String mSdkName; 134 final CallingInfo mCallingInfo; 135 136 // The params used to load this SDK. 137 private final Bundle mLoadParams; 138 // The callback used to load this SDK. 139 private final ILoadSdkCallback mLoadCallback; 140 141 final SdkProviderInfo mSdkProviderInfo; 142 143 /** 144 * The initial status is LOAD_PENDING. Once the loading is complete, the status is set to LOADED 145 * or LOAD_FAILED depending on the success of loading. If the SDK is unloaded at any point or 146 * the sandbox dies, the status is set to UNLOADED. 147 * 148 * <p>The status cannot be reset to LOAD_PENDING as this class is meant to represent a single 149 * load request. 150 */ 151 @GuardedBy("mLock") 152 @LoadStatus 153 private int mStatus = LOAD_PENDING; 154 155 // The sandbox in which this SDK is supposed to be loaded. 156 @GuardedBy("mLock") 157 private ISdkSandboxService mSandboxService = null; 158 159 // Used for communication with the remotely loaded SDK in the sandbox. 160 private final RemoteSdkLink mRemoteSdkLink; 161 162 // Maintain all surface package requests whose callbacks have not been invoked yet. 163 @GuardedBy("mLock") 164 private final ArraySet<IRequestSurfacePackageCallback> mPendingRequestSurfacePackageCallbacks = 165 new ArraySet<>(); 166 LoadSdkSession( Context context, SdkSandboxManagerService service, SdkSandboxManagerService.Injector injector, String sdkName, CallingInfo callingInfo, Bundle loadParams, ILoadSdkCallback loadCallback)167 LoadSdkSession( 168 Context context, 169 SdkSandboxManagerService service, 170 SdkSandboxManagerService.Injector injector, 171 String sdkName, 172 CallingInfo callingInfo, 173 Bundle loadParams, 174 ILoadSdkCallback loadCallback) 175 throws PackageManager.NameNotFoundException { 176 mContext = context; 177 mSdkSandboxManagerService = service; 178 mInjector = injector; 179 mSdkName = sdkName; 180 mCallingInfo = callingInfo; 181 mLoadParams = loadParams; 182 mLoadCallback = loadCallback; 183 184 mSdkProviderInfo = createSdkProviderInfo(); 185 mRemoteSdkLink = new RemoteSdkLink(); 186 } 187 188 @LoadStatus getStatus()189 int getStatus() { 190 synchronized (mLock) { 191 return mStatus; 192 } 193 } 194 195 @Nullable getSandboxedSdk()196 SandboxedSdk getSandboxedSdk() { 197 return mRemoteSdkLink.mSandboxedSdk; 198 } 199 200 // Asks the given sandbox service to load this SDK. load( ISdkSandboxService service, ApplicationInfo customizedInfo, SandboxLatencyInfo sandboxLatencyInfo)201 void load( 202 ISdkSandboxService service, 203 ApplicationInfo customizedInfo, 204 SandboxLatencyInfo sandboxLatencyInfo) { 205 // TODO(b/258679084): If a second load request comes here, while the first is pending, it 206 // will go through. SdkSandboxManagerService already has a check for this, but we should 207 // have it here as well. 208 synchronized (mLock) { 209 if (getStatus() != LOAD_PENDING) { 210 // If the status is not the initial pending load, that means that this load request 211 // had already been performed before and completed (either successfully or 212 // unsuccessfully). Therefore, do not invoke any callback here. 213 throw new IllegalArgumentException("Invalid request to load SDK " + mSdkName); 214 } 215 mSandboxService = service; 216 } 217 218 if (service == null) { 219 sandboxLatencyInfo.setSandboxStatus( 220 SandboxLatencyInfo.SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_APP_TO_SANDBOX); 221 sandboxLatencyInfo.setTimeSystemServerCallFinished(mInjector.elapsedRealtime()); 222 handleLoadFailure( 223 new LoadSdkException( 224 SDK_SANDBOX_PROCESS_NOT_AVAILABLE, "Sandbox is not available"), 225 sandboxLatencyInfo); 226 return; 227 } 228 229 sandboxLatencyInfo.setTimeSystemServerCallFinished(mInjector.elapsedRealtime()); 230 try { 231 service.loadSdk( 232 mCallingInfo.getPackageName(), 233 mSdkProviderInfo.getApplicationInfo(), 234 mSdkProviderInfo.getSdkInfo().getName(), 235 mSdkProviderInfo.getSdkProviderClassName(), 236 customizedInfo, 237 mLoadParams, 238 mRemoteSdkLink, 239 sandboxLatencyInfo); 240 } catch (DeadObjectException e) { 241 sandboxLatencyInfo.setSandboxStatus( 242 SandboxLatencyInfo.SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_APP_TO_SANDBOX); 243 handleLoadFailure( 244 new LoadSdkException( 245 SDK_SANDBOX_PROCESS_NOT_AVAILABLE, 246 "Failed to load SDK as sandbox is dead"), 247 sandboxLatencyInfo); 248 } catch (RemoteException e) { 249 String errorMsg = "Failed to load sdk"; 250 sandboxLatencyInfo.setSandboxStatus( 251 SandboxLatencyInfo.SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_APP_TO_SANDBOX); 252 handleLoadFailure( 253 new LoadSdkException(SdkSandboxManager.LOAD_SDK_INTERNAL_ERROR, errorMsg), 254 sandboxLatencyInfo); 255 } 256 } 257 handleLoadSuccess(SandboxLatencyInfo sandboxLatencyInfo)258 void handleLoadSuccess(SandboxLatencyInfo sandboxLatencyInfo) { 259 sandboxLatencyInfo.setTimeSystemServerCalledApp(mInjector.elapsedRealtime()); 260 261 synchronized (mLock) { 262 if (getStatus() == LOAD_PENDING) { 263 mStatus = LOADED; 264 } else { 265 // If the SDK is not pending a load, something has happened to it - for example, the 266 // sandbox might have died and the status is now LOAD_FAILED. Either way, since it 267 // is not waiting to be loaded, the LoadSdkCallback would have already been invoked. 268 // Just log and return. 269 LogUtil.d( 270 TAG, 271 "Could not successfully load " 272 + mSdkName 273 + " as its status is " 274 + getStatus()); 275 return; 276 } 277 } 278 try { 279 mLoadCallback.onLoadSdkSuccess(getSandboxedSdk(), sandboxLatencyInfo); 280 } catch (RemoteException e) { 281 Log.w(TAG, "Failed to send onLoadSdkSuccess", e); 282 } 283 } 284 handleLoadFailure(LoadSdkException exception, SandboxLatencyInfo sandboxLatencyInfo)285 void handleLoadFailure(LoadSdkException exception, SandboxLatencyInfo sandboxLatencyInfo) { 286 sandboxLatencyInfo.setTimeSystemServerCalledApp(mInjector.elapsedRealtime()); 287 288 synchronized (mLock) { 289 if (getStatus() == LOAD_PENDING) { 290 mStatus = LOAD_FAILED; 291 } else { 292 // If the SDK is not pending a load, something has happened to it - for example, the 293 // sandbox might have died and the status is now LOAD_FAILED. Either way, since it 294 // is not waiting to be loaded, the LoadSdkCallback would have already been invoked. 295 // Just log and return. 296 LogUtil.d( 297 TAG, 298 "Could not complete load failure for " 299 + mSdkName 300 + " as its status is " 301 + getStatus()); 302 return; 303 } 304 } 305 try { 306 mLoadCallback.onLoadSdkFailure(exception, sandboxLatencyInfo); 307 } catch (RemoteException e) { 308 Log.w(TAG, "Failed to send onLoadSdkFailure", e); 309 } 310 } 311 unload(SandboxLatencyInfo sandboxLatencyInfo, IUnloadSdkCallback callback)312 void unload(SandboxLatencyInfo sandboxLatencyInfo, IUnloadSdkCallback callback) { 313 // TODO(b/312444990): log latency in cases the method call fails. 314 sandboxLatencyInfo.setTimeSystemServerCallFinished(mInjector.elapsedRealtime()); 315 IUnloadSdkInSandboxCallback unloadInSandboxCallback = 316 new IUnloadSdkInSandboxCallback.Stub() { 317 @Override 318 public void onUnloadSdk(SandboxLatencyInfo sandboxLatencyInfo) { 319 sandboxLatencyInfo.setTimeSystemServerReceivedCallFromSandbox( 320 mInjector.elapsedRealtime()); 321 try { 322 callback.onUnloadSdk(sandboxLatencyInfo); 323 } catch (RemoteException e) { 324 Log.e(TAG, "Could not send onUnloadSdk"); 325 } 326 } 327 }; 328 329 ISdkSandboxService service = null; 330 synchronized (mLock) { 331 switch (getStatus()) { 332 case LOAD_PENDING: 333 // If load is pending, unloading should fail. 334 throw new IllegalArgumentException( 335 "SDK " 336 + mSdkName 337 + " is currently being loaded for " 338 + mCallingInfo 339 + " - wait till onLoadSdkSuccess() to unload"); 340 case LOADED: 341 // Set status as unloaded right away, so that it is treated as unloaded even if 342 // the actual unloading hasn't completed. 343 mStatus = UNLOADED; 344 break; 345 default: 346 // Unloading an SDK that is not loaded is a no-op, return. Don't throw any 347 // exception here since the sandbox can die at any time and the SDK becomes 348 // unloaded. 349 Log.i(TAG, "SDK " + mSdkName + " is not loaded for " + mCallingInfo); 350 return; 351 } 352 353 service = mSandboxService; 354 } 355 356 if (service == null) { 357 // Sandbox could have died, just ignore. 358 Log.i(TAG, "Cannot unload SDK " + mSdkName + " - could not find sandbox service"); 359 return; 360 } 361 362 try { 363 service.unloadSdk(mSdkName, unloadInSandboxCallback, sandboxLatencyInfo); 364 } catch (DeadObjectException e) { 365 Log.i( 366 TAG, 367 "Sdk sandbox for " + mCallingInfo + " is dead, cannot unload SDK " + mSdkName); 368 } catch (RemoteException e) { 369 Log.w(TAG, "Failed to unload SDK: ", e); 370 } 371 } 372 requestSurfacePackage( IBinder hostToken, int displayId, int width, int height, SandboxLatencyInfo sandboxLatencyInfo, Bundle params, IRequestSurfacePackageCallback callback)373 void requestSurfacePackage( 374 IBinder hostToken, 375 int displayId, 376 int width, 377 int height, 378 SandboxLatencyInfo sandboxLatencyInfo, 379 Bundle params, 380 IRequestSurfacePackageCallback callback) { 381 synchronized (mLock) { 382 mPendingRequestSurfacePackageCallbacks.add(callback); 383 384 if (getStatus() != LOADED) { 385 sandboxLatencyInfo.setTimeSystemServerCallFinished(mInjector.elapsedRealtime()); 386 sandboxLatencyInfo.setSandboxStatus( 387 SandboxLatencyInfo.SANDBOX_STATUS_FAILED_AT_SYSTEM_SERVER_APP_TO_SANDBOX); 388 handleSurfacePackageError( 389 REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED, 390 "SDK " + mSdkName + " is not loaded", 391 sandboxLatencyInfo, 392 callback); 393 return; 394 } 395 } 396 mRemoteSdkLink.requestSurfacePackage( 397 hostToken, displayId, width, height, sandboxLatencyInfo, params, callback); 398 } 399 handleSurfacePackageReady( SurfaceControlViewHost.SurfacePackage surfacePackage, int surfacePackageId, Bundle params, SandboxLatencyInfo sandboxLatencyInfo, IRequestSurfacePackageCallback callback)400 void handleSurfacePackageReady( 401 SurfaceControlViewHost.SurfacePackage surfacePackage, 402 int surfacePackageId, 403 Bundle params, 404 SandboxLatencyInfo sandboxLatencyInfo, 405 IRequestSurfacePackageCallback callback) { 406 synchronized (mLock) { 407 mPendingRequestSurfacePackageCallbacks.remove(callback); 408 } 409 sandboxLatencyInfo.setTimeSystemServerCalledApp(mInjector.elapsedRealtime()); 410 try { 411 callback.onSurfacePackageReady( 412 surfacePackage, surfacePackageId, params, sandboxLatencyInfo); 413 } catch (RemoteException e) { 414 Log.w(TAG, "Failed to send onSurfacePackageReady callback", e); 415 } 416 } 417 handleSurfacePackageError( int errorCode, String errorMsg, SandboxLatencyInfo sandboxLatencyInfo, IRequestSurfacePackageCallback callback)418 void handleSurfacePackageError( 419 int errorCode, 420 String errorMsg, 421 SandboxLatencyInfo sandboxLatencyInfo, 422 IRequestSurfacePackageCallback callback) { 423 synchronized (mLock) { 424 mPendingRequestSurfacePackageCallbacks.remove(callback); 425 } 426 sandboxLatencyInfo.setTimeSystemServerCalledApp(mInjector.elapsedRealtime()); 427 try { 428 callback.onSurfacePackageError(errorCode, errorMsg, sandboxLatencyInfo); 429 } catch (RemoteException e) { 430 Log.w(TAG, "Failed to send onSurfacePackageError", e); 431 } 432 } 433 onSandboxDeath()434 void onSandboxDeath() { 435 synchronized (mLock) { 436 mSandboxService = null; 437 438 // If load status was pending, then the callback need to be notified. 439 if (getStatus() == LOAD_PENDING) { 440 handleLoadFailure( 441 new LoadSdkException( 442 SDK_SANDBOX_PROCESS_NOT_AVAILABLE, 443 "Could not load SDK, sandbox has died"), 444 new SandboxLatencyInfo()); 445 } 446 447 // Clear all pending request surface package callbacks. 448 notifyPendingRequestSurfacePackageCallbacksLocked(); 449 450 // Set status to unloaded on sandbox death. 451 if (getStatus() == LOADED) { 452 mStatus = UNLOADED; 453 } 454 } 455 } 456 457 @GuardedBy("mLock") notifyPendingRequestSurfacePackageCallbacksLocked()458 private void notifyPendingRequestSurfacePackageCallbacksLocked() { 459 for (int i = 0; i < mPendingRequestSurfacePackageCallbacks.size(); i++) { 460 IRequestSurfacePackageCallback callback = 461 mPendingRequestSurfacePackageCallbacks.valueAt(i); 462 handleSurfacePackageError( 463 REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED, 464 "Sandbox died - could not request surface package", 465 new SandboxLatencyInfo(), 466 callback); 467 } 468 mPendingRequestSurfacePackageCallbacks.clear(); 469 } 470 471 /** 472 * A callback object to establish a link between the manager service and the remote SDK being 473 * loaded in SdkSandbox. 474 * 475 * <p>Overview of communication: 476 * 477 * <ol> 478 * <li>RemoteSdk to ManagerService: {@link RemoteSdkLink} extends {@link 479 * ILoadSdkInSandboxCallback} interface. We pass on this object to {@link 480 * ISdkSandboxService} so that remote SDK can call back into ManagerService. 481 * <li>ManagerService to RemoteSdk: When the SDK is loaded for the first time and remote SDK 482 * calls back with successful result, it also sends reference to {@link 483 * ISdkSandboxManagerToSdkSandboxCallback} callback object. ManagerService uses this to 484 * callback into the remote SDK. 485 * </ol> 486 * 487 * <p>We maintain a link for each unique {app, remoteSdk} pair, which is identified with {@code 488 * sdkName}. 489 */ 490 private class RemoteSdkLink extends ILoadSdkInSandboxCallback.Stub { 491 @Nullable private volatile SandboxedSdk mSandboxedSdk; 492 493 @GuardedBy("this") 494 @Nullable 495 private ISdkSandboxManagerToSdkSandboxCallback mManagerToSdkCallback; 496 497 @Override onLoadSdkSuccess( SandboxedSdk sandboxedSdk, ISdkSandboxManagerToSdkSandboxCallback callback, SandboxLatencyInfo sandboxLatencyInfo)498 public void onLoadSdkSuccess( 499 SandboxedSdk sandboxedSdk, 500 ISdkSandboxManagerToSdkSandboxCallback callback, 501 SandboxLatencyInfo sandboxLatencyInfo) { 502 sandboxLatencyInfo.setTimeSystemServerReceivedCallFromSandbox( 503 mInjector.elapsedRealtime()); 504 505 synchronized (this) { 506 // Keep reference to callback so that manager service can 507 // callback to remote SDK loaded. 508 mManagerToSdkCallback = callback; 509 510 // Attach the SharedLibraryInfo for the loaded SDK to the SandboxedSdk. 511 sandboxedSdk.attachSharedLibraryInfo(mSdkProviderInfo.getSdkInfo()); 512 513 // Keep reference to SandboxedSdk so that manager service can 514 // keep log of all loaded SDKs and their binders for communication. 515 mSandboxedSdk = sandboxedSdk; 516 } 517 518 handleLoadSuccess(sandboxLatencyInfo); 519 } 520 521 @Override onLoadSdkError( LoadSdkException exception, SandboxLatencyInfo sandboxLatencyInfo)522 public void onLoadSdkError( 523 LoadSdkException exception, SandboxLatencyInfo sandboxLatencyInfo) { 524 sandboxLatencyInfo.setTimeSystemServerReceivedCallFromSandbox( 525 mInjector.elapsedRealtime()); 526 527 if (exception.getLoadSdkErrorCode() 528 == ILoadSdkInSandboxCallback.LOAD_SDK_INSTANTIATION_ERROR) { 529 mSdkSandboxManagerService.handleFailedSandboxInitialization(mCallingInfo); 530 } 531 handleLoadFailure( 532 updateLoadSdkErrorCode(exception), 533 sandboxLatencyInfo); 534 } 535 updateLoadSdkErrorCode(LoadSdkException exception)536 private LoadSdkException updateLoadSdkErrorCode(LoadSdkException exception) { 537 @SdkSandboxManager.LoadSdkErrorCode 538 int newErrorCode = toSdkSandboxManagerLoadSdkErrorCode(exception.getLoadSdkErrorCode()); 539 return new LoadSdkException( 540 newErrorCode, 541 exception.getMessage(), 542 exception.getCause(), 543 exception.getExtraInformation()); 544 } 545 546 @SdkSandboxManager.LoadSdkErrorCode toSdkSandboxManagerLoadSdkErrorCode(int sdkSandboxErrorCode)547 private int toSdkSandboxManagerLoadSdkErrorCode(int sdkSandboxErrorCode) { 548 switch (sdkSandboxErrorCode) { 549 case ILoadSdkInSandboxCallback.LOAD_SDK_ALREADY_LOADED: 550 return SdkSandboxManager.LOAD_SDK_ALREADY_LOADED; 551 case ILoadSdkInSandboxCallback.LOAD_SDK_NOT_FOUND: 552 return SdkSandboxManager.LOAD_SDK_NOT_FOUND; 553 case ILoadSdkInSandboxCallback.LOAD_SDK_PROVIDER_INIT_ERROR: 554 case ILoadSdkInSandboxCallback.LOAD_SDK_INSTANTIATION_ERROR: 555 case ILoadSdkInSandboxCallback.LOAD_SDK_INTERNAL_ERROR: 556 return SdkSandboxManager.LOAD_SDK_INTERNAL_ERROR; 557 case SdkSandboxManager.LOAD_SDK_SDK_DEFINED_ERROR: 558 return sdkSandboxErrorCode; 559 default: 560 Log.e( 561 TAG, 562 "Error code " 563 + sdkSandboxErrorCode 564 + " has no mapping to the SdkSandboxManager error codes"); 565 return SdkSandboxManager.LOAD_SDK_INTERNAL_ERROR; 566 } 567 } 568 requestSurfacePackage( IBinder hostToken, int displayId, int width, int height, SandboxLatencyInfo sandboxLatencyInfo, Bundle params, IRequestSurfacePackageCallback callback)569 public void requestSurfacePackage( 570 IBinder hostToken, 571 int displayId, 572 int width, 573 int height, 574 SandboxLatencyInfo sandboxLatencyInfo, 575 Bundle params, 576 IRequestSurfacePackageCallback callback) { 577 sandboxLatencyInfo.setTimeSystemServerCallFinished(mInjector.elapsedRealtime()); 578 try { 579 synchronized (this) { 580 mManagerToSdkCallback.onSurfacePackageRequested( 581 hostToken, 582 displayId, 583 width, 584 height, 585 params, 586 sandboxLatencyInfo, 587 new IRequestSurfacePackageFromSdkCallback.Stub() { 588 @Override 589 public void onSurfacePackageReady( 590 SurfaceControlViewHost.SurfacePackage surfacePackage, 591 int surfacePackageId, 592 Bundle params, 593 SandboxLatencyInfo sandboxLatencyInfo) { 594 sandboxLatencyInfo.setTimeSystemServerReceivedCallFromSandbox( 595 mInjector.elapsedRealtime()); 596 597 LogUtil.d(TAG, "onSurfacePackageReady received"); 598 599 handleSurfacePackageReady( 600 surfacePackage, 601 surfacePackageId, 602 params, 603 sandboxLatencyInfo, 604 callback); 605 } 606 607 @Override 608 public void onSurfacePackageError( 609 int errorCode, 610 String errorMsg, 611 SandboxLatencyInfo sandboxLatencyInfo) { 612 sandboxLatencyInfo.setTimeSystemServerReceivedCallFromSandbox( 613 mInjector.elapsedRealtime()); 614 615 int sdkSandboxManagerErrorCode = 616 toSdkSandboxManagerRequestSurfacePackageErrorCode( 617 errorCode); 618 619 handleSurfacePackageError( 620 sdkSandboxManagerErrorCode, 621 errorMsg, 622 sandboxLatencyInfo, 623 callback); 624 } 625 }); 626 } 627 } catch (DeadObjectException e) { 628 LogUtil.d( 629 TAG, 630 mCallingInfo 631 + " requested surface package from SDK " 632 + mSdkName 633 + " but sandbox is not alive"); 634 handleSurfacePackageError( 635 REQUEST_SURFACE_PACKAGE_SDK_NOT_LOADED, 636 "SDK " + mSdkName + " is not loaded", 637 sandboxLatencyInfo, 638 callback); 639 } catch (RemoteException e) { 640 String errorMsg = "Failed to requestSurfacePackage"; 641 Log.w(TAG, errorMsg, e); 642 handleSurfacePackageError( 643 SdkSandboxManager.REQUEST_SURFACE_PACKAGE_INTERNAL_ERROR, 644 errorMsg + ": " + e, 645 sandboxLatencyInfo, 646 callback); 647 } 648 } 649 650 @SdkSandboxManager.RequestSurfacePackageErrorCode toSdkSandboxManagerRequestSurfacePackageErrorCode(int sdkSandboxErrorCode)651 private int toSdkSandboxManagerRequestSurfacePackageErrorCode(int sdkSandboxErrorCode) { 652 if (sdkSandboxErrorCode 653 == IRequestSurfacePackageFromSdkCallback.SURFACE_PACKAGE_INTERNAL_ERROR) { 654 return SdkSandboxManager.REQUEST_SURFACE_PACKAGE_INTERNAL_ERROR; 655 } 656 Log.e( 657 TAG, 658 "Error code" 659 + sdkSandboxErrorCode 660 + "has no mapping to the SdkSandboxManager error codes"); 661 return SdkSandboxManager.REQUEST_SURFACE_PACKAGE_INTERNAL_ERROR; 662 } 663 } 664 createSdkProviderInfo()665 private SdkProviderInfo createSdkProviderInfo() throws PackageManager.NameNotFoundException { 666 PackageManagerHelper packageManagerHelper = 667 new PackageManagerHelper(mContext, mCallingInfo.getUid()); 668 SharedLibraryInfo sharedLibrary = 669 packageManagerHelper.getSdkSharedLibraryInfoForSdk( 670 mCallingInfo.getPackageName(), mSdkName); 671 672 String sdkProviderClassName; 673 try { 674 sdkProviderClassName = 675 packageManagerHelper 676 .getProperty( 677 PROPERTY_SDK_PROVIDER_CLASS_NAME, 678 sharedLibrary.getDeclaringPackage().getPackageName()) 679 .getString(); 680 } catch (PackageManager.NameNotFoundException e) { 681 throw new PackageManager.NameNotFoundException( 682 PROPERTY_SDK_PROVIDER_CLASS_NAME + " property"); 683 } 684 685 ApplicationInfo applicationInfo = 686 packageManagerHelper.getApplicationInfoForSharedLibrary( 687 sharedLibrary, 688 PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES 689 | PackageManager.MATCH_ANY_USER); 690 691 return new SdkProviderInfo(applicationInfo, sharedLibrary, sdkProviderClassName); 692 } 693 getApplicationInfo()694 ApplicationInfo getApplicationInfo() { 695 return mSdkProviderInfo.getApplicationInfo(); 696 } 697 698 /** Class which retrieves and stores the sdkName, sdkProviderClassName, and ApplicationInfo */ 699 static class SdkProviderInfo { 700 701 private final ApplicationInfo mApplicationInfo; 702 private final SharedLibraryInfo mSdkInfo; 703 private final String mSdkProviderClassName; 704 SdkProviderInfo( ApplicationInfo applicationInfo, SharedLibraryInfo sdkInfo, String sdkProviderClassName)705 private SdkProviderInfo( 706 ApplicationInfo applicationInfo, 707 SharedLibraryInfo sdkInfo, 708 String sdkProviderClassName) { 709 mApplicationInfo = applicationInfo; 710 mSdkInfo = sdkInfo; 711 mSdkProviderClassName = sdkProviderClassName; 712 } 713 getSdkInfo()714 public SharedLibraryInfo getSdkInfo() { 715 return mSdkInfo; 716 } 717 getSdkProviderClassName()718 public String getSdkProviderClassName() { 719 return mSdkProviderClassName; 720 } 721 getApplicationInfo()722 public ApplicationInfo getApplicationInfo() { 723 return mApplicationInfo; 724 } 725 } 726 } 727