1 /* 2 * Copyright (C) 2023 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.testutils; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.sdksandbox.testutils.FakeSdkSandboxService; 22 import android.content.ComponentName; 23 import android.content.ServiceConnection; 24 import android.content.pm.PackageManager; 25 import android.util.ArrayMap; 26 27 import com.android.sdksandbox.ISdkSandboxService; 28 import com.android.server.sdksandbox.CallingInfo; 29 import com.android.server.sdksandbox.SdkSandboxServiceProvider; 30 31 import org.mockito.Mockito; 32 33 import java.io.PrintWriter; 34 35 /** Fake service provider that returns local instance of {@link SdkSandboxServiceProvider} */ 36 public class FakeSdkSandboxProvider implements SdkSandboxServiceProvider { 37 private FakeSdkSandboxService mSdkSandboxService; 38 private final ArrayMap<CallingInfo, ISdkSandboxService> mService = new ArrayMap<>(); 39 private static final String TEST_PACKAGE = "com.android.server.sdksandbox.tests"; 40 41 public static final String FAKE_DUMP_OUTPUT = "FakeDump"; 42 43 // When set to true, this will fail the bindService call 44 private boolean mFailBinding = false; 45 46 private ServiceConnection mServiceConnection = null; 47 FakeSdkSandboxProvider(FakeSdkSandboxService service)48 public FakeSdkSandboxProvider(FakeSdkSandboxService service) { 49 mSdkSandboxService = service; 50 } 51 52 /** Disable the binding */ disableBinding()53 public void disableBinding() { 54 mFailBinding = true; 55 } 56 57 /** Restart the sandbox process */ restartSandbox()58 public FakeSdkSandboxService restartSandbox() { 59 mServiceConnection.onServiceDisconnected(null); 60 61 // Create a new sandbox service. 62 mSdkSandboxService = Mockito.spy(FakeSdkSandboxService.class); 63 64 // Call onServiceConnected() again with the new fake sandbox service. 65 mServiceConnection.onServiceConnected(null, mSdkSandboxService.asBinder()); 66 return mSdkSandboxService; 67 } 68 69 @Override bindService(CallingInfo callingInfo, ServiceConnection serviceConnection)70 public void bindService(CallingInfo callingInfo, ServiceConnection serviceConnection) { 71 if (mFailBinding) { 72 serviceConnection.onNullBinding(new ComponentName("random", "component")); 73 return; 74 } 75 76 if (mService.containsKey(callingInfo)) { 77 return; 78 } 79 mService.put(callingInfo, mSdkSandboxService); 80 serviceConnection.onServiceConnected(null, mSdkSandboxService.asBinder()); 81 mServiceConnection = serviceConnection; 82 } 83 84 @Override unbindService(CallingInfo callingInfo)85 public void unbindService(CallingInfo callingInfo) { 86 mService.remove(callingInfo); 87 } 88 89 @Override stopSandboxService(CallingInfo callingInfo)90 public void stopSandboxService(CallingInfo callingInfo) { 91 mService.remove(callingInfo); 92 } 93 94 @Nullable 95 @Override getSdkSandboxServiceForApp(CallingInfo callingInfo)96 public ISdkSandboxService getSdkSandboxServiceForApp(CallingInfo callingInfo) { 97 return mService.get(callingInfo); 98 } 99 100 @Override onServiceConnected(CallingInfo callingInfo, @NonNull ISdkSandboxService service)101 public void onServiceConnected(CallingInfo callingInfo, @NonNull ISdkSandboxService service) { 102 mService.put(callingInfo, service); 103 } 104 105 @Override onServiceDisconnected(CallingInfo callingInfo)106 public void onServiceDisconnected(CallingInfo callingInfo) { 107 mService.put(callingInfo, null); 108 } 109 110 @Override onAppDeath(CallingInfo callingInfo)111 public void onAppDeath(CallingInfo callingInfo) {} 112 113 @Override onSandboxDeath(CallingInfo callingInfo)114 public void onSandboxDeath(CallingInfo callingInfo) {} 115 116 @Override isSandboxBoundForApp(CallingInfo callingInfo)117 public boolean isSandboxBoundForApp(CallingInfo callingInfo) { 118 return false; 119 } 120 121 @Override getSandboxStatusForApp(CallingInfo callingInfo)122 public int getSandboxStatusForApp(CallingInfo callingInfo) { 123 if (mService.containsKey(callingInfo)) { 124 return CREATED; 125 } else { 126 return NON_EXISTENT; 127 } 128 } 129 130 @Override dump(PrintWriter writer)131 public void dump(PrintWriter writer) { 132 writer.println(FAKE_DUMP_OUTPUT); 133 } 134 135 @NonNull 136 @Override toSandboxProcessName(@onNull CallingInfo callingInfo)137 public String toSandboxProcessName(@NonNull CallingInfo callingInfo) 138 throws PackageManager.NameNotFoundException { 139 return TEST_PACKAGE + SANDBOX_PROCESS_NAME_SUFFIX; 140 } 141 142 @NonNull 143 @Override toSandboxProcessNameForInstrumentation(@onNull CallingInfo callingInfo)144 public String toSandboxProcessNameForInstrumentation(@NonNull CallingInfo callingInfo) 145 throws PackageManager.NameNotFoundException { 146 return TEST_PACKAGE + SANDBOX_INSTR_PROCESS_NAME_SUFFIX; 147 } 148 } 149