AvdWizardUtils { @VisibleForTesting @Nullable public static File ensureSkinsAreCurrent(@Nullable File resourcePath, @Nullable File skinDestination, @Nullable File deviceName, boolean emulatorCanDecodeWebp, @NotNull FileOp fop) { if (resourcePath == null) { return (skinDestination == null) ? deviceName : skinDestination; } if (skinDestination == null) { return resourcePath; } if (fop.exists(skinDestination)) { File resourceLayout = new File(resourcePath, FN_SKIN_LAYOUT); File destLayout = new File(skinDestination, FN_SKIN_LAYOUT); if (!resourceLayout.exists() || (destLayout.exists() && destLayout.lastModified() >= resourceLayout.lastModified())) { return skinDestination; } fop.deleteFileOrFolder(skinDestination); } try { fop.mkdirs(skinDestination); if (!emulatorCanDecodeWebp) { convertWebpSkinToPng(fop, skinDestination, resourcePath); } else { for (File src : fop.listFiles(resourcePath)) { File target = new File(skinDestination, src.getName()); if (fop.isFile(src)) { fop.copyFile(src, target); } } } return skinDestination; } catch (IOException e) { getLog().warn(String.format("Failed to copy skin directory to %1$s, using studio-relative path %2$s", skinDestination, resourcePath)); } return resourcePath; }  @NotNull static Storage getDefaultRam(@NotNull Hardware hardware); @NotNull static Storage getMaxPossibleRam(); static int getMaxCpuCores(); @Nullable static String getHardwarePropertyDefaultValue(String name, @Nullable AndroidSdkHandler sdkHandler); static String cleanAvdName(@NotNull AvdManagerConnection connection, @NotNull String candidateBase, boolean uniquify); @Nullable static File pathToUpdatedSkins(@Nullable File deviceFile, @Nullable SystemImageDescription image, @NotNull FileOp fop); @VisibleForTesting @Nullable static File ensureSkinsAreCurrent(@Nullable File resourcePath,
                                           @Nullable File skinDestination,
                                           @Nullable File deviceName,
                                           boolean emulatorCanDecodeWebp,
                                           @NotNull FileOp fop); static ModelWizardDialog createAvdWizard(@Nullable Component parent,
                                                  @Nullable Project project); static ModelWizardDialog createAvdWizard(@Nullable Component parent,
                                                  @Nullable Project project,
                                                  @Nullable AvdInfo avdInfo); static ModelWizardDialog createAvdWizard(@Nullable Component parent,
                                                  @Nullable Project project,
                                                  @NotNull AvdOptionsModel model); static ModelWizardDialog createAvdWizardForDuplication(@Nullable Component parent,
                                                                @Nullable Project project,
                                                                @NotNull  AvdInfo avdInfo); static final String WIZARD_ONLY; static final String DEVICE_DEFINITION_KEY; static final String SYSTEM_IMAGE_KEY; static final String RAM_STORAGE_KEY; static final String VM_HEAP_STORAGE_KEY; static final String INTERNAL_STORAGE_KEY; static final String SD_CARD_STORAGE_KEY; static final String EXISTING_SD_LOCATION; static final String DISPLAY_SD_SIZE_KEY; static final String DISPLAY_SD_LOCATION_KEY; static final String DISPLAY_USE_EXTERNAL_SD_KEY; static final String DEFAULT_ORIENTATION_KEY; static final String AVD_INI_NETWORK_SPEED; static final String NETWORK_SPEED_KEY; static final String AVD_INI_NETWORK_LATENCY; static final String NETWORK_LATENCY_KEY; static final String FRONT_CAMERA_KEY; static final String BACK_CAMERA_KEY; static final String USE_HOST_GPU_KEY; static final String HOST_GPU_MODE_KEY; static final String USE_COLD_BOOT; static final String USE_FAST_BOOT; static final String USE_CHOSEN_SNAPSHOT_BOOT; static final String CHOSEN_SNAPSHOT_FILE; static final String COLD_BOOT_ONCE_VALUE; static final String IS_IN_EDIT_MODE_KEY; static final String CUSTOM_SKIN_FILE_KEY; static final String BACKUP_SKIN_FILE_KEY; static final String DEVICE_FRAME_KEY; static final String DISPLAY_NAME_KEY; static final String AVD_ID_KEY; static final String CPU_CORES_KEY; static final String HAS_HARDWARE_KEYBOARD_KEY; static final Font STANDARD_FONT; static final Font FIGURE_FONT; static final Font TITLE_FONT; static final List<IdDisplay> ALL_DEVICE_TAGS; static final List<IdDisplay> TAGS_WITH_GOOGLE_API; static final String CREATE_SKIN_HELP_LINK; static final File NO_SKIN; }
@Test public void testEnsureSkinsAreCurrent() throws IOException { WebpMetadata.ensureWebpRegistered(); if (!WebpNativeLibHelper.loadNativeLibraryIfNeeded()) { System.out.println("Can't run skin conversion test without native webp library"); return; } DeviceArtDescriptor pixel = null; List<DeviceArtDescriptor> specs = DeviceArtDescriptor.getDescriptors(null); for (DeviceArtDescriptor spec : specs) { if ("pixel".equals(spec.getId())) { pixel = spec; break; } } assertThat(pixel).isNotNull(); File skinResource = pixel.getBaseFolder(); FileOp fileOp = FileOpUtils.create(); File resourceLayout = new File(skinResource, "layout"); assertThat(fileOp.exists(resourceLayout)).isTrue(); assertThat(fileOp.exists(new File(skinResource, "port_back.webp"))).isTrue(); String deviceName = skinResource.getName(); File deviceFile = new File(deviceName); File skinDestinationBase = new File(myFolder.getRoot(), "skins"); File skinDestination = new File(skinDestinationBase, deviceName); File resultFile = AvdWizardUtils.ensureSkinsAreCurrent(skinResource, skinDestination, deviceFile, true, fileOp); assertThat(resultFile).isEqualTo(skinDestination); File destLayout = new File(skinDestination, "layout"); File destPortBack = new File(skinDestination, "port_back.webp"); assertThat(fileOp.exists(destLayout)).isTrue(); assertThat(fileOp.exists(destPortBack)).isTrue(); fileOp.delete(destPortBack); AvdWizardUtils.ensureSkinsAreCurrent(skinResource, skinDestination, deviceFile, true, fileOp); assertThat(fileOp.exists(destLayout)).isTrue(); assertThat(fileOp.exists(destPortBack)).isFalse(); fileOp.setLastModified(destLayout, resourceLayout.lastModified() - 10); AvdWizardUtils.ensureSkinsAreCurrent(skinResource, skinDestination, deviceFile, true, fileOp); assertThat(fileOp.exists(destLayout)).isTrue(); assertThat(fileOp.exists(destPortBack)).isTrue(); fileOp.setLastModified(destLayout, resourceLayout.lastModified() - 10); AvdWizardUtils.ensureSkinsAreCurrent(skinResource, skinDestination, deviceFile, false, fileOp); assertThat(fileOp.exists(destLayout)).isTrue(); assertThat(fileOp.exists(destPortBack)).isFalse(); assertThat(fileOp.exists(new File(skinDestination, "port_back.png"))).isTrue(); resultFile = AvdWizardUtils.ensureSkinsAreCurrent(null, skinDestination, deviceFile, true, fileOp); assertThat(resultFile).isEqualTo(skinDestination); resultFile = AvdWizardUtils.ensureSkinsAreCurrent(skinResource, null, deviceFile, true, fileOp); assertThat(resultFile).isEqualTo(skinResource); resultFile = AvdWizardUtils.ensureSkinsAreCurrent(null, null, deviceFile, true, fileOp); assertThat(resultFile).isEqualTo(deviceFile); }