diff options
author | Googler <noreply@google.com> | 2016-10-06 20:21:56 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2016-10-07 08:08:04 +0000 |
commit | 4f005551b52083f1e8995f799d4dc8a690604d95 (patch) | |
tree | dd015311f1d71cefa7b7dbd2fe52fbfd2927fb2b /third_party/java | |
parent | 69d9b417534aae71728c5f6bcc67fe44bb4e4241 (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')
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); } /** |