/*
* Copyright 2012-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.android;
import java.nio.file.Path;
/** Specifies how secondary .dex files should be stored in the .apk. */
enum DexStore {
/** Secondary dexes should be raw dex files for inclusion in the APK. */
RAW {
@Override
public String fileNameForSecondary(int index) {
return fileNameForSecondary("classes", index);
}
@Override
public String fileNameForSecondary(String prefix, int index) {
// Google expects secondary dex files to start at 2.
// I guess classes.dex is number 1.
return String.format("%s%d.dex", prefix, index + 2);
}
@Override
public boolean matchesPath(Path path) {
return path.getFileName().toString().matches(".*\\d+\\.dex");
}
},
/** Secondary dexes should be compressed using JAR's deflate. */
JAR {
@Override
public String fileNameForSecondary(int index) {
return fileNameForSecondary("secondary", index);
}
@Override
public String fileNameForSecondary(String prefix, int index) {
// Start at one for easier comprehension by humans.
return String.format("%s-%s.dex.jar", prefix, index + 1);
}
@Override
public boolean matchesPath(Path path) {
return path.getFileName().toString().endsWith(".dex.jar");
}
},
/** Secondary dexes should be stored uncompressed in jars that will be XZ-compressed. */
XZ {
@Override
public String fileNameForSecondary(int index) {
return fileNameForSecondary("secondary", index);
}
@Override
public String fileNameForSecondary(String prefix, int index) {
// Start at one for easier comprehension by humans.
return String.format("%s-%s.dex.jar.xz", prefix, index + 1);
}
@Override
public boolean matchesPath(Path path) {
return path.getFileName().toString().endsWith(".dex.jar.xz");
}
},
/** Secondary dexes will be solid compressed into a single XZS file. */
XZS {
// Since secondary dexes are created in parallel, we add a .tmp~
// extension to indicate that this process is not yet complete.
// A .dex.jar.xzs.tmp~ is a dex file that is waiting to be concatenated
// and then XZ compressed. The ~ character is a hack to ensure that
// the external apkbuilder tool does not copy this file to the final apk.
// The alternative would require either rewriting apkbuilder or writing substantial code
// to get around the current limitations of its API.
@Override
public String fileNameForSecondary(int index) {
return fileNameForSecondary("secondary", index);
}
@Override
public String fileNameForSecondary(String prefix, int index) {
return String.format("%s-%s.dex.jar.xzs.tmp~", prefix, index + 1);
}
@Override
public boolean matchesPath(Path path) {
return path.getFileName().toString().endsWith(".dex.jar.xzs.tmp~");
}
},
;
/**
* @param index The index of a given secondary dex file, starting from 0.
* @return The appropriate name for the secondary dex file at {@code index}.
*/
public abstract String fileNameForSecondary(int index);
/**
* @param prefix The prefix to use to name the file according to what store it is in
* @param index The index of a given secondary dex file, starting from 0.
* @return The appropriate name for the dex file at {@code index}.
*/
public abstract String fileNameForSecondary(String prefix, int index);
/**
* @param path The path where a secondary dex file will be written.
* @return Whether that file is of this DexStore type.
*/
public abstract boolean matchesPath(Path path);
}