OSDN Git Service

am 81c80180: Merge "Camera2: relax the EV compensation requirements" into lmp-mr1-dev
[android-x86/frameworks-base.git] / core / jni / android_app_backup_FullBackup.cpp
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "FullBackup_native"
18 #include <utils/Log.h>
19 #include <utils/String8.h>
20
21 #include "JNIHelp.h"
22 #include <android_runtime/AndroidRuntime.h>
23
24 #include <androidfw/BackupHelpers.h>
25
26 #include "core_jni_helpers.h"
27
28 #include <string.h>
29
30 namespace android
31 {
32
33 // android.app.backup.BackupDataOutput
34 static struct {
35     // This is actually a native pointer to the underlying BackupDataWriter instance
36     jfieldID mBackupWriter;
37 } sBackupDataOutput;
38
39 /*
40  * Write files to the given output.  This implementation does *not* create
41  * a standalone archive suitable for restore on its own.  In particular, the identification of
42  * the application's name etc is not in-band here; it's assumed that the calling code has
43  * taken care of supplying that information previously in the output stream.
44  *
45  * The file format is 'tar's, with special semantics applied by use of a "fake" directory
46  * hierarchy within the tar stream:
47  *
48  * apps/packagename/a/Filename.apk - this is an actual application binary, which will be
49  *   installed on the target device at restore time.  These need to appear first in the tar
50  *   stream.
51  * apps/packagename/obb/[relpath] - OBB containers belonging the app
52  * apps/packagename/r/[relpath] - these are files at the root of the app's data tree
53  * apps/packagename/f/[relpath] - this is a file within the app's getFilesDir() tree, stored
54  *   at [relpath] relative to the top of that tree.
55  * apps/packagename/db/[relpath] - as with "files" but for the getDatabasePath() tree
56  * apps/packagename/sp/[relpath] - as with "files" but for the getSharedPrefsFile() tree
57  * apps/packagename/c/[relpath] - as with "files" but for the getCacheDir() tree
58  *
59  * and for the shared storage hierarchy:
60  *
61  * shared/[relpaths] - files belonging in the device's shared storage location.  This will
62  *    *not* include .obb files; those are saved with their owning apps.
63  *
64  * This method writes one file data block.  'domain' is the name of the appropriate pseudo-
65  * directory to be applied for this file; 'linkdomain' is the pseudo-dir for a relative
66  * symlink's antecedent.
67  *
68  * packagename: the package name to use as the top level directory tag
69  * domain:      which semantic name the file is to be stored under (a, r, f, db, etc)
70  * linkdomain:  where a symlink points for purposes of rewriting; current unused
71  * rootpath:    prefix to be snipped from full path when encoding in tar
72  * path:        absolute path to the file to be saved
73  * dataOutput:  the BackupDataOutput object that we're saving into
74  */
75 static jint backupToTar(JNIEnv* env, jobject clazz, jstring packageNameObj,
76         jstring domainObj, jstring linkdomain,
77         jstring rootpathObj, jstring pathObj, jobject dataOutputObj) {
78     // Extract the various strings, allowing for null object pointers
79     const char* packagenamechars = (packageNameObj) ? env->GetStringUTFChars(packageNameObj, NULL) : NULL;
80     const char* rootchars = (rootpathObj) ? env->GetStringUTFChars(rootpathObj, NULL) : NULL;
81     const char* pathchars = (pathObj) ? env->GetStringUTFChars(pathObj, NULL) : NULL;
82     const char* domainchars = (domainObj) ? env->GetStringUTFChars(domainObj, NULL) : NULL;
83
84     String8 packageName(packagenamechars ? packagenamechars : "");
85     String8 rootpath(rootchars ? rootchars : "");
86     String8 path(pathchars ? pathchars : "");
87     String8 domain(domainchars ? domainchars : "");
88
89     if (domainchars) env->ReleaseStringUTFChars(domainObj, domainchars);
90     if (pathchars) env->ReleaseStringUTFChars(pathObj, pathchars);
91     if (rootchars) env->ReleaseStringUTFChars(rootpathObj, rootchars);
92     if (packagenamechars) env->ReleaseStringUTFChars(packageNameObj, packagenamechars);
93
94     // Extract the data output fd
95     BackupDataWriter* writer = (BackupDataWriter*) env->GetLongField(dataOutputObj,
96             sBackupDataOutput.mBackupWriter);
97
98     // Validate
99     if (!writer) {
100         ALOGE("No output stream provided [%s]", path.string());
101         return (jint) -1;
102     }
103
104     if (path.length() < rootpath.length()) {
105         ALOGE("file path [%s] shorter than root path [%s]",
106                 path.string(), rootpath.string());
107         return (jint) -1;
108     }
109
110     return (jint) write_tarfile(packageName, domain, rootpath, path, writer);
111 }
112
113 static const JNINativeMethod g_methods[] = {
114     { "backupToTar",
115             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/backup/BackupDataOutput;)I",
116             (void*)backupToTar },
117 };
118
119 int register_android_app_backup_FullBackup(JNIEnv* env)
120 {
121     jclass clazz = FindClassOrDie(env, "android/app/backup/BackupDataOutput");
122
123     sBackupDataOutput.mBackupWriter = GetFieldIDOrDie(env, clazz, "mBackupWriter", "J");
124
125     return RegisterMethodsOrDie(env, "android/app/backup/FullBackup", g_methods, NELEM(g_methods));
126 }
127
128 }