All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.ide.common.packaging.PackagingUtils Maven / Gradle / Ivy

There is a newer version: 25.3.0
Show newest version
/*
 * Copyright (C) 2013 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.ide.common.packaging;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;

import java.io.File;
import java.io.IOException;

/**
 * Utility class for packaging.
 */
public class PackagingUtils {

    /**
     * Checks whether a folder and its content is valid for packaging into the .apk as
     * standard Java resource.
     * @param folderName the name of the folder.
     *
     * @return true if the folder is valid for packaging.
     */
    public static boolean checkFolderForPackaging(@NonNull String folderName) {
        return !folderName.equalsIgnoreCase("CVS") &&
                !folderName.equalsIgnoreCase(".svn") &&
                !folderName.equalsIgnoreCase("SCCS") &&
                !folderName.startsWith("_");
    }

    /**
     * Checks a file to make sure it should be packaged as standard resources.
     * @param fileName the name of the file (including extension)
     * @param allowClassFiles whether to allow java class files
     * @return true if the file should be packaged as standard java resources.
     */
    public static boolean checkFileForPackaging(@NonNull String fileName, boolean allowClassFiles) {
        String[] fileSegments = fileName.split("\\.");
        String fileExt = "";
        if (fileSegments.length > 1) {
            fileExt = fileSegments[fileSegments.length-1];
        }

        return checkFileForPackaging(fileName, fileExt, allowClassFiles);
    }

    /**
     * Checks a file to make sure it should be packaged as standard resources.
     * @param fileName the name of the file (including extension)
     * @return true if the file should be packaged as standard java resources.
     */
    public static boolean checkFileForPackaging(@NonNull String fileName) {
        return checkFileForPackaging(fileName, false);
    }

    /**
     * Checks a file to make sure it should be packaged as standard resources.
     * @param fileName the name of the file (including extension)
     * @param extension the extension of the file (excluding '.')
     * @param allowClassFiles whether to allow java class files
     * @return true if the file should be packaged as standard java resources.
     */
    public static boolean checkFileForPackaging(
            @NonNull String fileName,
            @NonNull String extension,
            boolean allowClassFiles) {
        // ignore hidden files and backup files
        return !(fileName.charAt(0) == '.' || fileName.charAt(fileName.length() - 1) == '~') &&
                !isOfNonResourcesExtensions(extension, allowClassFiles) &&
                !isNotAResourceFile(fileName);
    }

    /**
     * Checks a file to make sure it should be packaged as standard resources.
     * @param fileName the name of the file (including extension)
     * @param extension the extension of the file (excluding '.')
     * @return true if the file should be packaged as standard java resources.
     */
    public static boolean checkFileForPackaging(
            @NonNull String fileName,
            @NonNull String extension) {
        // ignore hidden files and backup files
        return !(fileName.charAt(0) == '.' || fileName.charAt(fileName.length() - 1) == '~') &&
                !isOfNonResourcesExtensions(extension, false) &&
                !isNotAResourceFile(fileName);
    }

    private static boolean isOfNonResourcesExtensions(
            @NonNull String extension,
            boolean allowClassFiles) {
        for (String ext : NON_RESOURCES_EXTENSIONS) {
            if (ext.equalsIgnoreCase(extension)) {
                return true;
            }
        }

        return !allowClassFiles && SdkConstants.EXT_CLASS.equals(extension);
    }

    private static boolean isNotAResourceFile(@NonNull String fileName) {
        for (String name : NON_RESOURCES_FILENAMES) {
            if (name.equalsIgnoreCase(fileName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the list of file extensions that represents non resources files.
     */
    public static final ImmutableList NON_RESOURCES_EXTENSIONS =
            ImmutableList.builder()
                    .add("aidl")            // Aidl files
                    .add("rs")              // RenderScript files
                    .add("fs")              // FilterScript files
                    .add("rsh")             // RenderScript header files
                    .add("d")               // Dependency files
                    .add("java")            // Java files
                    .add("scala")           // Scala files
                    .add("scc")             // VisualSourceSafe
                    .add("swp")             // vi swap file
                    .build();

    /**
     * Return file names that are not resource files.
     */
    public static final ImmutableList NON_RESOURCES_FILENAMES =
            ImmutableList.builder()
                    .add("thumbs.db")       // image index file
                    .add("picasa.ini")      // image index file
                    .add("about.html")      // Javadoc
                    .add("package.html")    // Javadoc
                    .add("overview.html")   // Javadoc
                    .build();

    /**
     * Computes an "application hash", a reasonably unique identifier for an app.
     * 

* This is currently used by Instant Run to prevent apps on a device from guessing * the authentication token associated with an instant run developed app on the same * device. *

* This method creates the "secret", the field in the AppInfo class which is used as a simple * authentication token between the IDE and the app server. *

* This is not a cryptographically strong unique id; we could attempt to make a truly random * number here, but we'd need to store that id somewhere such that subsequent builds * will use the same secret, to avoid having the IDE and the app getting out of sync, * and there isn't really a natural place for us to store the key to make it survive across * a clean build. (One possibility is putting it into local.properties). *

* However, we have much simpler needs: we just need a key that can't be guessed from * a hostile app on the developer's device, and it only has a few guesses (after providing * the wrong secret to the server a few times, the server will shut down.) We can't * rely on the package name along, since the port number is known, and the package name is * discoverable by the hostile app (by querying the contents of /data/data/*). Therefore * we also include facts that the hostile app can't know, such as as the path on the * developer's machine to the app project and the name of the developer's machine, etc. * The goal is for this secret to be reasonably stable (e.g. the same from build to build) * yet not something an app could guess if it only has a couple of tries. */ public static long computeApplicationHash(@NonNull File projectDir) { HashFunction hashFunction = Hashing.md5(); Hasher hasher = hashFunction.newHasher(); try { projectDir = projectDir.getCanonicalFile(); } catch (IOException ignore) { // If this throws an exception the assignment won't // be done and we'll stick with the regular project dir } String path = projectDir.getPath(); hasher.putBytes(path.getBytes(Charsets.UTF_8)); String user = System.getProperty("user.name"); if (user != null) { hasher.putBytes(user.getBytes(Charsets.UTF_8)); } return hasher.hash().asLong(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy