aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/java
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2016-10-06 20:21:56 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-10-07 08:08:04 +0000
commit4f005551b52083f1e8995f799d4dc8a690604d95 (patch)
treedd015311f1d71cefa7b7dbd2fe52fbfd2927fb2b /third_party/java
parent69d9b417534aae71728c5f6bcc67fe44bb4e4241 (diff)
Update android_ide_common to 25.0.0 and clean up FolderConfigs
Older android_ide_common does not handle BCP 47, so we update the code to handle that and remove most of the workarounds. This also pulls in a fix for 3-letter locales, unblocks resource shrinking whitelisting, etc. -- MOS_MIGRATED_REVID=135396457
Diffstat (limited to 'third_party/java')
-rw-r--r--third_party/java/apkbuilder/java/com/android/SdkConstants.java163
-rw-r--r--third_party/java/apkbuilder/java/com/android/annotations/NonNull.java2
-rw-r--r--third_party/java/apkbuilder/java/com/android/annotations/Nullable.java2
-rw-r--r--third_party/java/apkbuilder/java/com/android/prefs/AndroidLocation.java198
-rw-r--r--third_party/java/apkbuilder/java/com/android/sdklib/internal/build/DebugKeyProvider.java4
-rw-r--r--third_party/java/apkbuilder/java/com/android/sdklib/internal/build/KeystoreHelper.java2
-rw-r--r--third_party/java/apkbuilder/java/com/android/sdklib/internal/build/SignedJarBuilder.java4
-rw-r--r--third_party/java/apkbuilder/java/com/android/utils/FileUtils.java373
-rw-r--r--third_party/java/apkbuilder/java/com/android/utils/GrabProcessOutput.java4
9 files changed, 669 insertions, 83 deletions
diff --git a/third_party/java/apkbuilder/java/com/android/SdkConstants.java b/third_party/java/apkbuilder/java/com/android/SdkConstants.java
index 56b6a14f22..ee52300771 100644
--- a/third_party/java/apkbuilder/java/com/android/SdkConstants.java
+++ b/third_party/java/apkbuilder/java/com/android/SdkConstants.java
@@ -34,7 +34,7 @@ import java.io.File;
* <li><code>EXT_</code> File name extension, without the dot </li>
* </ul>
*/
-@SuppressWarnings("javadoc") // Not documenting all the fields here
+@SuppressWarnings({"javadoc", "unused"}) // Not documenting all the fields here
public final class SdkConstants {
public static final int PLATFORM_UNKNOWN = 0;
public static final int PLATFORM_LINUX = 1;
@@ -53,6 +53,9 @@ public final class SdkConstants {
/** Property in local.properties file that specifies the path of the Android SDK. */
public static final String SDK_DIR_PROPERTY = "sdk.dir";
+ /** Property in local.properties file that specifies the path of the Android NDK. */
+ public static final String NDK_DIR_PROPERTY = "ndk.dir";
+
/** Property in gradle-wrapper.properties file that specifies the URL to the correct Gradle distribution. */
public static final String GRADLE_DISTRIBUTION_URL_PROPERTY = "distributionUrl"; //$NON-NLS-1$
@@ -79,6 +82,8 @@ public final class SdkConstants {
public static final String FN_CLASSES_JAR = "classes.jar"; //$NON-NLS-1$
/** Dex filename inside the APK. i.e. "classes.dex" */
public static final String FN_APK_CLASSES_DEX = "classes.dex"; //$NON-NLS-1$
+ /** Dex filename inside the APK. i.e. "classes.dex" */
+ public static final String FN_APK_CLASSES_N_DEX = "classes%d.dex"; //$NON-NLS-1$
/** An SDK Project's build.xml file */
public static final String FN_BUILD_XML = "build.xml"; //$NON-NLS-1$
@@ -199,6 +204,10 @@ public final class SdkConstants {
public static final String FN_EMULATOR =
"emulator" + ext(".exe", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ /** emulator-check executable for the current OS */
+ public static final String FN_EMULATOR_CHECK =
+ "emulator-check" + ext(".exe", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
/** zipalign executable (with extension for the current OS) */
public static final String FN_ZIPALIGN =
"zipalign" + ext(".exe", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@@ -219,6 +228,15 @@ public final class SdkConstants {
public static final String FN_HPROF_CONV =
"hprof-conv" + ext(".exe", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ /** jack.jar */
+ public static final String FN_JACK = "jack.jar"; //$NON-NLS-1$
+ /** jill.jar */
+ public static final String FN_JILL = "jill.jar"; //$NON-NLS-1$
+
+ /** split-select */
+ public static final String FN_SPLIT_SELECT = "split-select" + ext(".exe", "");
+
+
/** properties file for SDK Updater packages */
public static final String FN_SOURCE_PROP = "source.properties"; //$NON-NLS-1$
/** properties file for content hash of installed packages */
@@ -259,6 +277,8 @@ public final class SdkConstants {
public static final String FD_TEST = "androidTest"; //$NON-NLS-1$
/** Default java code folder name, i.e. "java" */
public static final String FD_JAVA = "java"; //$NON-NLS-1$
+ /** Default native code folder name, i.e. "jni" */
+ public static final String FD_JNI = "jni"; //$NON-NLS-1$
/** Default gradle folder name, i.e. "gradle" */
public static final String FD_GRADLE = "gradle"; //$NON-NLS-1$
/** Default gradle wrapper folder name, i.e. "gradle/wrapper" */
@@ -286,6 +306,9 @@ public final class SdkConstants {
/** rs Libs output folder for support mode */
public static final String FD_RS_OBJ = "rsObj"; //$NON-NLS-1$
+ /** jars folder */
+ public static final String FD_JARS = "jars"; //$NON-NLS-1$
+
/* Folder Names for the Android SDK */
/** Name of the SDK platforms folder. */
@@ -341,6 +364,8 @@ public final class SdkConstants {
/** Name of the SDK extras folder. */
public static final String FD_EXTRAS = "extras"; //$NON-NLS-1$
public static final String FD_M2_REPOSITORY = "m2repository"; //$NON-NLS-1$
+ public static final String FD_NDK = "ndk-bundle"; //$NON-NLS-1$
+ public static final String FD_LLDB = "lldb"; //$NON-NLS-1$
/**
* Name of an extra's sample folder.
* Ideally extras should have one {@link #FD_SAMPLES} folder containing
@@ -358,6 +383,8 @@ public final class SdkConstants {
public static final String FD_DATA = "data"; //$NON-NLS-1$
/** Name of the SDK renderscript folder, i.e. "rs" */
public static final String FD_RENDERSCRIPT = "rs"; //$NON-NLS-1$
+ /** Name of the Java resources folder, i.e. "resources" */
+ public static final String FD_JAVA_RES = "resources"; //$NON-NLS-1$
/** Name of the SDK resources folder, i.e. "res" */
public static final String FD_RES = "res"; //$NON-NLS-1$
/** Name of the SDK font folder, i.e. "fonts" */
@@ -389,7 +416,7 @@ public final class SdkConstants {
* Note: if you need an URI specifically for the "android" namespace, consider using
* {@link SdkConstants#NS_RESOURCES} instead.
*/
- public final static String NS_CUSTOM_RESOURCES_S = "http://schemas.android.com/apk/res/%1$s"; //$NON-NLS-1$
+ public static final String NS_CUSTOM_RESOURCES_S = "http://schemas.android.com/apk/res/%1$s"; //$NON-NLS-1$
/** The name of the uses-library that provides "android.test.runner" */
@@ -433,7 +460,7 @@ public final class SdkConstants {
/** Path of the bin folder of proguard folder relative to the sdk folder.
* This is an OS path, ending with a separator. */
public static final String OS_SDK_TOOLS_PROGUARD_BIN_FOLDER =
- SdkConstants.OS_SDK_TOOLS_FOLDER +
+ OS_SDK_TOOLS_FOLDER +
"proguard" + File.separator + //$NON-NLS-1$
"bin" + File.separator; //$NON-NLS-1$
@@ -531,6 +558,7 @@ public final class SdkConstants {
public static final String CLASS_SERVICE = "android.app.Service"; //$NON-NLS-1$
public static final String CLASS_BROADCASTRECEIVER = "android.content.BroadcastReceiver"; //$NON-NLS-1$
public static final String CLASS_CONTENTPROVIDER = "android.content.ContentProvider"; //$NON-NLS-1$
+ public static final String CLASS_ATTRIBUTE_SET = "android.util.AttributeSet"; //$NON-NLS-1$
public static final String CLASS_INSTRUMENTATION = "android.app.Instrumentation"; //$NON-NLS-1$
public static final String CLASS_INSTRUMENTATION_RUNNER =
"android.test.InstrumentationTestRunner"; //$NON-NLS-1$
@@ -540,6 +568,7 @@ public final class SdkConstants {
public static final String CLASS_MANIFEST_PERMISSION = "android.Manifest$permission"; //$NON-NLS-1$
public static final String CLASS_INTENT = "android.content.Intent"; //$NON-NLS-1$
public static final String CLASS_CONTEXT = "android.content.Context"; //$NON-NLS-1$
+ public static final String CLASS_RESOURCES = "android.content.res.Resources"; //$NON-NLS-1$
public static final String CLASS_VIEW = "android.view.View"; //$NON-NLS-1$
public static final String CLASS_VIEWGROUP = "android.view.ViewGroup"; //$NON-NLS-1$
public static final String CLASS_NAME_LAYOUTPARAMS = "LayoutParams"; //$NON-NLS-1$
@@ -554,11 +583,30 @@ public final class SdkConstants {
"android.preference." + CLASS_NAME_PREFERENCE_SCREEN; //$NON-NLS-1$
public static final String CLASS_PREFERENCEGROUP = "android.preference.PreferenceGroup"; //$NON-NLS-1$
public static final String CLASS_PARCELABLE = "android.os.Parcelable"; //$NON-NLS-1$
+ public static final String CLASS_PARCEL = "android.os.Parcel"; //$NON-NLS-1$
public static final String CLASS_FRAGMENT = "android.app.Fragment"; //$NON-NLS-1$
public static final String CLASS_V4_FRAGMENT = "android.support.v4.app.Fragment"; //$NON-NLS-1$
+ public static final String CLASS_ACTION_PROVIDER = "android.view.ActionProvider"; //$NON-NLS-1$
+ public static final String CLASS_BACKUP_AGENT = "android.app.backup.BackupAgent"; //$NON-NLS-1$
/** MockView is part of the layoutlib bridge and used to display classes that have
* no rendering in the graphical layout editor. */
public static final String CLASS_MOCK_VIEW = "com.android.layoutlib.bridge.MockView"; //$NON-NLS-1$
+ public static final String CLASS_LAYOUT_INFLATER = "android.view.LayoutInflater"; //$NON-NLS-1$
+ public static final String CLASS_DATA_BINDING_COMPONENT = "android.databinding.DataBindingComponent"; //$NON-NLS-1$
+ public static final String CLASS_NAME_DATA_BINDING_COMPONENT = "DataBindingComponent"; //$NON-NLS-1$
+ public static final String CLASS_DATA_BINDING_BASE_BINDING = "android.databinding.ViewDataBinding";
+
+ /* Android Design Support Class Constants */
+ public static final String CLASS_COORDINATOR_LAYOUT = "android.support.design.widget.CoordinatorLayout"; //$NON-NLS-1$
+ public static final String CLASS_APP_BAR_LAYOUT = "android.support.design.widget.AppBarLayout"; //$NON-NLS-1$
+ public static final String CLASS_FLOATING_ACTION_BUTTON = "android.support.design.widget.FloatingActionButton"; //$NON-NLS-1$
+ public static final String CLASS_COLLAPSING_TOOLBAR_LAYOUT = "android.support.design.widget.CollapsingToolbarLayout"; //$NON-NLS-1$
+ public static final String CLASS_NAVIGATION_VIEW = "android.support.design.widget.NavigationView"; //$NON-NLS-1$
+ public static final String CLASS_SNACKBAR = "android.support.design.widget.Snackbar"; //$NON-NLS-1$
+ public static final String CLASS_TAB_LAYOUT = "android.support.design.widget.TabLayout"; //$NON-NLS-1$
+ public static final String CLASS_TEXT_INPUT_LAYOUT = "android.support.design.widget.TextInputLayout"; //$NON-NLS-1$
+ public static final String CLASS_NESTED_SCROLL_VIEW = "android.support.v4.widget.NestedScrollView"; //$NON-NLS-1$
+
/** Returns the appropriate name for the 'android' command, which is 'android.exe' for
* Windows and 'android' for all other platforms. */
@@ -696,8 +744,12 @@ public final class SdkConstants {
/** Namespace used for auto-adjusting namespaces */
public static final String AUTO_URI =
"http://schemas.android.com/apk/res-auto"; //$NON-NLS-1$
+ /** Namespace for xliff in string resources. */
+ public static final String XLIFF_URI = "urn:oasis:names:tc:xliff:document:1.2";
/** Default prefix used for tools attributes */
public static final String TOOLS_PREFIX = "tools"; //$NON-NLS-1$
+ /** Default prefix used for xliff tags. */
+ public static final String XLIFF_PREFIX = "xliff"; //$NON-NLS-1$
public static final String R_CLASS = "R"; //$NON-NLS-1$
public static final String ANDROID_PKG = "android"; //$NON-NLS-1$
@@ -706,6 +758,8 @@ public final class SdkConstants {
public static final String TAG_PERMISSION = "permission"; //$NON-NLS-1$
public static final String TAG_USES_FEATURE = "uses-feature"; //$NON-NLS-1$
public static final String TAG_USES_PERMISSION = "uses-permission";//$NON-NLS-1$
+ public static final String TAG_USES_PERMISSION_SDK_23 = "uses-permission-sdk-23";//$NON-NLS-1$
+ public static final String TAG_USES_PERMISSION_SDK_M = "uses-permission-sdk-m";//$NON-NLS-1$
public static final String TAG_USES_LIBRARY = "uses-library"; //$NON-NLS-1$
public static final String TAG_APPLICATION = "application"; //$NON-NLS-1$
public static final String TAG_INTENT_FILTER = "intent-filter"; //$NON-NLS-1$
@@ -736,9 +790,12 @@ public final class SdkConstants {
public static final String TAG_DECLARE_STYLEABLE = "declare-styleable"; //$NON-NLS-1$
public static final String TAG_EAT_COMMENT = "eat-comment"; //$NON-NLS-1$
public static final String TAG_SKIP = "skip"; //$NON-NLS-1$
+ public static final String TAG_SELECTOR = "selector"; //$NON-NLS-1$
// Tags: XML
public static final String TAG_HEADER = "header"; //$NON-NLS-1$
+ public static final String TAG_APPWIDGET_PROVIDER = "appwidget-provider"; //$NON-NLS-1$
+ public static final String TAG_PREFERENCE_SCREEN = "PreferenceScreen"; //$NON-NLS-1$
// Tags: Layouts
public static final String VIEW_TAG = "view"; //$NON-NLS-1$
@@ -792,10 +849,27 @@ public final class SdkConstants {
public static final String MULTI_AUTO_COMPLETE_TEXT_VIEW = "MultiAutoCompleteTextView"; //$NON-NLS-1$
public static final String AUTO_COMPLETE_TEXT_VIEW = "AutoCompleteTextView"; //$NON-NLS-1$
public static final String CHECKABLE = "Checkable"; //$NON-NLS-1$
+ public static final String TEXTURE_VIEW = "TextureView"; //$NON-NLS-1$
+
+ /* Android Design Support Tag Constants */
+ public static final String COORDINATOR_LAYOUT = CLASS_COORDINATOR_LAYOUT;
+ public static final String APP_BAR_LAYOUT = CLASS_APP_BAR_LAYOUT;
+ public static final String FLOATING_ACTION_BUTTON = CLASS_FLOATING_ACTION_BUTTON;
+ public static final String COLLAPSING_TOOLBAR_LAYOUT = CLASS_COLLAPSING_TOOLBAR_LAYOUT;
+ public static final String NAVIGATION_VIEW = CLASS_NAVIGATION_VIEW;
+ public static final String SNACKBAR = CLASS_SNACKBAR;
+ public static final String TAB_LAYOUT = CLASS_TAB_LAYOUT;
+ public static final String TEXT_INPUT_LAYOUT = CLASS_TEXT_INPUT_LAYOUT;
// Tags: Drawables
public static final String TAG_BITMAP = "bitmap"; //$NON-NLS-1$
+ // Tags: Data-Binding
+ public static final String TAG_LAYOUT = "layout"; //$NON-NLS-1$
+ public static final String TAG_DATA = "data"; //$NON-NLS-1$
+ public static final String TAG_VARIABLE = "variable"; //$NON-NLS-1$
+ public static final String TAG_IMPORT = "import"; //$NON-NLS-1$
+
// Attributes: Manifest
public static final String ATTR_EXPORTED = "exported"; //$NON-NLS-1$
public static final String ATTR_PERMISSION = "permission"; //$NON-NLS-1$
@@ -805,6 +879,8 @@ public final class SdkConstants {
public static final String ATTR_PACKAGE = "package"; //$NON-NLS-1$
public static final String ATTR_CORE_APP = "coreApp"; //$NON-NLS-1$
public static final String ATTR_THEME = "theme"; //$NON-NLS-1$
+ public static final String ATTR_SCHEME = "scheme"; //$NON_NLS-1$
+ public static final String ATTR_HOST = "host"; //$NON_NLS-1$
public static final String ATTR_PATH = "path"; //$NON-NLS-1$
public static final String ATTR_PATH_PREFIX = "pathPrefix"; //$NON-NLS-1$
public static final String ATTR_PATH_PATTERN = "pathPattern"; //$NON-NLS-1$
@@ -814,6 +890,7 @@ public final class SdkConstants {
public static final String ATTR_WRITE_PERMISSION = "writePermission"; //$NON_NLS-1$
public static final String ATTR_VERSION_CODE = "versionCode"; //$NON_NLS-1$
public static final String ATTR_VERSION_NAME = "versionName"; //$NON_NLS-1$
+ public static final String ATTR_FULL_BACKUP_CONTENT = "fullBackupContent"; //$NON_NLS-1$
// Attributes: Resources
public static final String ATTR_NAME = "name"; //$NON-NLS-1$
@@ -826,6 +903,10 @@ public final class SdkConstants {
public static final String ATTR_VALUE = "value"; //$NON-NLS-1$
public static final String ATTR_QUANTITY = "quantity"; //$NON-NLS-1$
public static final String ATTR_FORMAT = "format"; //$NON-NLS-1$
+ public static final String ATTR_PREPROCESSING = "preprocessing"; //$NON-NLS-1$
+
+ // Attributes: Data-Binding
+ public static final String ATTR_ALIAS = "alias"; //$NON-NLS-1$
// Attributes: Layout
public static final String ATTR_LAYOUT_RESOURCE_PREFIX = "layout_";//$NON-NLS-1$
@@ -895,6 +976,14 @@ public final class SdkConstants {
public static final String ATTR_LIST_PREFERRED_ITEM_PADDING_END =
"listPreferredItemPaddingEnd"; //$NON-NLS-1$
public static final String ATTR_INDEX = "index"; //$NON-NLS-1$
+ public static final String ATTR_ACTION_BAR_NAV_MODE = "actionBarNavMode"; //$NON-NLS-1$
+ public static final String ATTR_MENU = "menu"; //$NON-NLS-1$
+ public static final String ATTR_SHOW_IN = "showIn"; //$NON-NLS-1$
+
+ // Tools attributes for AdapterView inheritors
+ public static final String ATTR_LISTFOOTER = "listfooter"; //$NON-NLS-1$
+ public static final String ATTR_LISTHEADER = "listheader"; //$NON-NLS-1$
+ public static final String ATTR_LISTITEM = "listitem"; //$NON-NLS-1$
// AbsoluteLayout layout params
public static final String ATTR_LAYOUT_Y = "layout_y"; //$NON-NLS-1$
@@ -946,6 +1035,12 @@ public final class SdkConstants {
// Attributes: Drawables
public static final String ATTR_TILE_MODE = "tileMode"; //$NON-NLS-1$
+ // Attributes: CoordinatorLayout
+ public static final String ATTR_LAYOUT_ANCHOR = "layout_anchor"; //$NON-NLS-1$
+ public static final String ATTR_LAYOUT_ANCHOR_GRAVITY = "layout_anchorGravity"; //$NON-NLS-1$
+ public static final String ATTR_LAYOUT_BEHAVIOR = "layout_behavior"; //$NON-NLS-1$
+ public static final String ATTR_LAYOUT_KEYLINE = "layout_keyline"; //$NON-NLS-1$
+
// Values: Manifest
public static final String VALUE_SPLIT_ACTION_BAR_WHEN_NARROW = "splitActionBarWhenNarrow"; // NON-NLS-$1
@@ -959,7 +1054,6 @@ public final class SdkConstants {
public static final String VALUE_SELECTABLE_ITEM_BACKGROUND =
"?android:attr/selectableItemBackground"; //$NON-NLS-1$
-
// Values: Resources
public static final String VALUE_ID = "id"; //$NON-NLS-1$
@@ -995,9 +1089,11 @@ public final class SdkConstants {
public static final String RES_FOLDER = "res"; //$NON-NLS-1$
public static final String DOT_XML = ".xml"; //$NON-NLS-1$
+ public static final String DOT_XSD = ".xsd"; //$NON-NLS-1$
public static final String DOT_GIF = ".gif"; //$NON-NLS-1$
public static final String DOT_JPG = ".jpg"; //$NON-NLS-1$
public static final String DOT_JPEG = ".jpeg"; //$NON-NLS-1$
+ public static final String DOT_WEBP = ".webp"; //$NON-NLS-1$
public static final String DOT_PNG = ".png"; //$NON-NLS-1$
public static final String DOT_9PNG = ".9.png"; //$NON-NLS-1$
public static final String DOT_JAVA = ".java"; //$NON-NLS-1$
@@ -1005,6 +1101,7 @@ public final class SdkConstants {
public static final String DOT_JAR = ".jar"; //$NON-NLS-1$
public static final String DOT_GRADLE = ".gradle"; //$NON-NLS-1$
public static final String DOT_PROPERTIES = ".properties"; //$NON-NLS-1$
+ public static final String DOT_JSON = ".json"; //$NON-NLS-1$
/** Extension of the Application package Files, i.e. "apk". */
public static final String EXT_ANDROID_PACKAGE = "apk"; //$NON-NLS-1$
@@ -1061,6 +1158,8 @@ public final class SdkConstants {
public static final String DOT_BC = DOT + EXT_BC;
/** Dot-Extension of dependency files, i.e. ".d" */
public static final String DOT_DEP = DOT + EXT_DEP;
+ /** Dot-Extension of native dynamic libraries, i.e. ".so" */
+ public static final String DOT_NATIVE_LIBS = DOT + EXT_NATIVE_LIB;
/** Dot-Extension of dex files, i.e. ".dex" */
public static final String DOT_DEX = DOT + EXT_DEX;
/** Dot-Extension for temporary resource files, ie "ap_ */
@@ -1075,6 +1174,8 @@ public final class SdkConstants {
public static final String DOT_TXT = ".txt"; //$NON-NLS-1$
/** Dot-Extension for Android archive files */
public static final String DOT_AAR = DOT + EXT_AAR; //$NON-NLS-1$
+ /** Dot-Extension for Java heap dumps. */
+ public static final String DOT_HPROF = DOT + EXT_HPROF; //$NON-NLS-1$
/** Resource base name for java files and classes */
public static final String FN_RESOURCE_BASE = "R"; //$NON-NLS-1$
@@ -1084,6 +1185,8 @@ public final class SdkConstants {
public static final String FN_COMPILED_RESOURCE_CLASS = FN_RESOURCE_BASE + DOT_CLASS;
/** Resource text filename, i.e. "R.txt" */
public static final String FN_RESOURCE_TEXT = FN_RESOURCE_BASE + DOT_TXT;
+ /** Filename for public resources in AAR archives */
+ public static final String FN_PUBLIC_TXT = "public.txt";
/** Generated manifest class name */
public static final String FN_MANIFEST_BASE = "Manifest"; //$NON-NLS-1$
/** Generated BuildConfig class name */
@@ -1096,6 +1199,7 @@ public final class SdkConstants {
public static final String DRAWABLE_FOLDER = "drawable"; //$NON-NLS-1$
public static final String DRAWABLE_XHDPI = "drawable-xhdpi"; //$NON-NLS-1$
public static final String DRAWABLE_XXHDPI = "drawable-xxhdpi"; //$NON-NLS-1$
+ public static final String DRAWABLE_XXXHDPI = "drawable-xxxhdpi"; //$NON-NLS-1$
public static final String DRAWABLE_HDPI = "drawable-hdpi"; //$NON-NLS-1$
public static final String DRAWABLE_MDPI = "drawable-mdpi"; //$NON-NLS-1$
public static final String DRAWABLE_LDPI = "drawable-ldpi"; //$NON-NLS-1$
@@ -1103,6 +1207,8 @@ public final class SdkConstants {
// Resources
public static final String PREFIX_RESOURCE_REF = "@"; //$NON-NLS-1$
public static final String PREFIX_THEME_REF = "?"; //$NON-NLS-1$
+ public static final String PREFIX_BINDING_EXPR = "@{"; //$NON-NLS-1$
+ public static final String PREFIX_TWOWAY_BINDING_EXPR = "@={"; //$NON-NLS-1$
public static final String ANDROID_PREFIX = "@android:"; //$NON-NLS-1$
public static final String ANDROID_THEME_PREFIX = "?android:"; //$NON-NLS-1$
public static final String LAYOUT_RESOURCE_PREFIX = "@layout/"; //$NON-NLS-1$
@@ -1113,9 +1219,11 @@ public final class SdkConstants {
public static final String DRAWABLE_PREFIX = "@drawable/"; //$NON-NLS-1$
public static final String STRING_PREFIX = "@string/"; //$NON-NLS-1$
public static final String DIMEN_PREFIX = "@dimen/"; //$NON-NLS-1$
+ public static final String MIPMAP_PREFIX = "@mipmap/"; //$NON-NLS-1$
public static final String ANDROID_LAYOUT_RESOURCE_PREFIX = "@android:layout/"; //$NON-NLS-1$
public static final String ANDROID_STYLE_RESOURCE_PREFIX = "@android:style/"; //$NON-NLS-1$
+ public static final String ANDROID_COLOR_RESOURCE_PREFIX = "@android:color/"; //$NON-NLS-1$
public static final String ANDROID_NEW_ID_PREFIX = "@android:+id/"; //$NON-NLS-1$
public static final String ANDROID_ID_PREFIX = "@android:id/"; //$NON-NLS-1$
public static final String ANDROID_DRAWABLE_PREFIX = "@android:drawable/"; //$NON-NLS-1$
@@ -1170,14 +1278,6 @@ public final class SdkConstants {
// Class Names
public static final String CONSTRUCTOR_NAME = "<init>"; //$NON-NLS-1$
public static final String CLASS_CONSTRUCTOR = "<clinit>"; //$NON-NLS-1$
- public static final String FRAGMENT = "android/app/Fragment"; //$NON-NLS-1$
- public static final String FRAGMENT_V4 = "android/support/v4/app/Fragment"; //$NON-NLS-1$
- public static final String ANDROID_APP_ACTIVITY = "android/app/Activity"; //$NON-NLS-1$
- public static final String ANDROID_APP_SERVICE = "android/app/Service"; //$NON-NLS-1$
- public static final String ANDROID_CONTENT_CONTENT_PROVIDER =
- "android/content/ContentProvider"; //$NON-NLS-1$
- public static final String ANDROID_CONTENT_BROADCAST_RECEIVER =
- "android/content/BroadcastReceiver"; //$NON-NLS-1$
public static final String ANDROID_VIEW_VIEW = "android/view/View"; //$NON-NLS-1$
// Method Names
@@ -1185,8 +1285,6 @@ public final class SdkConstants {
public static final String GET_STRING_METHOD = "getString"; //$NON-NLS-1$
-
-
public static final String ATTR_TAG = "tag"; //$NON-NLS-1$
public static final String ATTR_NUM_COLUMNS = "numColumns"; //$NON-NLS-1$
@@ -1256,6 +1354,9 @@ public final class SdkConstants {
/** The android.webkit. package prefix */
public static final String ANDROID_WEBKIT_PKG = ANDROID_PKG_PREFIX + "webkit."; //$NON-NLS-1$
+ /** The android.app. package prefix */
+ public static final String ANDROID_APP_PKG = ANDROID_PKG_PREFIX + "app."; //$NON-NLS-1$
+
/** The LayoutParams inner-class name suffix, .LayoutParams */
public static final String DOT_LAYOUT_PARAMS = ".LayoutParams"; //$NON-NLS-1$
@@ -1340,11 +1441,11 @@ public final class SdkConstants {
public static final String VALUE_HORIZONTAL = "horizontal"; //$NON-NLS-1$
public static final String GRADLE_PLUGIN_NAME = "com.android.tools.build:gradle:";
- public static final String GRADLE_MINIMUM_VERSION = "1.12";
- public static final String GRADLE_LATEST_VERSION = "1.12";
- public static final String GRADLE_PLUGIN_MINIMUM_VERSION = "0.12.0";
- public static final String GRADLE_PLUGIN_LATEST_VERSION = "0.12.+";
- public static final String GRADLE_PLUGIN_RECOMMENDED_VERSION = "0.12.2";
+ public static final String GRADLE_MINIMUM_VERSION = "2.2.1";
+ public static final String GRADLE_LATEST_VERSION = "2.10";
+ public static final String GRADLE_PLUGIN_MINIMUM_VERSION = "1.0.0";
+ public static final String GRADLE_PLUGIN_RECOMMENDED_VERSION = "2.0.0-rc3";
+ public static final String GRADLE_PLUGIN_LATEST_VERSION = GRADLE_PLUGIN_RECOMMENDED_VERSION;
public static final String MIN_BUILD_TOOLS_VERSION = "19.1.0";
public static final String SUPPORT_LIB_ARTIFACT = "com.android.support:support-v4";
public static final String APPCOMPAT_LIB_ARTIFACT = "com.android.support:appcompat-v7";
@@ -1356,4 +1457,28 @@ public final class SdkConstants {
public static final String TYPE_DEF_VALUE_ATTRIBUTE = "value";
public static final String TYPE_DEF_FLAG_ATTRIBUTE = "flag";
public static final String FN_ANNOTATIONS_ZIP = "annotations.zip";
+ public static final String BINDING_ADAPTER_ANNOTATION = "android.databinding.BindingAdapter";
+
+ // Data Binding MISC
+ public static final String DATA_BINDING_LIB_ARTIFACT = "com.android.databinding:library";
+ public static final String DATA_BINDING_BASELIB_ARTIFACT = "com.android.databinding:baseLibrary";
+ public static final String DATA_BINDING_ANNOTATION_PROCESSOR_ARTIFACT =
+ "com.android.databinding:compiler";
+ public static final String DATA_BINDING_ADAPTER_LIB_ARTIFACT =
+ "com.android.databinding:adapters";
+ public static final String[] TAGS_DATA_BINDING = new String[]{TAG_VARIABLE,
+ TAG_IMPORT, TAG_LAYOUT, TAG_DATA};
+ public static final String[] ATTRS_DATA_BINDING = new String[]{ATTR_NAME,
+ ATTR_TYPE, ATTR_CLASS, ATTR_ALIAS};
+
+ /** Name of keep attribute in XML */
+ public static final String ATTR_KEEP = "keep";
+ /** Name of discard attribute in XML (to mark resources as not referenced, despite guesses) */
+ public static final String ATTR_DISCARD = "discard";
+ /** Name of attribute in XML to control whether we should guess resources to keep */
+ public static final String ATTR_SHRINK_MODE = "shrinkMode";
+ /** {@linkplain #ATTR_SHRINK_MODE} value to only shrink explicitly encountered resources */
+ public static final String VALUE_STRICT = "strict";
+ /** {@linkplain #ATTR_SHRINK_MODE} value to keep possibly referenced resources */
+ public static final String VALUE_SAFE = "safe";
}
diff --git a/third_party/java/apkbuilder/java/com/android/annotations/NonNull.java b/third_party/java/apkbuilder/java/com/android/annotations/NonNull.java
index 973ebb654b..e306a31215 100644
--- a/third_party/java/apkbuilder/java/com/android/annotations/NonNull.java
+++ b/third_party/java/apkbuilder/java/com/android/annotations/NonNull.java
@@ -32,7 +32,7 @@ import java.lang.annotation.Target;
* This is a marker annotation and it has no specific attributes.
*/
@Documented
-@Retention(RetentionPolicy.CLASS)
+@Retention(RetentionPolicy.SOURCE)
@Target({METHOD,PARAMETER,LOCAL_VARIABLE,FIELD})
public @interface NonNull {
}
diff --git a/third_party/java/apkbuilder/java/com/android/annotations/Nullable.java b/third_party/java/apkbuilder/java/com/android/annotations/Nullable.java
index d9c3861efe..376c1f63c5 100644
--- a/third_party/java/apkbuilder/java/com/android/annotations/Nullable.java
+++ b/third_party/java/apkbuilder/java/com/android/annotations/Nullable.java
@@ -43,7 +43,7 @@ import java.lang.annotation.Target;
* This is a marker annotation and it has no specific attributes.
*/
@Documented
-@Retention(RetentionPolicy.CLASS)
+@Retention(RetentionPolicy.SOURCE)
@Target({METHOD, PARAMETER, LOCAL_VARIABLE, FIELD})
public @interface Nullable {
}
diff --git a/third_party/java/apkbuilder/java/com/android/prefs/AndroidLocation.java b/third_party/java/apkbuilder/java/com/android/prefs/AndroidLocation.java
index 1444cc8279..7bfb316411 100644
--- a/third_party/java/apkbuilder/java/com/android/prefs/AndroidLocation.java
+++ b/third_party/java/apkbuilder/java/com/android/prefs/AndroidLocation.java
@@ -17,6 +17,8 @@
package com.android.prefs;
import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.utils.FileUtils;
import java.io.File;
@@ -26,12 +28,12 @@ import java.io.File;
public final class AndroidLocation {
/**
- * The name of the .android folder returned by {@link #getFolder()}.
+ * The name of the .android folder returned by {@link #getFolder}.
*/
public static final String FOLDER_DOT_ANDROID = ".android";
/**
- * Virtual Device folder inside the path returned by {@link #getFolder()}
+ * Virtual Device folder inside the path returned by {@link #getFolder}
*/
public static final String FOLDER_AVD = "avd";
@@ -47,12 +49,14 @@ public final class AndroidLocation {
}
private static String sPrefsLocation = null;
+ private static String sAvdLocation = null;
/**
* Enum describing which variables to check and whether they should
* be checked via {@link System#getProperty(String)} or {@link System#getenv()} or both.
*/
public enum EnvVar {
+ ANDROID_AVD_HOME("ANDROID_AVD_HOME", true, true), // both sys prop and env var
ANDROID_SDK_HOME("ANDROID_SDK_HOME", true, true), // both sys prop and env var
USER_HOME ("user.home", true, false), // sys prop only
HOME ("HOME", false, true); // env var only
@@ -61,7 +65,7 @@ public final class AndroidLocation {
final boolean mIsSysProp;
final boolean mIsEnvVar;
- private EnvVar(String name, boolean isSysProp, boolean isEnvVar) {
+ EnvVar(String name, boolean isSysProp, boolean isEnvVar) {
mName = name;
mIsSysProp = isSysProp;
mIsEnvVar = isEnvVar;
@@ -70,94 +74,178 @@ public final class AndroidLocation {
public String getName() {
return mName;
}
+
+ @Nullable
+ public String validatePath(boolean silent) throws AndroidLocationException {
+ String path;
+ if (mIsSysProp) {
+ path = checkPath(System.getProperty(mName), silent);
+ if (path != null) {
+ return path;
+ }
+ }
+
+ if (mIsEnvVar) {
+ path = checkPath(System.getenv(mName), silent);
+ if (path != null) {
+ return path;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private String checkPath(@Nullable String path, boolean silent)
+ throws AndroidLocationException {
+ if (path == null) {
+ return null;
+ }
+ File file = new File(path);
+ if (!file.isDirectory()) {
+ return null;
+ }
+ if (!(this == ANDROID_SDK_HOME && isSdkRootWithoutDotAndroid(file))) {
+ return path;
+ }
+ if (!silent) {
+ throw new AndroidLocationException(String.format(
+ "ANDROID_SDK_HOME is set to the root of your SDK: %1$s\n" +
+ "This is the path of the preference folder expected by the Android tools.\n" +
+ "It should NOT be set to the same as the root of your SDK.\n" +
+ "Please set it to a different folder or do not set it at all.\n" +
+ "If this is not set we default to: %2$s",
+ path, findValidPath(USER_HOME, HOME)));
+ }
+ return null;
+ }
+
+ private static boolean isSdkRootWithoutDotAndroid(@NonNull File folder) {
+ return subFolderExist(folder, "platforms") &&
+ subFolderExist(folder, "platform-tools") &&
+ !subFolderExist(folder, FOLDER_DOT_ANDROID);
+ }
+
+ private static boolean subFolderExist(@NonNull File folder, @NonNull String subFolder) {
+ return new File(folder, subFolder).isDirectory();
+ }
}
/**
* Returns the folder used to store android related files.
+ * If the folder is not created yet, it will be created here.
* @return an OS specific path, terminated by a separator.
* @throws AndroidLocationException
*/
- @NonNull
- public static final String getFolder() throws AndroidLocationException {
+ public static String getFolder() throws AndroidLocationException {
if (sPrefsLocation == null) {
- String home = findValidPath(new EnvVar[] { EnvVar.ANDROID_SDK_HOME,
- EnvVar.USER_HOME,
- EnvVar.HOME });
-
- // if the above failed, we throw an exception.
- if (home == null) {
- throw new AndroidLocationException(
- "Unable to get the Android SDK home directory.\n" +
- "Make sure the environment variable ANDROID_SDK_HOME is set up.");
- } else {
- sPrefsLocation = home;
- if (!sPrefsLocation.endsWith(File.separator)) {
- sPrefsLocation += File.separator;
- }
- sPrefsLocation += FOLDER_DOT_ANDROID + File.separator;
- }
+ sPrefsLocation = findHomeFolder();
}
// make sure the folder exists!
File f = new File(sPrefsLocation);
- if (f.exists() == false) {
+ if (!f.exists()) {
try {
- f.mkdir();
+ FileUtils.mkdirs(f);
} catch (SecurityException e) {
AndroidLocationException e2 = new AndroidLocationException(String.format(
- "Unable to create folder '%1$s'. " +
- "This is the path of preference folder expected by the Android tools.",
- sPrefsLocation));
+ "Unable to create folder '%1$s'. " +
+ "This is the path of preference folder expected by the Android tools.",
+ sPrefsLocation));
e2.initCause(e);
throw e2;
}
} else if (f.isFile()) {
- throw new AndroidLocationException(sPrefsLocation +
- " is not a directory! " +
- "This is the path of preference folder expected by the Android tools.");
+ throw new AndroidLocationException(String.format(
+ "%1$s is not a directory!\n" +
+ "This is the path of preference folder expected by the Android tools.", sPrefsLocation));
}
+ return sPrefsLocation;
+ }
+ /**
+ * Returns the folder used to store android related files.
+ * This method will not create the folder if it doesn't exist yet.\
+ *
+ * @return an OS specific path, terminated by a separator or null
+ * if no path is found or an error occurred.
+ */
+ public static String getFolderWithoutWrites() {
+ if (sPrefsLocation == null) {
+ try {
+ sPrefsLocation = findHomeFolder();
+ }
+ catch (AndroidLocationException e) {
+ return null;
+ }
+ }
return sPrefsLocation;
}
+
/**
- * Resets the folder used to store android related files. For testing.
+ * Check the if ANDROID_SDK_HOME variable points to a SDK.
+ * If it points to an SDK
+ * @throws AndroidLocationException
*/
- public static final void resetFolder() {
- sPrefsLocation = null;
+ public static void checkAndroidSdkHome() throws AndroidLocationException {
+ EnvVar.ANDROID_SDK_HOME.validatePath(false);
}
/**
- * Checks a list of system properties and/or system environment variables for validity, and
- * existing director, and returns the first one.
- * @param vars The variables to check. Order does matter.
- * @return the content of the first property/variable that is a valid directory.
+ * Returns the folder where the users AVDs are stored.
+ * @return an OS specific path, terminated by a separator.
+ * @throws AndroidLocationException
*/
- private static String findValidPath(EnvVar... vars) {
- for (EnvVar var : vars) {
- String path;
- if (var.mIsSysProp) {
- path = checkPath(System.getProperty(var.mName));
- if (path != null) {
- return path;
- }
+ @NonNull
+ public static String getAvdFolder() throws AndroidLocationException {
+ if (sAvdLocation == null) {
+ String home = findValidPath(EnvVar.ANDROID_AVD_HOME);
+ if (home == null) {
+ home = getFolder() + FOLDER_AVD;
}
-
- if (var.mIsEnvVar) {
- path = checkPath(System.getenv(var.mName));
- if (path != null) {
- return path;
- }
+ sAvdLocation = home;
+ if (!sAvdLocation.endsWith(File.separator)) {
+ sAvdLocation += File.separator;
}
}
+ return sAvdLocation;
+ }
- return null;
+ private static String findHomeFolder()
+ throws AndroidLocationException {
+ String home = findValidPath(EnvVar.ANDROID_SDK_HOME, EnvVar.USER_HOME, EnvVar.HOME);
+
+ // if the above failed, we throw an exception.
+ if (home == null) {
+ throw new AndroidLocationException(
+ "Unable to get the Android SDK home directory.\n" +
+ "Make sure the environment variable ANDROID_SDK_HOME is set up.");
+ }
+ if (!home.endsWith(File.separator)) {
+ home += File.separator;
+ }
+ return home + FOLDER_DOT_ANDROID + File.separator;
+ }
+
+ /**
+ * Resets the folder used to store android related files. For testing.
+ */
+ public static void resetFolder() {
+ sPrefsLocation = null;
+ sAvdLocation = null;
}
- private static String checkPath(String path) {
- if (path != null) {
- File f = new File(path);
- if (f.isDirectory()) {
+ /**
+ * Checks a list of system properties and/or system environment variables for validity,
+ * and returns the first one.
+ * @param vars The variables to check. Order does matter.
+ * @return the content of the first property/variable that is a valid directory.
+ */
+ @Nullable
+ private static String findValidPath(EnvVar... vars) throws AndroidLocationException {
+ for (EnvVar var : vars) {
+ String path = var.validatePath(true);
+ if (path != null) {
return path;
}
}
diff --git a/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/DebugKeyProvider.java b/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/DebugKeyProvider.java
index 8d4ba37aa3..0f492eabf3 100644
--- a/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/DebugKeyProvider.java
+++ b/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/DebugKeyProvider.java
@@ -41,8 +41,8 @@ import java.security.cert.CertificateException;
public class DebugKeyProvider {
public interface IKeyGenOutput {
- public void out(String message);
- public void err(String message);
+ void out(String message);
+ void err(String message);
}
private static final String PASSWORD_STRING = "android";
diff --git a/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/KeystoreHelper.java b/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/KeystoreHelper.java
index d339ea52af..6ba4e723e8 100644
--- a/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/KeystoreHelper.java
+++ b/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/KeystoreHelper.java
@@ -77,7 +77,7 @@ public final class KeystoreHelper {
String javaHome = System.getProperty("java.home");
- if (javaHome != null && javaHome.length() > 0) {
+ if (javaHome != null && !javaHome.isEmpty()) {
keytoolCommand = javaHome + File.separator + "bin" + File.separator + keytoolCommand;
}
diff --git a/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/SignedJarBuilder.java b/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/SignedJarBuilder.java
index 2faba6ae02..afb7e658fc 100644
--- a/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/SignedJarBuilder.java
+++ b/third_party/java/apkbuilder/java/com/android/sdklib/internal/build/SignedJarBuilder.java
@@ -120,7 +120,7 @@ public class SignedJarBuilder {
* This is typically thrown by implementations of
* {@link IZipEntryFilter#checkEntry(String)}.
*/
- public static class ZipAbortException extends Exception {
+ class ZipAbortException extends Exception {
private static final long serialVersionUID = 1L;
public ZipAbortException() {
@@ -147,7 +147,7 @@ public class SignedJarBuilder {
* @return <code>true</code> if the file should be included.
* @throws ZipAbortException if writing the file should be aborted.
*/
- public boolean checkEntry(String archivePath) throws ZipAbortException;
+ boolean checkEntry(String archivePath) throws ZipAbortException;
}
/**
diff --git a/third_party/java/apkbuilder/java/com/android/utils/FileUtils.java b/third_party/java/apkbuilder/java/com/android/utils/FileUtils.java
new file mode 100644
index 0000000000..7cd718c901
--- /dev/null
+++ b/third_party/java/apkbuilder/java/com/android/utils/FileUtils.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.android.utils;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.android.annotations.NonNull;
+import com.google.common.base.Charsets;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Iterables;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+import com.google.common.io.Closeables;
+import com.google.common.io.Files;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public final class FileUtils {
+
+ private FileUtils() {}
+
+ private static final Joiner PATH_JOINER = Joiner.on(File.separatorChar);
+ private static final Joiner COMMA_SEPARATED_JOINER = Joiner.on(", ");
+ private static final Joiner UNIX_NEW_LINE_JOINER = Joiner.on('\n');
+
+ public static final Function<File, String> GET_NAME = new Function<File, String>() {
+ @Override
+ public String apply(File file) {
+ return file.getName();
+ }
+ };
+
+ public static final Function<File, String> GET_PATH = new Function<File, String>() {
+ @Override
+ public String apply(File file) {
+ return file.getPath();
+ }
+ };
+
+ @NonNull
+ public static Predicate<File> withExtension(@NonNull final String extension) {
+ checkArgument(extension.charAt(0) != '.', "Extension should not start with a dot.");
+
+ return new Predicate<File>() {
+ @Override
+ public boolean apply(File input) {
+ return Files.getFileExtension(input.getName()).equals(extension);
+ }
+ };
+ }
+
+ public static void deleteFolder(@NonNull final File folder) throws IOException {
+ if (!folder.exists()) {
+ return;
+ }
+ File[] files = folder.listFiles();
+ if (files != null) { // i.e. is a directory.
+ for (final File file : files) {
+ deleteFolder(file);
+ }
+ }
+ if (!folder.delete()) {
+ throw new IOException(String.format("Could not delete folder %s", folder));
+ }
+ }
+
+ public static void emptyFolder(@NonNull final File folder) throws IOException {
+ deleteFolder(folder);
+ if (!folder.mkdirs()) {
+ throw new IOException(String.format("Could not create empty folder %s", folder));
+ }
+ }
+
+ public static void copy(@NonNull final File from, @NonNull final File toDir)
+ throws IOException {
+ File to = new File(toDir, from.getName());
+ if (from.isDirectory()) {
+ mkdirs(to);
+
+ File[] children = from.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ copy(child, to);
+ }
+ }
+ } else if (from.isFile()) {
+ Files.copy(from, to);
+ }
+ }
+
+ public static void mkdirs(@NonNull File folder) {
+ // attempt to create first.
+ // if failure only throw if folder does not exist.
+ // This makes this method able to create the same folder(s) from different thread
+ if (!folder.mkdirs() && !folder.exists()) {
+ throw new RuntimeException("Cannot create directory " + folder);
+ }
+ }
+
+ public static void delete(@NonNull File file) throws IOException {
+ boolean result = file.delete();
+ if (!result) {
+ throw new IOException("Failed to delete " + file.getAbsolutePath());
+ }
+ }
+
+ public static void deleteIfExists(@NonNull File file) throws IOException {
+ boolean result = file.delete();
+ if (!result && file.exists()) {
+ throw new IOException("Failed to delete " + file.getAbsolutePath());
+ }
+ }
+
+ public static void renameTo(@NonNull File file, @NonNull File to) throws IOException {
+ boolean result = file.renameTo(to);
+ if (!result) {
+ throw new IOException("Failed to rename " + file.getAbsolutePath() + " to " + to);
+ }
+ }
+
+ /**
+ * Joins a list of path segments to a given File object.
+ *
+ * @param dir the file object.
+ * @param paths the segments.
+ * @return a new File object.
+ */
+ @NonNull
+ public static File join(@NonNull File dir, @NonNull String... paths) {
+ if (paths.length == 0) {
+ return dir;
+ }
+
+ return new File(dir, PATH_JOINER.join(paths));
+ }
+
+ /**
+ * Joins a list of path segments to a given File object.
+ *
+ * @param dir the file object.
+ * @param paths the segments.
+ * @return a new File object.
+ */
+ @NonNull
+ public static File join(@NonNull File dir, @NonNull Iterable<String> paths) {
+ return new File(dir, PATH_JOINER.join(paths));
+ }
+
+ /**
+ * Joins a set of segment into a string, separating each segments with a host-specific
+ * path separator.
+ *
+ * @param paths the segments.
+ * @return a string with the segments.
+ */
+ @NonNull
+ public static String join(@NonNull String... paths) {
+ return PATH_JOINER.join(paths);
+ }
+
+ /**
+ * Joins a set of segment into a string, separating each segments with a host-specific
+ * path separator.
+ *
+ * @param paths the segments.
+ * @return a string with the segments.
+ */
+ @NonNull
+ public static String join(@NonNull Iterable<String> paths) {
+ return PATH_JOINER.join(paths);
+ }
+
+ /**
+ * Loads a text file forcing the line separator to be of Unix style '\n' rather than being
+ * Windows style '\r\n'.
+ */
+ @NonNull
+ public static String loadFileWithUnixLineSeparators(@NonNull File file) throws IOException {
+ return UNIX_NEW_LINE_JOINER.join(Files.readLines(file, Charsets.UTF_8));
+ }
+
+ /**
+ * Computes the relative of a file or directory with respect to a directory.
+ *
+ * @param file the file or directory, which must exist in the filesystem
+ * @param dir the directory to compute the path relative to
+ * @return the relative path from {@code dir} to {@code file}; if {@code file} is a directory
+ * the path comes appended with the file separator (see documentation on {@code relativize}
+ * on java's {@code URI} class)
+ */
+ @NonNull
+ public static String relativePath(@NonNull File file, @NonNull File dir) {
+ checkArgument(file.isFile() || file.isDirectory(), "%s is not a file nor a directory.",
+ file.getPath());
+ checkArgument(dir.isDirectory(), "%s is not a directory.", dir.getPath());
+ return relativePossiblyNonExistingPath(file, dir);
+ }
+
+ /**
+ * Computes the relative of a file or directory with respect to a directory.
+ * For example, if the file's absolute path is {@code /a/b/c} and the directory
+ * is {@code /a}, this method returns {@code b/c}.
+ *
+ * @param file the path that may not correspond to any existing path in the filesystem
+ * @param dir the directory to compute the path relative to
+ * @return the relative path from {@code dir} to {@code file}; if {@code file} is a directory
+ * the path comes appended with the file separator (see documentation on {@code relativize}
+ * on java's {@code URI} class)
+ */
+ @NonNull
+ public static String relativePossiblyNonExistingPath(@NonNull File file, @NonNull File dir) {
+ String path = dir.toURI().relativize(file.toURI()).getPath();
+ return toSystemDependentPath(path);
+ }
+
+ /**
+ * Converts a /-based path into a path using the system dependent separator.
+ * @param path the system independent path to convert
+ * @return the system dependent path
+ */
+ @NonNull
+ public static String toSystemDependentPath(@NonNull String path) {
+ if (File.separatorChar != '/') {
+ path = path.replace('/', File.separatorChar);
+ }
+ return path;
+ }
+
+ /**
+ * Converts a system-dependent path into a /-based path.
+ * @param path the system dependent path
+ * @return the system independent path
+ */
+ @NonNull
+ public static String toSystemIndependentPath(@NonNull String path) {
+ if (File.separatorChar != '/') {
+ path = path.replace(File.separatorChar, '/');
+ }
+ return path;
+ }
+
+ @NonNull
+ public static String sha1(@NonNull File file) throws IOException {
+ return Hashing.sha1().hashBytes(Files.toByteArray(file)).toString();
+ }
+
+ @NonNull
+ public static FluentIterable<File> getAllFiles(@NonNull File dir) {
+ return Files.fileTreeTraverser().preOrderTraversal(dir).filter(Files.isFile());
+ }
+
+ @NonNull
+ public static String getNamesAsCommaSeparatedList(@NonNull Iterable<File> files) {
+ return COMMA_SEPARATED_JOINER.join(Iterables.transform(files, GET_NAME));
+ }
+
+ /**
+ * Chooses a directory name, based on a JAR file name, considering exploded-aar and classes.jar.
+ */
+ @NonNull
+ public static String getDirectoryNameForJar(@NonNull File inputFile) {
+ // add a hash of the original file path.
+ HashFunction hashFunction = Hashing.sha1();
+ HashCode hashCode = hashFunction.hashString(inputFile.getAbsolutePath(), Charsets.UTF_16LE);
+
+ String name = Files.getNameWithoutExtension(inputFile.getName());
+ if (name.equals("classes") && inputFile.getAbsolutePath().contains("exploded-aar")) {
+ // This naming scheme is coming from DependencyManager#computeArtifactPath.
+ File versionDir = inputFile.getParentFile().getParentFile();
+ File artifactDir = versionDir.getParentFile();
+ File groupDir = artifactDir.getParentFile();
+
+ name = Joiner.on('-').join(
+ groupDir.getName(), artifactDir.getName(), versionDir.getName());
+ }
+ name = name + "_" + hashCode.toString();
+ return name;
+ }
+
+ public static void createFile(@NonNull File file, @NonNull String content) throws IOException {
+ checkArgument(!file.exists(), "%s exists already.", file);
+
+ Files.createParentDirs(file);
+ Files.write(content, file, Charsets.UTF_8);
+ }
+
+ /**
+ * Find a list of files in a directory, using a specified path pattern.
+ */
+ public static List<File> find(@NonNull File base, @NonNull final Pattern pattern) {
+ checkArgument(base.isDirectory(), "'base' must be a directory.");
+ return Files.fileTreeTraverser()
+ .preOrderTraversal(base)
+ .filter(Predicates.compose(Predicates.contains(pattern), GET_PATH))
+ .toList();
+ }
+
+ /**
+ * Find a file with the specified name in a given directory .
+ */
+ public static Optional<File> find(@NonNull File base, @NonNull final String name) {
+ checkArgument(base.isDirectory(), "'base' must be a directory.");
+ return Files.fileTreeTraverser()
+ .preOrderTraversal(base)
+ .filter(Predicates.compose(Predicates.equalTo(name), GET_NAME))
+ .last();
+ }
+
+ /**
+ * Reads a portion of a file to memory.
+ *
+ * @param file the file to read data from
+ * @param start the offset in the file to start reading
+ * @param length the number of bytes to read
+ * @return the bytes read
+ * @throws Exception failed to read the file
+ */
+ @NonNull
+ public static byte[] readSegment(@NonNull File file, long start, int length) throws Exception {
+ Preconditions.checkArgument(start >= 0, "start < 0");
+ Preconditions.checkArgument(length >= 0, "length < 0");
+
+ byte data[];
+ boolean threw = true;
+ RandomAccessFile raf = new RandomAccessFile(file, "r");
+ try {
+ raf.seek(start);
+
+ data = new byte[length];
+ int tot = 0;
+ while (tot < length) {
+ int r = raf.read(data, tot, length - tot);
+ if (r < 0) {
+ throw new EOFException();
+ }
+
+ tot += r;
+ }
+
+ threw = false;
+ } finally {
+ Closeables.close(raf, threw);
+ }
+
+ return data;
+ }
+}
diff --git a/third_party/java/apkbuilder/java/com/android/utils/GrabProcessOutput.java b/third_party/java/apkbuilder/java/com/android/utils/GrabProcessOutput.java
index d5cd78b4ad..46f26dab5f 100644
--- a/third_party/java/apkbuilder/java/com/android/utils/GrabProcessOutput.java
+++ b/third_party/java/apkbuilder/java/com/android/utils/GrabProcessOutput.java
@@ -61,12 +61,12 @@ public class GrabProcessOutput {
* Processes an stdout message line.
* @param line The stdout message line. Null when the reader reached the end of stdout.
*/
- public void out(@Nullable String line);
+ void out(@Nullable String line);
/**
* Processes an stderr message line.
* @param line The stderr message line. Null when the reader reached the end of stderr.
*/
- public void err(@Nullable String line);
+ void err(@Nullable String line);
}
/**