1 /* 2 * Copyright (C) 2021 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.system.virtualmachine; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.Context; 22 23 import java.lang.ref.WeakReference; 24 import java.util.Map; 25 import java.util.WeakHashMap; 26 27 /** 28 * Manages {@link VirtualMachine} objects created for an application. 29 * 30 * @hide 31 */ 32 public class VirtualMachineManager { 33 private final @NonNull Context mContext; 34 VirtualMachineManager(@onNull Context context)35 private VirtualMachineManager(@NonNull Context context) { 36 mContext = context; 37 } 38 39 static Map<Context, WeakReference<VirtualMachineManager>> sInstances = new WeakHashMap<>(); 40 41 /** Returns the per-context instance. */ getInstance(@onNull Context context)42 public static @NonNull VirtualMachineManager getInstance(@NonNull Context context) { 43 synchronized (sInstances) { 44 VirtualMachineManager vmm = 45 sInstances.containsKey(context) ? sInstances.get(context).get() : null; 46 if (vmm == null) { 47 vmm = new VirtualMachineManager(context); 48 sInstances.put(context, new WeakReference(vmm)); 49 } 50 return vmm; 51 } 52 } 53 54 /** A lock used to synchronize the creation of virtual machines */ 55 private static final Object sCreateLock = new Object(); 56 57 /** 58 * Creates a new {@link VirtualMachine} with the given name and config. Creating a virtual 59 * machine with the same name as an existing virtual machine is an error. The existing virtual 60 * machine has to be deleted before its name can be reused. Every call to this methods creates a 61 * new (and different) virtual machine even if the name and the config are the same as the 62 * deleted one. 63 */ create( @onNull String name, @NonNull VirtualMachineConfig config)64 public @NonNull VirtualMachine create( 65 @NonNull String name, @NonNull VirtualMachineConfig config) 66 throws VirtualMachineException { 67 synchronized (sCreateLock) { 68 return VirtualMachine.create(mContext, name, config); 69 } 70 } 71 72 /** 73 * Returns an existing {@link VirtualMachine} with the given name. Returns null if there is no 74 * such virtual machine. 75 */ get(@onNull String name)76 public @Nullable VirtualMachine get(@NonNull String name) throws VirtualMachineException { 77 return VirtualMachine.load(mContext, name); 78 } 79 80 /** 81 * Returns an existing {@link VirtualMachine} if it exists, or create a new one. The config 82 * parameter is used only when a new virtual machine is created. 83 */ getOrCreate( @onNull String name, @NonNull VirtualMachineConfig config)84 public @NonNull VirtualMachine getOrCreate( 85 @NonNull String name, @NonNull VirtualMachineConfig config) 86 throws VirtualMachineException { 87 VirtualMachine vm; 88 synchronized (sCreateLock) { 89 vm = get(name); 90 if (vm == null) { 91 vm = create(name, config); 92 } 93 } 94 return vm; 95 } 96 } 97