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.testutils; 18 19 import android.app.sdksandbox.ISdkToServiceCallback; 20 import android.app.sdksandbox.LoadSdkException; 21 import android.app.sdksandbox.SandboxLatencyInfo; 22 import android.app.sdksandbox.SandboxedSdk; 23 import android.app.sdksandbox.SdkSandboxManager; 24 import android.app.sdksandbox.SharedPreferencesUpdate; 25 import android.content.pm.ApplicationInfo; 26 import android.os.Binder; 27 import android.os.Bundle; 28 import android.os.DeadObjectException; 29 import android.os.IBinder; 30 import android.os.RemoteException; 31 32 import androidx.annotation.Nullable; 33 34 import com.android.sdksandbox.IComputeSdkStorageCallback; 35 import com.android.sdksandbox.ILoadSdkInSandboxCallback; 36 import com.android.sdksandbox.IRequestSurfacePackageFromSdkCallback; 37 import com.android.sdksandbox.ISdkSandboxManagerToSdkSandboxCallback; 38 import com.android.sdksandbox.ISdkSandboxService; 39 import com.android.sdksandbox.IUnloadSdkInSandboxCallback; 40 41 import java.util.List; 42 import java.util.concurrent.CountDownLatch; 43 import java.util.concurrent.TimeUnit; 44 45 public class FakeSdkSandboxService extends ISdkSandboxService.Stub { 46 private final ISdkSandboxManagerToSdkSandboxCallback mManagerToSdkCallback; 47 private final CountDownLatch mLatch; 48 49 private long mTimeSystemServerCallFinished = -1; 50 private long mTimeSandboxReceivedCallFromSystemServer = -1; 51 private long mTimeSandboxCalledSdk = -1; 52 private long mTimeSdkCallCompleted = -1; 53 private long mTimeSandboxCalledSystemServer = -1; 54 55 private ILoadSdkInSandboxCallback mLoadSdkInSandboxCallback; 56 private IRequestSurfacePackageFromSdkCallback mRequestSurfacePackageFromSdkCallback = null; 57 private IUnloadSdkInSandboxCallback mUnloadSdkInSandboxCallback = null; 58 private IComputeSdkStorageCallback mComputeSdkStorageCallback = null; 59 private ApplicationInfo mCustomizedInfo; 60 61 private boolean mSurfacePackageRequested = false; 62 private int mInitializationCount = 0; 63 64 public boolean dieOnLoad = false; 65 66 public boolean failInitialization = false; 67 68 private SharedPreferencesUpdate mLastSyncUpdate = null; 69 70 FakeSdkSandboxService()71 public FakeSdkSandboxService() { 72 mManagerToSdkCallback = new FakeManagerToSdkCallback(); 73 mLatch = new CountDownLatch(5); 74 } 75 setTimeValues( long timeSystemServerCallFinished, long timeSandboxReceivedCallFromSystemServer, long timeSandboxCalledSdk, long timeSdkCallCompleted, long timeSandboxCalledSystemServer)76 public void setTimeValues( 77 long timeSystemServerCallFinished, 78 long timeSandboxReceivedCallFromSystemServer, 79 long timeSandboxCalledSdk, 80 long timeSdkCallCompleted, 81 long timeSandboxCalledSystemServer) { 82 mTimeSystemServerCallFinished = timeSystemServerCallFinished; 83 mTimeSandboxReceivedCallFromSystemServer = timeSandboxReceivedCallFromSystemServer; 84 mTimeSandboxCalledSdk = timeSandboxCalledSdk; 85 mTimeSdkCallCompleted = timeSdkCallCompleted; 86 mTimeSandboxCalledSystemServer = timeSandboxCalledSystemServer; 87 } 88 89 @Override initialize(ISdkToServiceCallback sdkToServiceCallback)90 public void initialize(ISdkToServiceCallback sdkToServiceCallback) 91 throws IllegalStateException { 92 if (failInitialization) { 93 throw new IllegalStateException(); 94 } 95 mInitializationCount++; 96 } 97 98 @Override loadSdk( String callingPackageName, ApplicationInfo info, String sdkName, String sdkProviderClass, ApplicationInfo customizedInfo, Bundle params, ILoadSdkInSandboxCallback callback, SandboxLatencyInfo sandboxLatencyInfo)99 public void loadSdk( 100 String callingPackageName, 101 ApplicationInfo info, 102 String sdkName, 103 String sdkProviderClass, 104 ApplicationInfo customizedInfo, 105 Bundle params, 106 ILoadSdkInSandboxCallback callback, 107 SandboxLatencyInfo sandboxLatencyInfo) 108 throws DeadObjectException { 109 if (dieOnLoad) { 110 throw new DeadObjectException(); 111 } 112 mLoadSdkInSandboxCallback = callback; 113 mCustomizedInfo = customizedInfo; 114 } 115 116 @Override unloadSdk( String sdkName, IUnloadSdkInSandboxCallback callback, SandboxLatencyInfo sandboxLatencyInfo)117 public void unloadSdk( 118 String sdkName, 119 IUnloadSdkInSandboxCallback callback, 120 SandboxLatencyInfo sandboxLatencyInfo) { 121 mUnloadSdkInSandboxCallback = callback; 122 } 123 124 @Override syncDataFromClient(SharedPreferencesUpdate update)125 public void syncDataFromClient(SharedPreferencesUpdate update) { 126 mLastSyncUpdate = update; 127 } 128 129 @Override computeSdkStorage( List<String> cePackagePaths, List<String> dePackagePaths, IComputeSdkStorageCallback callback)130 public void computeSdkStorage( 131 List<String> cePackagePaths, 132 List<String> dePackagePaths, 133 IComputeSdkStorageCallback callback) { 134 mLatch.countDown(); 135 mComputeSdkStorageCallback = callback; 136 } 137 138 @Nullable getLastSyncData()139 public Bundle getLastSyncData() { 140 return mLastSyncUpdate.getData(); 141 } 142 143 @Nullable getLastSyncUpdate()144 public SharedPreferencesUpdate getLastSyncUpdate() { 145 return mLastSyncUpdate; 146 } 147 148 @Override notifySdkSandboxClientImportanceChange(boolean isForeground)149 public void notifySdkSandboxClientImportanceChange(boolean isForeground) {} 150 getInitializationCount()151 public int getInitializationCount() { 152 return mInitializationCount; 153 } 154 sendLoadSdkSuccessful()155 public void sendLoadSdkSuccessful() throws RemoteException { 156 final SandboxLatencyInfo sandboxLatencyInfo = new SandboxLatencyInfo(); 157 sandboxLatencyInfo.setTimeSystemServerCallFinished(mTimeSystemServerCallFinished); 158 mLoadSdkInSandboxCallback.onLoadSdkSuccess( 159 new SandboxedSdk(new Binder()), mManagerToSdkCallback, sandboxLatencyInfo); 160 } 161 sendLoadSdkSuccessfulWithSandboxLatencies(SandboxLatencyInfo sandboxLatencyInfo)162 public void sendLoadSdkSuccessfulWithSandboxLatencies(SandboxLatencyInfo sandboxLatencyInfo) 163 throws RemoteException { 164 setSandboxLatencyTimestamps(sandboxLatencyInfo); 165 mLoadSdkInSandboxCallback.onLoadSdkSuccess( 166 new SandboxedSdk(new Binder()), mManagerToSdkCallback, sandboxLatencyInfo); 167 } 168 isSdkUnloaded()169 public boolean isSdkUnloaded() { 170 return mUnloadSdkInSandboxCallback != null; 171 } 172 sendStorageInfoToSystemServer()173 public void sendStorageInfoToSystemServer() throws Exception { 174 mLatch.await(5, TimeUnit.SECONDS); 175 mComputeSdkStorageCallback.onStorageInfoComputed(0, 0); 176 } 177 sendLoadSdkError()178 public void sendLoadSdkError() throws Exception { 179 Class<?> clz = Class.forName("android.app.sdksandbox.LoadSdkException"); 180 final SandboxLatencyInfo sandboxLatencyInfo = new SandboxLatencyInfo(); 181 sandboxLatencyInfo.setTimeSystemServerCallFinished(mTimeSystemServerCallFinished); 182 LoadSdkException exception = 183 (LoadSdkException) 184 clz.getConstructor(Integer.TYPE, String.class) 185 .newInstance( 186 SdkSandboxManager.LOAD_SDK_INTERNAL_ERROR, 187 "Internal error"); 188 mLoadSdkInSandboxCallback.onLoadSdkError(exception, sandboxLatencyInfo); 189 } 190 sendSurfacePackageReady(SandboxLatencyInfo sandboxLatencyInfo)191 public void sendSurfacePackageReady(SandboxLatencyInfo sandboxLatencyInfo) 192 throws RemoteException { 193 if (mSurfacePackageRequested) { 194 mRequestSurfacePackageFromSdkCallback.onSurfacePackageReady( 195 /*surfacePackage=*/ null, 196 /*surfacePackageId=*/ 1, 197 /*params=*/ new Bundle(), 198 sandboxLatencyInfo); 199 } 200 } 201 sendUnloadSdkSuccess(SandboxLatencyInfo sandboxLatencyInfo)202 public void sendUnloadSdkSuccess(SandboxLatencyInfo sandboxLatencyInfo) throws Exception { 203 setSandboxLatencyTimestamps(sandboxLatencyInfo); 204 mUnloadSdkInSandboxCallback.onUnloadSdk(sandboxLatencyInfo); 205 } 206 207 // TODO(b/242684679): Use iRequestSurfacePackageFromSdkCallback instead of fake callback sendSurfacePackageError( int errorCode, String errorMsg, FakeRequestSurfacePackageCallbackBinder callback)208 public void sendSurfacePackageError( 209 int errorCode, String errorMsg, FakeRequestSurfacePackageCallbackBinder callback) 210 throws RemoteException { 211 callback.onSurfacePackageError(errorCode, errorMsg, new SandboxLatencyInfo()); 212 } 213 getCustomizedInfo()214 public ApplicationInfo getCustomizedInfo() { 215 return mCustomizedInfo; 216 } 217 setSandboxLatencyTimestamps(SandboxLatencyInfo sandboxLatencyInfo)218 private void setSandboxLatencyTimestamps(SandboxLatencyInfo sandboxLatencyInfo) { 219 sandboxLatencyInfo.setTimeSystemServerCallFinished(mTimeSystemServerCallFinished); 220 sandboxLatencyInfo.setTimeSandboxReceivedCallFromSystemServer( 221 mTimeSandboxReceivedCallFromSystemServer); 222 sandboxLatencyInfo.setTimeSandboxCalledSdk(mTimeSandboxCalledSdk); 223 sandboxLatencyInfo.setTimeSdkCallCompleted(mTimeSdkCallCompleted); 224 sandboxLatencyInfo.setTimeSandboxCalledSystemServer(mTimeSandboxCalledSystemServer); 225 } 226 227 private class FakeManagerToSdkCallback extends ISdkSandboxManagerToSdkSandboxCallback.Stub { 228 @Override onSurfacePackageRequested( IBinder hostToken, int displayId, int width, int height, Bundle extraParams, SandboxLatencyInfo sandboxLatencyInfo, IRequestSurfacePackageFromSdkCallback iRequestSurfacePackageFromSdkCallback)229 public void onSurfacePackageRequested( 230 IBinder hostToken, 231 int displayId, 232 int width, 233 int height, 234 Bundle extraParams, 235 SandboxLatencyInfo sandboxLatencyInfo, 236 IRequestSurfacePackageFromSdkCallback iRequestSurfacePackageFromSdkCallback) { 237 mSurfacePackageRequested = true; 238 mRequestSurfacePackageFromSdkCallback = iRequestSurfacePackageFromSdkCallback; 239 } 240 } 241 } 242