/*
 * Copyright (C) 2011 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 android.app.backup;

import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.system.ErrnoException;
import android.system.Os;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * Global constant definitions et cetera related to the full-backup-to-fd
 * binary format.  Nothing in this namespace is part of any API; it's all
 * hidden details of the current implementation gathered into one location.
 *
 * @hide
 */
public class FullBackup {
    static final String TAG = "FullBackup";
    /** Enable this log tag to get verbose information while parsing the client xml. */
    static final String TAG_XML_PARSER = "BackupXmlParserLogging";

    public static final String APK_TREE_TOKEN = "a";
    public static final String OBB_TREE_TOKEN = "obb";
    public static final String KEY_VALUE_DATA_TOKEN = "k";

    public static final String ROOT_TREE_TOKEN = "r";
    public static final String FILES_TREE_TOKEN = "f";
    public static final String NO_BACKUP_TREE_TOKEN = "nb";
    public static final String DATABASE_TREE_TOKEN = "db";
    public static final String SHAREDPREFS_TREE_TOKEN = "sp";
    public static final String CACHE_TREE_TOKEN = "c";

    public static final String DEVICE_ROOT_TREE_TOKEN = "d_r";
    public static final String DEVICE_FILES_TREE_TOKEN = "d_f";
    public static final String DEVICE_NO_BACKUP_TREE_TOKEN = "d_nb";
    public static final String DEVICE_DATABASE_TREE_TOKEN = "d_db";
    public static final String DEVICE_SHAREDPREFS_TREE_TOKEN = "d_sp";
    public static final String DEVICE_CACHE_TREE_TOKEN = "d_c";

    public static final String MANAGED_EXTERNAL_TREE_TOKEN = "ef";
    public static final String SHARED_STORAGE_TOKEN = "shared";

    public static final String APPS_PREFIX = "apps/";
    public static final String SHARED_PREFIX = SHARED_STORAGE_TOKEN + "/";

    public static final String FULL_BACKUP_INTENT_ACTION = "fullback";
    public static final String FULL_RESTORE_INTENT_ACTION = "fullrest";
    public static final String CONF_TOKEN_INTENT_EXTRA = "conftoken";

    public static final String FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION = "clientSideEncryption";
    public static final String FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER = "deviceToDeviceTransfer";
    public static final String FLAG_REQUIRED_FAKE_CLIENT_SIDE_ENCRYPTION =
            "fakeClientSideEncryption";

    /**
     * @hide
     */
    @UnsupportedAppUsage
    static public native int backupToTar(String packageName, String domain,
            String linkdomain, String rootpath, String path, FullBackupDataOutput output);

    private static final Map<String, BackupScheme> kPackageBackupSchemeMap =
            new ArrayMap<String, BackupScheme>();

    static synchronized BackupScheme getBackupScheme(Context context) {
        BackupScheme backupSchemeForPackage =
                kPackageBackupSchemeMap.get(context.getPackageName());
        if (backupSchemeForPackage == null) {
            backupSchemeForPackage = new BackupScheme(context);
            kPackageBackupSchemeMap.put(context.getPackageName(), backupSchemeForPackage);
        }
        return backupSchemeForPackage;
    }

    public static BackupScheme getBackupSchemeForTest(Context context) {
        BackupScheme testing = new BackupScheme(context);
        testing.mExcludes = new ArraySet();
        testing.mIncludes = new ArrayMap();
        return testing;
    }


    /**
     * Copy data from a socket to the given File location on permanent storage.  The
     * modification time and access mode of the resulting file will be set if desired,
     * although group/all rwx modes will be stripped: the restored file will not be
     * accessible from outside the target application even if the original file was.
     * If the {@code type} parameter indicates that the result should be a directory,
     * the socket parameter may be {@code null}; even if it is valid, no data will be
     * read from it in this case.
     * <p>
     * If the {@code mode} argument is negative, then the resulting output file will not
     * have its access mode or last modification time reset as part of this operation.
     *
     * @param data Socket supplying the data to be copied to the output file.  If the
     *    output is a directory, this may be {@code null}.
     * @param size Number of bytes of data to copy from the socket to the file.  At least
     *    this much data must be available through the {@code data} parameter.
     * @param type Must be either {@link BackupAgent#TYPE_FILE} for ordinary file data
     *    or {@link BackupAgent#TYPE_DIRECTORY} for a directory.
     * @param mode Unix-style file mode (as used by the chmod(2) syscall) to be set on
     *    the output file or directory.  group/all rwx modes are stripped even if set
     *    in this parameter.  If this parameter is negative then neither
     *    the mode nor the mtime values will be applied to the restored file.
     * @param mtime A timestamp in the standard Unix epoch that will be imposed as the
     *    last modification time of the output file.  if the {@code mode} parameter is
     *    negative then this parameter will be ignored.
     * @param outFile Location within the filesystem to place the data.  This must point
     *    to a location that is writeable by the caller, preferably using an absolute path.
     * @throws IOException
     */
    static public void restoreFile(ParcelFileDescriptor data,
            long size, int type, long mode, long mtime, File outFile) throws IOException {
        if (type == BackupAgent.TYPE_DIRECTORY) {
            // Canonically a directory has no associated content, so we don't need to read
            // anything from the pipe in this case.  Just create the directory here and
            // drop down to the final metadata adjustment.
            if (outFile != null) outFile.mkdirs();
        } else {
            FileOutputStream out = null;

            // Pull the data from the pipe, copying it to the output file, until we're done
            try {
                if (outFile != null) {
                    File parent = outFile.getParentFile();
                    if (!parent.exists()) {
                        // in practice this will only be for the default semantic directories,
                        // and using the default mode for those is appropriate.
                        // This can also happen for the case where a parent directory has been
                        // excluded, but a file within that directory has been included.
                        parent.mkdirs();
                    }
                    out = new FileOutputStream(outFile);
                }
            } catch (IOException e) {
                Log.e(TAG, "Unable to create/open file " + outFile.getPath(), e);
            }

            byte[] buffer = new byte[32 * 1024];
            final long origSize = size;
            FileInputStream in = new FileInputStream(data.getFileDescriptor());
            while (size > 0) {
                int toRead = (size > buffer.length) ? buffer.length : (int)size;
                int got = in.read(buffer, 0, toRead);
                if (got <= 0) {
                    Log.w(TAG, "Incomplete read: expected " + size + " but got "
                            + (origSize - size));
                    break;
                }
                if (out != null) {
                    try {
                        out.write(buffer, 0, got);
                    } catch (IOException e) {
                        // Problem writing to the file.  Quit copying data and delete
                        // the file, but of course keep consuming the input stream.
                        Log.e(TAG, "Unable to write to file " + outFile.getPath(), e);
                        out.close();
                        out = null;
                        outFile.delete();
                    }
                }
                size -= got;
            }
            if (out != null) out.close();
        }

        // Now twiddle the state to match the backup, assuming all went well
        if (mode >= 0 && outFile != null) {
            try {
                // explicitly prevent emplacement of files accessible by outside apps
                mode &= 0700;
                Os.chmod(outFile.getPath(), (int)mode);
            } catch (ErrnoException e) {
                e.rethrowAsIOException();
            }
            outFile.setLastModified(mtime);
        }
    }

    @VisibleForTesting
    public static class BackupScheme {
        private final File FILES_DIR;
        private final File DATABASE_DIR;
        private final File ROOT_DIR;
        private final File SHAREDPREF_DIR;
        private final File CACHE_DIR;
        private final File NOBACKUP_DIR;

        private final File DEVICE_FILES_DIR;
        private final File DEVICE_DATABASE_DIR;
        private final File DEVICE_ROOT_DIR;
        private final File DEVICE_SHAREDPREF_DIR;
        private final File DEVICE_CACHE_DIR;
        private final File DEVICE_NOBACKUP_DIR;

        private final File EXTERNAL_DIR;

        private final static String TAG_INCLUDE = "include";
        private final static String TAG_EXCLUDE = "exclude";

        final int mFullBackupContent;
        final PackageManager mPackageManager;
        final StorageManager mStorageManager;
        final String mPackageName;

        // lazy initialized, only when needed
        private StorageVolume[] mVolumes = null;

        /**
         * Parse out the semantic domains into the correct physical location.
         */
        String tokenToDirectoryPath(String domainToken) {
            try {
                if (domainToken.equals(FullBackup.FILES_TREE_TOKEN)) {
                    return FILES_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.DATABASE_TREE_TOKEN)) {
                    return DATABASE_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.ROOT_TREE_TOKEN)) {
                    return ROOT_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.SHAREDPREFS_TREE_TOKEN)) {
                    return SHAREDPREF_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.CACHE_TREE_TOKEN)) {
                    return CACHE_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.NO_BACKUP_TREE_TOKEN)) {
                    return NOBACKUP_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.DEVICE_FILES_TREE_TOKEN)) {
                    return DEVICE_FILES_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.DEVICE_DATABASE_TREE_TOKEN)) {
                    return DEVICE_DATABASE_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.DEVICE_ROOT_TREE_TOKEN)) {
                    return DEVICE_ROOT_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.DEVICE_SHAREDPREFS_TREE_TOKEN)) {
                    return DEVICE_SHAREDPREF_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.DEVICE_CACHE_TREE_TOKEN)) {
                    return DEVICE_CACHE_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.DEVICE_NO_BACKUP_TREE_TOKEN)) {
                    return DEVICE_NOBACKUP_DIR.getCanonicalPath();
                } else if (domainToken.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) {
                    if (EXTERNAL_DIR != null) {
                        return EXTERNAL_DIR.getCanonicalPath();
                    } else {
                        return null;
                    }
                } else if (domainToken.startsWith(FullBackup.SHARED_PREFIX)) {
                    return sharedDomainToPath(domainToken);
                }
                // Not a supported location
                Log.i(TAG, "Unrecognized domain " + domainToken);
                return null;
            } catch (Exception e) {
                Log.i(TAG, "Error reading directory for domain: " + domainToken);
                return null;
            }

        }

        private String sharedDomainToPath(String domain) throws IOException {
            // already known to start with SHARED_PREFIX, so we just look after that
            final String volume = domain.substring(FullBackup.SHARED_PREFIX.length());
            final StorageVolume[] volumes = getVolumeList();
            final int volNum = Integer.parseInt(volume);
            if (volNum < mVolumes.length) {
                return volumes[volNum].getPathFile().getCanonicalPath();
            }
            return null;
        }

        private StorageVolume[] getVolumeList() {
            if (mStorageManager != null) {
                if (mVolumes == null) {
                    mVolumes = mStorageManager.getVolumeList();
                }
            } else {
                Log.e(TAG, "Unable to access Storage Manager");
            }
            return mVolumes;
        }

        /**
         * Represents a path attribute specified in an <include /> rule along with optional
         * transport flags required from the transport to include file(s) under that path as
         * specified by requiredFlags attribute. If optional requiredFlags attribute is not
         * provided, default requiredFlags to 0.
         * Note: since our parsing codepaths were the same for <include /> and <exclude /> tags,
         * this structure is also used for <exclude /> tags to preserve that, however you can expect
         * the getRequiredFlags() to always return 0 for exclude rules.
         */
        public static class PathWithRequiredFlags {
            private final String mPath;
            private final int mRequiredFlags;

            public PathWithRequiredFlags(String path, int requiredFlags) {
                mPath = path;
                mRequiredFlags = requiredFlags;
            }

            public String getPath() {
                return mPath;
            }

            public int getRequiredFlags() {
                return mRequiredFlags;
            }
        }

        /**
         * A map of domain -> set of pairs (canonical file; required transport flags) in that
         * domain that are to be included if the transport has decared the required flags.
         * We keep track of the domain so that we can go through the file system in order later on.
         */
        Map<String, Set<PathWithRequiredFlags>> mIncludes;

        /**
         * Set that will be populated with pairs (canonical file; requiredFlags=0) for each file or
         * directory that is to be excluded. Note that for excludes, the requiredFlags attribute is
         * ignored and the value should be always set to 0.
         */
        ArraySet<PathWithRequiredFlags> mExcludes;

        BackupScheme(Context context) {
            mFullBackupContent = context.getApplicationInfo().fullBackupContent;
            mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
            mPackageManager = context.getPackageManager();
            mPackageName = context.getPackageName();

            // System apps have control over where their default storage context
            // is pointed, so we're always explicit when building paths.
            final Context ceContext = context.createCredentialProtectedStorageContext();
            FILES_DIR = ceContext.getFilesDir();
            DATABASE_DIR = ceContext.getDatabasePath("foo").getParentFile();
            ROOT_DIR = ceContext.getDataDir();
            SHAREDPREF_DIR = ceContext.getSharedPreferencesPath("foo").getParentFile();
            CACHE_DIR = ceContext.getCacheDir();
            NOBACKUP_DIR = ceContext.getNoBackupFilesDir();

            final Context deContext = context.createDeviceProtectedStorageContext();
            DEVICE_FILES_DIR = deContext.getFilesDir();
            DEVICE_DATABASE_DIR = deContext.getDatabasePath("foo").getParentFile();
            DEVICE_ROOT_DIR = deContext.getDataDir();
            DEVICE_SHAREDPREF_DIR = deContext.getSharedPreferencesPath("foo").getParentFile();
            DEVICE_CACHE_DIR = deContext.getCacheDir();
            DEVICE_NOBACKUP_DIR = deContext.getNoBackupFilesDir();

            if (android.os.Process.myUid() != Process.SYSTEM_UID) {
                EXTERNAL_DIR = context.getExternalFilesDir(null);
            } else {
                EXTERNAL_DIR = null;
            }
        }

        boolean isFullBackupContentEnabled() {
            if (mFullBackupContent < 0) {
                // android:fullBackupContent="false", bail.
                if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
                    Log.v(FullBackup.TAG_XML_PARSER, "android:fullBackupContent - \"false\"");
                }
                return false;
            }
            return true;
        }

        /**
         * @return A mapping of domain -> set of pairs (canonical file; required transport flags)
         * in that domain that are to be included if the transport has decared the required flags.
         * Each of these paths specifies a file that the client has explicitly included in their
         * backup set. If this map is empty we will back up the entire data directory (including
         * managed external storage).
         */
        public synchronized Map<String, Set<PathWithRequiredFlags>>
                maybeParseAndGetCanonicalIncludePaths() throws IOException, XmlPullParserException {
            if (mIncludes == null) {
                maybeParseBackupSchemeLocked();
            }
            return mIncludes;
        }

        /**
         * @return A set of (canonical paths; requiredFlags=0) that are to be excluded from the
         * backup/restore set.
         */
        public synchronized ArraySet<PathWithRequiredFlags> maybeParseAndGetCanonicalExcludePaths()
                throws IOException, XmlPullParserException {
            if (mExcludes == null) {
                maybeParseBackupSchemeLocked();
            }
            return mExcludes;
        }

        private void maybeParseBackupSchemeLocked() throws IOException, XmlPullParserException {
            // This not being null is how we know that we've tried to parse the xml already.
            mIncludes = new ArrayMap<String, Set<PathWithRequiredFlags>>();
            mExcludes = new ArraySet<PathWithRequiredFlags>();

            if (mFullBackupContent == 0) {
                // android:fullBackupContent="true" which means that we'll do everything.
                if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
                    Log.v(FullBackup.TAG_XML_PARSER, "android:fullBackupContent - \"true\"");
                }
            } else {
                // android:fullBackupContent="@xml/some_resource".
                if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
                    Log.v(FullBackup.TAG_XML_PARSER,
                            "android:fullBackupContent - found xml resource");
                }
                XmlResourceParser parser = null;
                try {
                    parser = mPackageManager
                            .getResourcesForApplication(mPackageName)
                            .getXml(mFullBackupContent);
                    parseBackupSchemeFromXmlLocked(parser, mExcludes, mIncludes);
                } catch (PackageManager.NameNotFoundException e) {
                    // Throw it as an IOException
                    throw new IOException(e);
                } finally {
                    if (parser != null) {
                        parser.close();
                    }
                }
            }
        }

        @VisibleForTesting
        public void parseBackupSchemeFromXmlLocked(XmlPullParser parser,
                                                   Set<PathWithRequiredFlags> excludes,
                                                   Map<String, Set<PathWithRequiredFlags>> includes)
                throws IOException, XmlPullParserException {
            int event = parser.getEventType(); // START_DOCUMENT
            while (event != XmlPullParser.START_TAG) {
                event = parser.next();
            }

            if (!"full-backup-content".equals(parser.getName())) {
                throw new XmlPullParserException("Xml file didn't start with correct tag" +
                        " (<full-backup-content>). Found \"" + parser.getName() + "\"");
            }

            if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                Log.v(TAG_XML_PARSER, "\n");
                Log.v(TAG_XML_PARSER, "====================================================");
                Log.v(TAG_XML_PARSER, "Found valid fullBackupContent; parsing xml resource.");
                Log.v(TAG_XML_PARSER, "====================================================");
                Log.v(TAG_XML_PARSER, "");
            }

            while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
                switch (event) {
                    case XmlPullParser.START_TAG:
                        validateInnerTagContents(parser);
                        final String domainFromXml = parser.getAttributeValue(null, "domain");
                        final File domainDirectory = getDirectoryForCriteriaDomain(domainFromXml);
                        if (domainDirectory == null) {
                            if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                Log.v(TAG_XML_PARSER, "...parsing \"" + parser.getName() + "\": "
                                        + "domain=\"" + domainFromXml + "\" invalid; skipping");
                            }
                            break;
                        }
                        final File canonicalFile =
                                extractCanonicalFile(domainDirectory,
                                        parser.getAttributeValue(null, "path"));
                        if (canonicalFile == null) {
                            break;
                        }

                        int requiredFlags = 0; // no transport flags are required by default
                        if (TAG_INCLUDE.equals(parser.getName())) {
                            // requiredFlags are only supported for <include /> tag, for <exclude />
                            // we should always leave them as the default = 0
                            requiredFlags = getRequiredFlagsFromString(
                                    parser.getAttributeValue(null, "requireFlags"));
                        }

                        // retrieve the include/exclude set we'll be adding this rule to
                        Set<PathWithRequiredFlags> activeSet = parseCurrentTagForDomain(
                                parser, excludes, includes, domainFromXml);
                        activeSet.add(new PathWithRequiredFlags(canonicalFile.getCanonicalPath(),
                                requiredFlags));
                        if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                            Log.v(TAG_XML_PARSER, "...parsed " + canonicalFile.getCanonicalPath()
                                    + " for domain \"" + domainFromXml + "\", requiredFlags + \""
                                    + requiredFlags + "\"");
                        }

                        // Special case journal files (not dirs) for sqlite database. frowny-face.
                        // Note that for a restore, the file is never a directory (b/c it doesn't
                        // exist). We have no way of knowing a priori whether or not to expect a
                        // dir, so we add the -journal anyway to be safe.
                        if ("database".equals(domainFromXml) && !canonicalFile.isDirectory()) {
                            final String canonicalJournalPath =
                                    canonicalFile.getCanonicalPath() + "-journal";
                            activeSet.add(new PathWithRequiredFlags(canonicalJournalPath,
                                    requiredFlags));
                            if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                Log.v(TAG_XML_PARSER, "...automatically generated "
                                        + canonicalJournalPath + ". Ignore if nonexistent.");
                            }
                            final String canonicalWalPath =
                                    canonicalFile.getCanonicalPath() + "-wal";
                            activeSet.add(new PathWithRequiredFlags(canonicalWalPath,
                                    requiredFlags));
                            if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                Log.v(TAG_XML_PARSER, "...automatically generated "
                                        + canonicalWalPath + ". Ignore if nonexistent.");
                            }
                        }

                        // Special case for sharedpref files (not dirs) also add ".xml" suffix file.
                        if ("sharedpref".equals(domainFromXml) && !canonicalFile.isDirectory() &&
                            !canonicalFile.getCanonicalPath().endsWith(".xml")) {
                            final String canonicalXmlPath =
                                    canonicalFile.getCanonicalPath() + ".xml";
                            activeSet.add(new PathWithRequiredFlags(canonicalXmlPath,
                                    requiredFlags));
                            if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                Log.v(TAG_XML_PARSER, "...automatically generated "
                                        + canonicalXmlPath + ". Ignore if nonexistent.");
                            }
                        }
                }
            }
            if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                Log.v(TAG_XML_PARSER, "\n");
                Log.v(TAG_XML_PARSER, "Xml resource parsing complete.");
                Log.v(TAG_XML_PARSER, "Final tally.");
                Log.v(TAG_XML_PARSER, "Includes:");
                if (includes.isEmpty()) {
                    Log.v(TAG_XML_PARSER, "  ...nothing specified (This means the entirety of app"
                            + " data minus excludes)");
                } else {
                    for (Map.Entry<String, Set<PathWithRequiredFlags>> entry
                            : includes.entrySet()) {
                        Log.v(TAG_XML_PARSER, "  domain=" + entry.getKey());
                        for (PathWithRequiredFlags includeData : entry.getValue()) {
                            Log.v(TAG_XML_PARSER, " path: " + includeData.getPath()
                                    + " requiredFlags: " + includeData.getRequiredFlags());
                        }
                    }
                }

                Log.v(TAG_XML_PARSER, "Excludes:");
                if (excludes.isEmpty()) {
                    Log.v(TAG_XML_PARSER, "  ...nothing to exclude.");
                } else {
                    for (PathWithRequiredFlags excludeData : excludes) {
                        Log.v(TAG_XML_PARSER, " path: " + excludeData.getPath()
                                + " requiredFlags: " + excludeData.getRequiredFlags());
                    }
                }

                Log.v(TAG_XML_PARSER, "  ");
                Log.v(TAG_XML_PARSER, "====================================================");
                Log.v(TAG_XML_PARSER, "\n");
            }
        }

        private int getRequiredFlagsFromString(String requiredFlags) {
            int flags = 0;
            if (requiredFlags == null || requiredFlags.length() == 0) {
                // requiredFlags attribute was missing or empty in <include /> tag
                return flags;
            }
            String[] flagsStr = requiredFlags.split("\\|");
            for (String f : flagsStr) {
                switch (f) {
                    case FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION:
                        flags |= BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;
                        break;
                    case FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER:
                        flags |= BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER;
                        break;
                    case FLAG_REQUIRED_FAKE_CLIENT_SIDE_ENCRYPTION:
                        flags |= BackupAgent.FLAG_FAKE_CLIENT_SIDE_ENCRYPTION_ENABLED;
                    default:
                        Log.w(TAG, "Unrecognized requiredFlag provided, value: \"" + f + "\"");
                }
            }
            return flags;
        }

        private Set<PathWithRequiredFlags> parseCurrentTagForDomain(XmlPullParser parser,
                Set<PathWithRequiredFlags> excludes,
                Map<String, Set<PathWithRequiredFlags>> includes, String domain)
                throws XmlPullParserException {
            if (TAG_INCLUDE.equals(parser.getName())) {
                final String domainToken = getTokenForXmlDomain(domain);
                Set<PathWithRequiredFlags> includeSet = includes.get(domainToken);
                if (includeSet == null) {
                    includeSet = new ArraySet<PathWithRequiredFlags>();
                    includes.put(domainToken, includeSet);
                }
                return includeSet;
            } else if (TAG_EXCLUDE.equals(parser.getName())) {
                return excludes;
            } else {
                // Unrecognised tag => hard failure.
                if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                    Log.v(TAG_XML_PARSER, "Invalid tag found in xml \""
                            + parser.getName() + "\"; aborting operation.");
                }
                throw new XmlPullParserException("Unrecognised tag in backup" +
                        " criteria xml (" + parser.getName() + ")");
            }
        }

        /**
         * Map xml specified domain (human-readable, what clients put in their manifest's xml) to
         * BackupAgent internal data token.
         * @return null if the xml domain was invalid.
         */
        private String getTokenForXmlDomain(String xmlDomain) {
            if ("root".equals(xmlDomain)) {
                return FullBackup.ROOT_TREE_TOKEN;
            } else if ("file".equals(xmlDomain)) {
                return FullBackup.FILES_TREE_TOKEN;
            } else if ("database".equals(xmlDomain)) {
                return FullBackup.DATABASE_TREE_TOKEN;
            } else if ("sharedpref".equals(xmlDomain)) {
                return FullBackup.SHAREDPREFS_TREE_TOKEN;
            } else if ("device_root".equals(xmlDomain)) {
                return FullBackup.DEVICE_ROOT_TREE_TOKEN;
            } else if ("device_file".equals(xmlDomain)) {
                return FullBackup.DEVICE_FILES_TREE_TOKEN;
            } else if ("device_database".equals(xmlDomain)) {
                return FullBackup.DEVICE_DATABASE_TREE_TOKEN;
            } else if ("device_sharedpref".equals(xmlDomain)) {
                return FullBackup.DEVICE_SHAREDPREFS_TREE_TOKEN;
            } else if ("external".equals(xmlDomain)) {
                return FullBackup.MANAGED_EXTERNAL_TREE_TOKEN;
            } else {
                return null;
            }
        }

        /**
         *
         * @param domain Directory where the specified file should exist. Not null.
         * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may
         *                        be null.
         * @return The canonical path of the file specified or null if no such file exists.
         */
        private File extractCanonicalFile(File domain, String filePathFromXml) {
            if (filePathFromXml == null) {
                // Allow things like <include domain="sharedpref"/>
                filePathFromXml = "";
            }
            if (filePathFromXml.contains("..")) {
                if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                    Log.v(TAG_XML_PARSER, "...resolved \"" + domain.getPath() + " " + filePathFromXml
                            + "\", but the \"..\" path is not permitted; skipping.");
                }
                return null;
            }
            if (filePathFromXml.contains("//")) {
                if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                    Log.v(TAG_XML_PARSER, "...resolved \"" + domain.getPath() + " " + filePathFromXml
                            + "\", which contains the invalid \"//\" sequence; skipping.");
                }
                return null;
            }
            return new File(domain, filePathFromXml);
        }

        /**
         * @param domain parsed from xml. Not sanitised before calling this function so may be null.
         * @return The directory relevant to the domain specified.
         */
        private File getDirectoryForCriteriaDomain(String domain) {
            if (TextUtils.isEmpty(domain)) {
                return null;
            }
            if ("file".equals(domain)) {
                return FILES_DIR;
            } else if ("database".equals(domain)) {
                return DATABASE_DIR;
            } else if ("root".equals(domain)) {
                return ROOT_DIR;
            } else if ("sharedpref".equals(domain)) {
                return SHAREDPREF_DIR;
            } else if ("device_file".equals(domain)) {
                return DEVICE_FILES_DIR;
            } else if ("device_database".equals(domain)) {
                return DEVICE_DATABASE_DIR;
            } else if ("device_root".equals(domain)) {
                return DEVICE_ROOT_DIR;
            } else if ("device_sharedpref".equals(domain)) {
                return DEVICE_SHAREDPREF_DIR;
            } else if ("external".equals(domain)) {
                return EXTERNAL_DIR;
            } else {
                return null;
            }
        }

        /**
         * Let's be strict about the type of xml the client can write. If we see anything untoward,
         * throw an XmlPullParserException.
         */
        private void validateInnerTagContents(XmlPullParser parser) throws XmlPullParserException {
            if (parser == null) {
                return;
            }
            switch (parser.getName()) {
                case TAG_INCLUDE:
                    if (parser.getAttributeCount() > 3) {
                        throw new XmlPullParserException("At most 3 tag attributes allowed for "
                                + "\"include\" tag (\"domain\" & \"path\""
                                + " & optional \"requiredFlags\").");
                    }
                    break;
                case TAG_EXCLUDE:
                    if (parser.getAttributeCount() > 2) {
                        throw new XmlPullParserException("At most 2 tag attributes allowed for "
                                + "\"exclude\" tag (\"domain\" & \"path\".");
                    }
                    break;
                default:
                    throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" +
                            " \"<exclude/>. You provided \"" + parser.getName() + "\"");
            }
        }
    }
}
